Frage

Ich habe eine C # /. Net Arbeit, die importiert Daten aus Excel und verarbeitet sie dann. Unser Kunde abfällt Dateien und wir verarbeiten sie (wichtig, weil ich keine Kontrolle über die Original-Datei).

Ich verwende die OleDb Bibliothek einen Datensatz zu füllen (ich hasse diesen Code zu schreiben. Im Ernst, gibt es einen Code, der ein .NET-Entwickler Dreads mehr als das Schreiben?). Die Datei enthält einige Zahlen wie 30829300, 30071500, etc ... Der Datentyp für diese Spalten ist „Text.“

Diese Zahlen werden in der wissenschaftlichen Notation konvertiert, wenn ich die Daten importieren. Gibt es trotzdem zu verhindern, dass dies geschieht?

-Chris

War es hilfreich?

Lösung

Die OleDb Bibliothek , mehr als oft nicht, verwirrung Ihrer Daten in einer Excel-Tabelle nach oben. Dies ist vor allem, weil es alles in einen Fest Typ Spaltenlayout zwingt, raten am Typ jeder Spalte von den Werten in den ersten 8 Zellen in jeder Spalte. Wenn es falsch errät, beenden Sie mit Ziffernketten umgewandelt wissenschaftlich-Notation auf. Blech!

Um dies zu vermeiden, du bist besser dran, die OleDb Überspringen und das Blatt direkt selbst zu lesen. Sie können dies tun, um die COM-Schnittstelle von Excel (auch BLECH!) Oder einen Drittanbieter .NET Excel-kompatibele Leser. SpreadsheetGear ist eine solche Bibliothek, die recht gut funktioniert und hat eine Schnittstelle, die die Excel-COM-Schnittstelle sehr ähnlich ist.

Andere Tipps

Eine Abhilfe für dieses Problem ist die Select-Anweisung zu ändern, statt SELECT * dies tun:

"SELECT Format([F1], 'General Number')  From [Sheet1$]"
 -or-
"SELECT Format([F1], \"#####\")  From [Sheet1$]"

Doch damit wird die Luft zu sprengen, wenn Ihre Zellen mit dem folgenden Fehler mehr als 255 Zeichen enthalten: „Mehreren Schritten bestehenden OLE DB-Vorgang Fehler erzeugt. Prüfen Sie alle OLE DB-Statuswerte, falls vorhanden. Keine Arbeit getan wurde.“

Zum Glück meines Kunde nicht in diesem Szenario über erroring out scherte.

Diese Seite hat eine Reihe von guten Dingen auch versuchen: http: //www.dicks- blog.com/archives/2004/06/03/external-data-mixed-data-types/

Mit dieser Verbindungszeichenfolge:

Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"

mit Excel 2010 Ich habe folgendes bemerkt. Wenn die Excel-Datei geöffnet ist, wenn Sie die OLEDB SELECT laufen dann erhalten Sie die aktuelle Version der Zellen, nicht die gespeicherte Datei Werte. Darüber hinaus sind die Stringwerte zurück für eine lange Zahl, Dezimalwert und Datum wie folgt aussehen:

5.0130370071e+012
4.08
36808

Wenn die Datei nicht geöffnet ist dann die zurückgegebenen Werte sind:

5013037007084
£4.08
Monday, October 09, 2000

Wenn man sich die tatsächlichen .xslx Datei mit Open XML SDK 2.0 Productivity Tool (oder einfach entpacken Sie die Datei und sehen Sie die XML im Editor) Sie werden sehen, dass Excel 2007 tatsächlich speichert die Rohdaten im wissenschaftlichen Format.

Zum Beispiel 0,00001 gespeichert als 1.0000000000000001E-5

<x:c r="C18" s="11" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:v>1.0000000000000001E-5</x:v>
</x:c>

in der Zelle der Suche in Excel seine angezeigt als 0,00001 sowohl in der Zelle und die Bearbeitungsleiste. So ist es nicht immer wahr, dass OleDB das Problem verursacht.

Ich habe festgestellt, dass der einfachste Weg ist, Zip-Format zu wählen, anstatt Textformat für Spalten mit großen ‚Zahlen‘.

Haben Sie versucht, den Wert des Feldes Gießen (int) oder vielleicht (Int64), wie Sie es lesen?

Sehen Sie die IMEX = 1 Verbindungszeichenfolge Option und TypeGuessRows Registrierungseinstellung auf google. In Wahrheit gibt es keine einfache Möglichkeit, rund um das, weil der Leser durch einen Blick auf den ersten Reihen (8 standardmäßig) Spaltendatentypen folgert. Wenn die Zeilen alle Zahlen enthalten dann bist du kein Glück.

