CSV-Tabellen-Spalten einlesen

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von HaRoWagner.

    CSV-Tabellen-Spalten einlesen

    Ich habe eine CSV-Tabelle mit 24 Spalten und vielen tausend Zeilen. Die Datei ist ca. 20 MB groß. Tatsächlich interessant sind (für mich) nur jeweils zwei Spalten: Eine Spalte mit IDs und eine mit entsprechenden Werten. Meine Idee: Beides in seperate Listen schreiben. Ein Index der einen Liste gehört dann immer zum Index der anderen. Der Weg erscheint mir reichlich unprofessionell. Gibt es da Alternativen?

    Selbst wenn nein, dann ist dies so für mich nicht umsetzbar. Es sei denn folgender Ansatz ist, falls der erste überhaupt "richtig" ist, falsch bzw. es gibt eine schnellere Lösung. Die Spalten lese ich folgendermaßen ein (Das ist nur ein Test zur Überlegung der Vorgehensweise, nichts "ernstes"):

    VB.NET-Quellcode

    1. Dim sr As New StreamReader(New FileStream(strDir, IO.FileMode.Open))
    2. Dim list As New List(Of String)
    3. Dim i As Integer = 0
    4. Do While sr.EndOfStream = False
    5. list.AddRange(sr.ReadLine.Split(";", 24, StringSplitOptions.None))
    6. Loop
    7. For Each line In list
    8. If (i Mod 24) = 0 Then
    9. TextBox1.Text += vbCrLf & line
    10. End If
    11. i += 1
    12. Next


    Mit dieser Methode jedenfalls kann ich das ganze in die Tonne kloppen. Bei einem Test mit 20 Zeilen, die eingelesen werden, klappt das wunderbar. Bei meinen 15k+ Zeilen ist da aber kein Land in Sicht :(
    Wenn du nur den ersten Wert brauchst dann Add doch nur den ersten Wert aus dem Array von Split in deine StringList
    Nicht die Zeile in einem Rutsch in die Liste schreiben, sondern erst splitten und nur die 2 benötigten Spalten der Liste zufügen. Bau dir eine einfache Klasse um die List(Of T), dann gibt es auch kein vertun in der Liste selbst.

    HaRo
    @Hilfsbedürftiger: Split ist die falsche Wahl. Was passiert wenn innerhalb der Spalte ein ; vorkommt? Hast schon ein falsches Ergebnis.
    Ich hatte das selbst auch mal gebraucht und habe irgendwo im Netz ein Snippet gefunden.
    Ich habs so gelöst:
    TestConsolenanwendung:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Data.OleDb
    3. Module Module1
    4. Sub Main()
    5. Dim ConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ORDNERPFAD_ZUR_CSV_OHNE_DATEINAMEN;Extended Properties=Text;"
    6. Dim dtCSV As New DataTable("CSV")
    7. Using conCSV As New OleDbConnection(ConnectionString), daCSV As New OleDbDataAdapter("SELECT * FROM [Datei.CSV]", conCSV)
    8. daCSV.Fill(dtCSV)
    9. For i As Integer = 0 To dtCSV.Rows.Count - 1
    10. Debug.Print(dtCSV.Rows(i).Item(0).ToString)
    11. Next
    12. End Using
    13. End Sub
    14. End Module


    OLEDB-Adapter kennt wann eine neue Spalte ist und wann nicht auch wenn ein ; darin vorkommt.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Eine Befüllung nach STand der Technik kannstedir auch auf CSV importieren angugge.
    OleDB (also das meines Vorredners) ist auch Stand der Technik, und eiglich eleganter, aber zB mit Excel-Csv-Exporten kommts reihenweise zu ungemeldeten Lese-Fehlern und Fehlinterpretation der Datentypen.

    ErfinderDesRades schrieb:

    aber zB mit Excel-Csv-Exporten kommts reihenweise zu ungemeldeten Lese-Fehlern und Fehlinterpretation der Datentypen.

    Dazu kann ich leider nichts sagen. In meinem Fall wurde täglich eine Preisliste im Textformat (eben mit ; getrennt) runtergeladen. Diese musste dann eben ausgewertet werden. ;)

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten

    fichz schrieb:

    OLEDB-Adapter kennt wann eine neue Spalte ist und wann nicht auch wenn ein ; darin vorkommt.
    Woran denn? Ich bekomme meine CSV Dateien aus propritären System, deren Programme auf die Nixdorf Quattro 8870 zurückgehen. Das sind wirklich nur Textdateien, die mit Business Basic Programmen erstelle Textdateien schreiben. Nun laufen die zwar hardwareseitig auf Linux Systemen, aber programmtechnisch hat sich an den Dingern nichts geändert. Ich habe es nicht ausprobiert, kann mir aber beim besten Willen nicht vorstellen, woran der OLEDB Adapter erkennen können will, ob eine neue Spalte nur ein Semikolon in einem Adressfeld ist oder doch ein neues Datenfeld.

    HaRo
    Ehrlich gesagt verstehe ich Deine Antwort nicht. Wie soll ich das Escapen was ich bekomme? Ich habe auf die Daten die ich bekomme keinen Einfluß, ich kenne zwar die Quelle aber ich bekomme die Daten, nur die Daten und nichts als die Daten. Mit denen darf ich dann glücklich werden, so wie sie sind.

    Ich habe eben mal aus Spaß einen Auzug dieser Adressen Deiner HiHaHu Beispielanwendung vorgeworfen. Das selbe Ergebnis wie bei mir, nämlich Spaltenverschiebung. Wie gesagt, ich habe auf die Entladungen der Altsysteme keinen Einfluß, ich bekomme nur das Ergebnis.

    Stark verkürztes Beipiel aus einer CSV-Datei, es sind natürlich wesentlich mehr "Spalten" bzw. ausgelesene Werte. Hier handelt es sich jeweils um drei Felder
    Debitorennummer,Strasse, Ort
    471111;FLUGHAFENSTRAßE 54;HAUS A;HAMBURG
    471112;HOPFENGARTEN 42;HAMBURG

    HaRo

    HaRoWagner schrieb:

    Wie soll ich das Escapen was ich bekomme?
    Nein, sollst du nicht.
    Das ist Sache der Daten-Erzeuger, und du kannst bestenfalls drauf gugge, ob die sich an die Spezifikationen halten.
    Eiglich darfman vorraussetzen, dass die auch Csv liefern, wennse das sagen, aber ob sie's wirklich tun...
    Jdfs. ist nicht deine Schuld, wenns deswegen batscht, und es sind die Erzeuger dann in der Korrektur-Pflicht - nicht du.
    Oder aber du machst den Workaround, und lässt dir das bezahlen.
    Mhh okay, beruhigt mich nur, dass ich nicht so blöde war eine gute Funktion nicht zu kennen. Deine Anleitung / Funktion HiHaHu hat es mir trotzdem sehr angetan. So lernt man (ich) jedenfalls dazu.

    Ein Workaround wäre nicht sehr treffsicher bei 61 Feldern, die alleine diese Tabelle hat. Was ich mache: ich protokolliere das Auftreten von zuvielen Semikolons in einer Zeile und gebe ins Log die komplette Zeile zurück. Ansonsten muss ich eh jede Menge Informationen parsen um eine Vorhersage machen zu können, ob die Zieldatenbank mit der Zell-Information überhaupt etwas anfangen kann.

    Danke für die Antwort und Danke für die vielen guten Tutorials.

    HaRo
    jetzt habich nochmal geguckt

    Quellcode

    1. 471111;FLUGHAFENSTRAßE 54;HAUS A;HAMBURG
    2. 471112;HOPFENGARTEN 42;HAMBURG
    ist richtig böse ungültiges csv.

    richtig musses heißen:

    Quellcode

    1. 471111;"FLUGHAFENSTRAßE 54;HAUS A";HAMBURG
    2. 471112;HOPFENGARTEN 42;HAMBURG


    bischen kann man machen, wenn man seine ProblemSpalten-Pappenheimer kennt, und dann iwie von links und von rechts auszählen oder sowas.
    aber ist echt voll murksig
    Ja das stimmt, eigentlich ist es kein CSV. Rule 9.1 wird verletzt, aber auch 9.2 wie ich weiß ;)

    Der Würgaround würde schon gehen. weil es zu mind. 95% die Adressfelder sind. Aber es gibt natürlich auch ausnahmen.
    Daten verändern darf ich nicht. Ich bekomme die Daten aus einer Quelle und muss sie an einem Konverter verfüttern, der CSV auch nicht besser beherrscht.
    So habe ich es mir zur Aufgabe gemacht, die Betroffenen auf die Probleme generell hinzuweisen und die Daten mit einem selbstgehäkeltem Tool zu prüfen.
    Das Ergebnis der Prüfung ist dann das Todo für den Betrieb um das Vorhaben einigermassen Rund über die Bühne zu bekommen.

    HaRo