2010-09-28 5 views
6

Zuerst möchte ich sagen, dass ich hier auf tiefem Wasser bin, da ich nur einige Änderungen an Code, der von jemand anderem in der Firma geschrieben wurde, machen, Verwenden von OleDbDataAdapter, um mit Excel zu "sprechen", und ich bin damit nicht vertraut. Da gibt es einen Fehler, dem ich einfach nicht folgen kann.Problem mit der Verwendung von OleDbDataAdapter zum Abrufen von Daten aus einer Excel-Tabelle

Ich versuche, einen OleDbDataAdapter zu verwenden, um eine Excel-Datei mit etwa 450 Zeilen einzulesen.

Im Code wird es so gemacht:

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) { 
    ... 
} 

Alles funktioniert gut, außer für eine Sache zu sein scheint. Die zweite Spalte ist mit meist vierstelligen Zahlen wie 6739, 3920 usw. gefüllt, aber die Zeilen haben alphanumerische Werte wie 8201NO und 8205NO. Von diesen fünf Zellen wird berichtet, dass sie einen leeren Inhalt anstelle ihres alphanumerischen Inhalts aufweisen. Ich habe Excel eingecheckt, und alle Zellen in diesen Spalten sind als Text markiert.

Dies ist eine xls-Datei übrigens, und nicht xlsx.

Weiß jemand, warum diese Zellen in der DataRow als leer angezeigt werden, aber die numerischen werden in Ordnung angezeigt? Es gibt andere Spalten mit alphanumerischem Inhalt, die gut angezeigt werden.

+0

Vielen Dank an alle für mich helfen, sich mit diesem Thema aus. Du hast mich verstehen lassen, warum das passiert ist, damit ich die richtige Lösung finden konnte. Ich denke immer noch, die Art, wie es funktioniert, ist ziemlich schrecklich, aber das ist eine andere Geschichte :) –

Antwort

8

Was ist passiert, dass Excel versucht, einen Datentyp auf die Spreadsheet-Spalte basierend auf den ersten mehreren Werten in dieser Spalte zuzuweisen. Ich vermute, wenn man sich die Eigenschaften in dieser Spalte anschaut, sagt man, dass es sich um eine numerische Spalte handelt.

Das Problem tritt auf, wenn Sie versuchen, diese Tabelle mit Jet abzufragen. Wenn es denkt, dass es sich um eine numerische Spalte handelt und es einen Varchar-Wert findet, gibt es nichts zurück. Nicht einmal eine kryptische Fehlermeldung, von der man abgehen könnte.

Als eine mögliche Umgehung können Sie einen der alphanumerischen Werte in die erste Datenzeile verschieben und dann versuchen, zu analysieren. Ich vermute, dass Sie beginnen werden, Werte für die alphanumerischen Zeilen zu erhalten, dann ...

Werfen Sie einen Blick auf this article. Es geht auf dieses Thema näher ein. es spricht auch über eine mögliche Arbeit, um die ist:

jedoch nach JET Dokumentation, wir können die Registrierung durch die Connection String Einstellung außer Kraft setzen, wenn wir gesetzt IMEX = 1 (als Teil Extended Eigenschaften), der JET die allen Spaltentyp als UNICODE VARCHAR oder AdVarWChar unabhängig von 'Importmixed' key value.hey

+0

Ich habe dies jetzt getestet, und in der Tat, wenn ich die erste Zeile alphanumerisch, dann funktioniert es wie erwartet. Mein Problem ist, dass ich dies nicht zur allgemeinen Regel machen kann, da die Kunden in ihren eigenen Blättern lesen werden. Allerdings war meine Lösung zu "cheaten", so dass ich HDR = No in der Verbindungszeichenfolge ändern, um sicherzustellen, dass der alphanumerische Header gelesen wird, um die Spalte alphanumerisch zu machen, dann schneide ich die erste Zeile der resultierenden DataTable. Es ist ziemlich eklig, aber ich sehe hier keine anderen Optionen. Vielen Dank für Ihre Hilfe, die mich in die richtige Richtung gebracht hat. –

+0

Sehr hinterhältig. Wenn es funktioniert, funktioniert es! –

1

IMEX=1 bedeutet "Lesen gemischten Daten als Text" gesetzt.

Es gibt jedoch einige Fehler. Jet verwendet nur mehrere Zeilen, um zu bestimmen, ob die Daten gemischt sind. Wenn dies der Fall ist, sind diese Zeilen alle numerisch, und Sie erhalten dieses Verhalten.

Siehe connectionstrings.com für Details:

Schauen Sie sich die [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel] befindet Registry REG_DWORD "TypeGuessRows". Das ist der Schlüssel, damit Excel nicht nur die ersten 8 Zeilen verwendet, um den Datentyp der Spalten zu erraten. Setzen Sie diesen Wert auf 0, um alle Zeilen zu scannen. Dies könnte die Leistung beeinträchtigen.Beachten Sie auch, dass das Hinzufügen der IMEX = 1-Option dazu führen kann, dass die IMEX-Funktion nach nur 8 Zeilen eingerichtet wird. Verwenden Sie stattdessen IMEX = 0, um sicherzustellen, dass die Registrierung TypeGuessRows = 0 (alle Zeilen scannen) erzwungen wird.

+0

Ich weiß nicht, wie Jet in Excel verfügbar gemacht wird, aber in Access können Sie solche Dinge zur Laufzeit in Ihrer aktuellen Instanz der Jet db-Engine ändern, ohne die Registrierung ändern und Access neu starten zu müssen. –

+0

Danke für diese Information. Es funktionierte, war aber überraschend langsam, also musste ich stattdessen mit dem "Lese- und Entsende-Header" -Trick gehen. –

1

Ich würde davon abraten, den OleDb-Datenprovider-Kram zu verwenden, um auf Excel zuzugreifen, wenn Sie ihm helfen können. Ich hatte nur Probleme, aus genau den Gründen, auf die andere hingewiesen haben. Auch bei großen Tabellenkalkulationen ist die Leistung meist grauenhaft.

Sie könnten diese Open-Source-Lösung versuchen: http://exceldatareader.codeplex.com/

+0

Ich stimme dir völlig zu Mark. Ich denke, es ist ziemlich schrecklich, aber in diesem Fall habe ich keine Optionen, da ich zugewiesen wurde, um diesen Fehler in einem bestehenden Programm zu beheben, und nicht die Zeit, um große Refactorings zu tun. Ich behalte Ihre Verbindung im Hinterkopf, wenn ich später von Grund auf neu machen muss. –

Verwandte Themen