2010-09-28 17 views
6

Primero, quiero decir que estoy afuera en aguas profundas, ya que solo estoy haciendo algunos cambios al código escrito por otra persona de la compañía, usando OleDbDataAdapter para "hablar" a Excel y no estoy familiarizado con eso. Hay un error allí que simplemente no puedo seguir.Problema con el uso de OleDbDataAdapter para recuperar datos de una hoja de Excel

Estoy tratando de usar un OleDbDataAdapter para leer en un archivo de Excel con alrededor de 450 líneas.

En el código se realiza Es así:

connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source='" + path + "';" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\""); 
connection.Open(); 
OleDbDataAdapter objAdapter = new OleDbDataAdapter(objCommand.CommandText, connection); 
objAdapter.Fill(objDataSet, "Excel"); 

foreach (DataColumn dataColumn in objTable.Columns) { 
    if (dataColumn.Ordinal > objDataSet.Tables[0].Columns.Count - 1) { 
    objDataSet.Tables[0].Columns.Add(); 
    } 
    objDataSet.Tables[0].Columns[dataColumn.Ordinal].ColumnName = dataColumn.ColumnName; 
    objImport.Columns.Add(dataColumn.ColumnName); 
} 

foreach (DataRow dataRow in objDataSet.Tables[0].Rows) { 
    ... 
} 

Todo parece estar funcionando bien, excepto por una cosa. La segunda columna está llena principalmente de números de cuatro dígitos como 6739, 3920 y uno, pero las filas tienen valores alfanuméricos como 8201NO y 8205NO. Se informa que esas cinco celdas tienen contenidos en blanco en lugar de su contenido alfanumérico. He marcado en Excel y todas las celdas en estas columnas están marcadas como Texto.

Este es un archivo xls por cierto, y no xlsx.

¿Alguien tiene alguna pista de por qué estas celdas se muestran en blanco en el DataRow, pero las numéricas se muestran bien? Hay otras columnas con contenido alfanumérico que se muestran bien.

+0

Gracias a todos por ayudarme con este problema. Me hiciste comprender por qué sucedió esto, para poder encontrar la solución adecuada. Sigo pensando que la forma en que funciona es bastante horrible, pero esa es otra historia :) –

Respuesta

8

Lo que está sucediendo es que Excel está intentando asignar un tipo de datos a la columna de la hoja de cálculo en función de los primeros valores de esa columna. Sospecho que si miras las propiedades en esa columna, dirán que es una columna numérica.

El problema surge cuando comienza a intentar consultar esa hoja de cálculo usando un chorro. Cuando cree que se trata de una columna numérica y encuentra un valor varchar silenciosamente, no devuelve nada. Ni siquiera un mensaje de error críptico para emitir.

Como posible solución, puede mover uno de los valores alfanuméricos a la primera fila de datos y luego intentar el análisis. Sospecho que comenzará a obtener valores para las filas alfanuméricas ...

Eche un vistazo a this article. Entra en más detalles sobre este tema. También habla de una posible solución, que es:

Sin embargo, según la documentación JET, que puede sustituir la configuración a través de la cadena de conexión del registro, si nos fijamos IMEX = 1 (como parte de extendido Bien), el JET establecerá el tipo de columna todas como Unicode VARCHAR o adVarWChar independientemente de clave value.hey '' ImportMixedTypes

+0

He probado esto ahora, y de hecho si pongo la primera fila alfanumérica, entonces funciona como se esperaba. Mi problema es que no puedo hacer de esto una regla general, ya que los clientes leerán en sus propias hojas. Sin embargo, mi solución fue "engañar", por lo que cambio HDR = No en la cadena de conexión para asegurarme de que el encabezado alfanumérico se lee para que la columna sea alfanumérica, luego corté la primera línea del DataTable resultante. Es bastante desagradable, pero no veo ninguna otra opción aquí. Muchas gracias por su ayuda que me ayudaron a ir en la dirección correcta. –

+0

Muy furtivo. ¡Si funciona, funciona! –

1

IMEX=1 significa "Leer datos mixtos como texto."

Hay algunos inconvenientes, sin embargo. Jet solo usará varias filas para determinar si los datos están mezclados, y si es así, estas filas son todas numéricas, obtendrá este comportamiento.

Ver connectionstrings.com para más detalles:

Mira la [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel] registro REG_DWORD "TypeGuessRows" localizados. 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.Tenga en cuenta que agregar la opción IMEX = 1 puede hacer que la función IMEX se configure después de solo 8 filas. Use IMEX = 0 en su lugar para asegurarse de forzar el registro TypeGuessRows = 0 (analizar todas las filas) para que funcione.

+0

No sé cómo Jet está expuesto en Excel, pero en Access, puede cambiar este tipo de cosas en tiempo de ejecución en su instancia actual del motor Jet db sin tener que modificar el registro y reiniciar Access. –

+0

Gracias por esta información. Funcionó, pero fue sorprendentemente lento, así que tuve que ir con el truco "leer y deshacer". –

1

Recomendaría no utilizar el proveedor de datos OleDb para acceder a Excel si puede evitarlo. No he tenido más que problemas, exactamente por las razones que otros han señalado. El rendimiento tiende a ser atroz también cuando se trata de grandes hojas de cálculo.

Usted puede tratar de esta solución de código abierto: http://exceldatareader.codeplex.com/

+0

Estoy totalmente de acuerdo contigo Mark. Creo que es bastante horrible, pero en este caso no tengo ninguna opción, ya que estoy asignado para corregir este error en un programa existente, y no me han asignado el tiempo para hacer refactorizaciones grandes. Tendré en cuenta su enlace si necesito hacerlo desde cero más adelante. –

Cuestiones relacionadas