2010-06-21 33 views
6

Estoy usando el DataReader OleDB para obtener datos de mis archivos de Excel (pero este problema también ocurre en DataTable.Fill). El caso es que tengo una columna que debería devolver cadenas. Todo está bien y funciona, pero recientemente surgió un problema, porque las celdas de la columna tenían diferentes formatos. Algunos estaban en números y otros en texto. Cuando revisé usando dataReader.GetSchema() mostró que la columna en cuestión se dedujo como tipo System.String. El problema con esto era que todas las celdas que no eran de texto se configuraron inmediatamente como nulas.Problema de formato de celda de Excel

¿Hay alguna manera de sugerir al lector que esa columna solo debe analizar las columnas como System.Object en lugar de inferirlo como System.String y eliminar todas las celdas que no sean cadenas?

La cadena de conexión que estoy usando es:

cadena connString = "Provider = Microsoft.Jet.OleDb.4.0;" + "Origen de datos =" + filePath + ";" + "Propiedades extendidas = Excel 8.0;";

y el código es:

using (OleDbConnection connection = new OleDbConnection(connString)) 
{ 
    connection.Open(); 
    foreach (string worksheetName in worksheetNames) 
    { 
     using (OleDbCommand command = 
      new OleDbCommand("SELECT * FROM [" + worksheetName + "]", connection)) 
     { 
      TEntity entity; 
      using (OleDbDataReader dataReader = command.ExecuteReader()) 
      { 
       while (dataReader.Read()) 
       { 
        entity = GetDataFromDataTable(dataReader); 

        if (entity != null) 
        { 
         entityList.Add(entity); 
        } 
       } 
      } 
     } 
    } 
    connection.Close(); 
} 

Respuesta

7

Debe agregar IMEX o MAXSCANROWS a la cadena de conexión.

MAXSCANROWS: el número de filas para escanear para determinar el tipo de datos de cada columna. El tipo de datos se determina dado el número máximo de tipos de datos encontrados. Si se encuentran datos que no coinciden con el tipo de datos adivinado para la columna, el tipo de datos se devolverá como un valor NULL.

Para el controlador de Microsoft Excel, puede ingresar un número del 1 al 16 para las filas a escanear. El valor predeterminado es 8; si se establece en 0, se escanean todas las filas. (Un número fuera del límite devolverá un error.)

Además, consulte el registro [HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Jet \ 4.0 \ Engines \ Excel] ubicado REG_DWORD "TypeGuessRows". Esa es la clave para no permitir que Excel use solo las primeras 8 filas para adivinar el tipo de datos de las columnas. Establezca este valor en 0 para escanear todas las filas. Esto podría perjudicar el rendimiento.

+0

Gracias. IMEX funcionó. – Jonn

+0

FYI: MaxScanRows = 0 se ignora cuando se utiliza el proveedor Microsoft.Jet.OLEDB.4.0; aún solo escanea las primeras 8 filas. El proveedor Microsoft.ACE.OLEDB.12.0 no parece sufrir el mismo problema. Consulte la sección sobre _Filas para escanear_ en [KB] (http://support.microsoft.com/default.aspx?scid=kb;en-us;257819) – codechurn

2

dos cosas que vienen a la mente:

  1. ¿Qué tipo es 'TEntity'. ¿Está restringido a cadenas u otro tipo?

  2. Qué tipo de lista es entityList. ¿Es genérico, o es una lista (de TEntity) o algún otro tipo?

+0

TEntity es un tipo genérico – Jonn

Cuestiones relacionadas