Eine unglückliche Abhilfe, die ich in der Vergangenheit verwendet habe, ist die HDR verwenden = keine Verbindungszeichenfolge Option und stellen Sie den TypeGuessRows Registrierungseinstellung Wert auf 1, die es die erste Zeile als gültige Daten zu lesen zwingt, seine Datentypbestimmung zu machen , sondern als ein Header. Es ist ein Hack, aber es funktioniert. Der Code liest die erste Zeile als Text (den Header enthält) und setzt dann den Datentyp entsprechend.

Ändern der Registry ein Schmerz ist (und nicht immer möglich), aber ich würde empfehlen, danach den ursprünglichen Wert wiederherzustellen.

Wenn Sie Ihre Importdaten nicht über eine Kopfzeile haben, dann eine alternative Option ist die Datei vorverarbeitet, und fügen Sie ein 'Zeichen vor jedem der Zahlen in der säumigen Spalte. Dies bewirkt, dass die Spaltendaten als Text behandelt werden.

Alles in allem gibt es eine Reihe von Hacks, dies zu umgehen, aber nichts wirklich narrensicher.

Ich hatte das gleiche Problem, aber war in der Lage, um es zu arbeiten, ohne auf die Excel-COM-Schnittstelle oder 3rd-Party-Software zurückgreifen. Es geht um einen wenig Verarbeitungsaufwand, scheint aber für mich zu arbeiten.

  1. Erste in den gelesenen Daten die Spaltennamen erhalten
  2. Erstellen Sie dann ein neues DataSet mit jeder dieser Säulen, die jeweils ihre Datentypen String-Einstellung.
  3. Lesen Sie die Daten wieder in diese neue Dataset. Voila - wissenschaftliche Notation ist jetzt weg und alles wird eingelesen als String zurück.

Hier ist ein Code, der dies veranschaulicht, und als zusätzlichen Bonus, es ist sogar StyleCopped!

public void ImportSpreadsheet(string path)
{
    string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1";
    string connectionString = string.Format(
        CultureInfo.CurrentCulture,
        "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"",
        path,
        extendedProperties);

    using (OleDbConnection connection = new OleDbConnection(connectionString))
    {
        using (OleDbCommand command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM [Worksheet1$]";
            connection.Open();

            using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
            using (DataSet columnDataSet = new DataSet())
            using (DataSet dataSet = new DataSet())
            {
                columnDataSet.Locale = CultureInfo.CurrentCulture;
                adapter.Fill(columnDataSet);

                if (columnDataSet.Tables.Count == 1)
                {
                    var worksheet = columnDataSet.Tables[0];

                    // Now that we have a valid worksheet read in, with column names, we can create a
                    // new DataSet with a table that has preset columns that are all of type string.
                    // This fixes a problem where the OLEDB provider is trying to guess the data types
                    // of the cells and strange data appears, such as scientific notation on some cells.
                    dataSet.Tables.Add("WorksheetData");
                    DataTable tempTable = dataSet.Tables[0];

                    foreach (DataColumn column in worksheet.Columns)
                    {
                        tempTable.Columns.Add(column.ColumnName, typeof(string));
                    }

                    adapter.Fill(dataSet, "WorksheetData");

                    if (dataSet.Tables.Count == 1)
                    {
                        worksheet = dataSet.Tables[0];

                        foreach (var row in worksheet.Rows)
                        {
                            // TODO: Consume some data.
                        }
                    }
                }
            }
        }
    }
}

gegoogelt ich um diesen Zustand .. Hier sind meine solulition Schritte

  • Für Vorlage Excel-Datei

1-Format Excel coloumn als Text 2- Schreibmakrofehler Warnungen für Nummer deaktivieren -> Text convertion

  Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ErrorCheckingOptions.BackgroundChecking = Ture
End Sub
Private Sub Workbook_Open()
Application.ErrorCheckingOptions.BackgroundChecking = False
End Sub
  • Ein Code-Behind

3-, während der Einfuhr Lesen von Daten versuchen, um eingehende Daten zu Int64 oder Int32 zu analysieren ....

Ich bin daran interessiert zu wissen, ob jemand eine Antwort auf diese bekam. Ich habe alle Höhen und Tiefen der interwebs und versuchte, alle Kombinationen von IMEX und HDR. IMEX = 1 ist das einzige, das ich es geschafft, mit Datum, Währung und allgemeine Zahlenwerte zu extrahieren. Aber große Zahlen noch als wissenschaftliches zeigen. Ich muß nur Dateien lesen und Ändern von Tabellen, die Registrierung, 3rd-Party ist keine Option.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top