.txt Datei als DataSet nutzen

  • VB.NET

Es gibt 46 Antworten in diesem Thema. Der letzte Beitrag () ist von Sam85.

    Sam85 schrieb:

    Und so hätte ich es ja mit XML gemacht.

    RodFromGermany schrieb:

    Nein.
    Die XML, die von einer DataTable im- und exportiert werden kann, enthält wesentlich mehr Informationen z.B. zb: Spaltennamen und Datentyp.

    RodFromGermany schrieb:

    Zeilenweise einlesen, Split() am ";", Trim(), numerischje Werte mit .TryParse() konvertieren und in die DataTable vom DataSet schreiben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich steig immer noch nicht ganz dahinter, was zu tun ist.

    Ich hab also mein DataSet (Care_log) und meinen DataTable (CareLogFile) laut dem Bild, oder? (Nicht das ich die Bedeutung falsch verstehe)
    Aber der DataTable ist kein Member vom DataSet, was mich schließen lässt, dass ich vermutlich doch etwas falsch verstehe.
    Was betrachte ich dabei falsch?

    VB.NET-Quellcode

    1. Sub RunDT()
    2. Dim dsB As DataSet = Care_log
    3. Dim dtB As DataTable = dsB.Tables(0)
    4. Dim m As String = CB_Month.Text
    5. Dim dataFile As String = "\\rs-win1\ablage\300archiv\log\" & m & "\log.txt"
    6. Dim i As Integer
    7. Dim GTstr As String = "System.String"
    8. 'dtB.Rows.Clear()
    9. 'dtB.Columns.Clear()
    10. Dim tFile() As String = System.IO.File.ReadAllLines(dataFile)
    11. Dim cntColumns As Integer = dtB.Columns.Count
    12. For Each line As String In tFile
    13. Dim split() As String = line.Split(";"c)
    14. Dim row As DataRow = dtB.NewRow
    15. For i = 0 To cntColumns - 1
    16. row(i) = split(i)
    17. Next i
    18. dtB.Rows.Add(row)
    19. Next line
    20. CareLogFileDGV.DataSource = dtB
    21. End Sub


    EDIT:
    Das .Clear habe ich mal aus den Weg geschafft und nachgelesen, dass es dsb.Tables(0) bzw. ("CareLogFile") heißen muss.
    Bilder
    • Bild.JPG

      65,66 kB, 1.340×407, 113 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Sam85“ ()

    Langsam. Care_log ist eine konkrete DataSet-Instanz, mit der sich typisiert im Code arbeiten lässt. Warum legst Du in Zeile#2 einen neuen Verweis an? Genauso die DataTables. Die sind alle ganz konkret über care_log erreichbar.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Ok, dann bin ich wohl gerade auf dem Holzweg. Ich dachte ich müsste New dazu schreiben um ein neues DataSet anzulegen und so hätte ich einfach nur den Namen abgekürzt.
    Wie muss ich es dann deklarieren?
    Ich glaub Du hast da einiges nicht verstanden. Deinem Bild entnehme ich, dass Du für jede "Tabelle" ein eigenes Dataset im Designer gemacht hast. Ich kann mir nicht vorstellen, dass das Vorgehen überhaupt sinnhaft ist. Mach ein Dataset "Sanitaetshaus" und bau dann dort die Tabellen(!) Orthesen, Einlagen etc. alle ein. Alle Tabellen im Designer sind "strongly typed Datatables" also streng typisierte Datentabellen. Wenn man Inhalte (Tabellen oder auch nur bestimmte Feldinhalte) aus den "Datenquellen" per Drag and Drop auf das Formular zieht, hast der Designer Dir automatisch das Dataset und die verwendete Tabelle instanziert und dir die Bindingsource ebenfalls angelegt, sowie das Datagridview oder die Textboxen darüber gebunden.

    Was Du da mit dem Code veranstaltest ist, dass Du hier ein weiteres Dataset "dsB" und eine Datentabelle "dtB" erstellst. Diese sind aber nicht "strongy typed" und haben auch gar nichts mit den im Designer erzeugten DS/DT zu tun.
    Wie man eine Datentabelle einem Dataset manuell zufügt kannst Du hier lesen. Du kannst es aber auch gleich wieder lassen, denn die Vorgehensweise ist kaum zu empfehlen.
    Leider gibt es im Netz auch kaum gute Informationen zu "strongly typed Datasets / Datatables". Die besten Infos findest Du hier in diesem Forum.
    @VB1963 hat Dir bereits die best verfügbare Information ans Herz gelegt und ich kann auch nur eines tun. Suche hier nach allem was @ErfinderDesRades an Tutorials verfasst hat. Zu Datasets gibt es nichts besseres.

    Lese das alles erstmal genau. Du scheinst Dich ganz fürchterlich zu verhaspeln.
    @Dksksm

    Ich verstehe was du meinst und bestätige auch zu 100% das es nicht Sinnhaft wäre, dass sind einfach nur Übungsprojekte und ich arbeite auch an keiner "Software" für ein Sanitätshaus. Für mich sind es nur kleine Hilfswerkzeuge für meine täglichen Routinen, daher gibt es kein DataTree wo alles DataSets sind, sondern nur meine Lern- und Anwendungsbaustellen.

    Ja ich habe das Tutorial gelesen, nur kann ich es nicht auf mein Bsp. übertragen (liegt sicherlich auch daran, dass ich Fachfremd bin was Programmierung betrifft). Daher bin ich ja hier gelandet und versuche es zu verstehen und daher danke für alle Arten von Hinweisen. :)

    Also gut das heisst Dim dsB as DataSet = Care_log bezieht sich nicht auf das DataSet im Designer sondern erstellt einfach ein neues. Es reicht also wenn ich einfach z. B. in Zeile 16 schreibe

    VB.NET-Quellcode

    1. Dim cntColumns As Integer = Care_log.Tables(0).Columns.Count

    Langsam. Was heißt hier Care_log.Tables(0).Columns.Count. Greif lieber gleich auf CareLogFile zu (das ist doch immer noch der Name Deiner Dattable, richtig?), sonst kommst Du schneller als Du denkst in den untypisierten Bereich. Und dann wird's bald Grütze.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Sam85
    folgendes Tutorial von @ErfinderDesRades solltest du einmal anschauen (Film VIII)
    Film VIII - Coden in typisierter Manier: Typisierung stellt geniale Properties und Methoden bereit, mit Intellisense- und Compiler-Unterstützung - man muß sie aber auch benutzen - andernfalls codet man Müll. Bezeichnend ist, dass die Demonstration wie mans nicht macht, im Video mehr Raum einnimmt, als wie mans macht. Grund ist, dasses eben einfacher ist, wenn mans richtig macht Nämlich bis 00:59 ist die Aufgabe vorgestellt, von 01:00 - 07:59 werden die Nachteile untypisierten Code-Horrors auseinandergenommen, und erst ab 08:00 wird kurz gezeigt, wies richtig muss. Trotzdem auch den CodeHorror angucken - es gibt glaub nicht einen Programmierer, der von Anfang an bereits gänzlich uninfiziert war von der untypisierten Programmier-Seuche. Und anders als natürliche Krankheiten heilen Programmier-Seuchen nicht von selbst, sondern man muss die Krankheit scharf ins Auge fassen - dann verschwindet sie

    die vier Views auf Video

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    @Dksksm
    also Vorzugsweise würde ich typisiert arbeiten. Im Vorfeld war ich mir nicht bewusst, dass ich mit einer .txt Datei auch typisiert arbeiten kann, von daher habe ich den zuerst genannten Weg eingeschlagen.
    Ggf. habe ich auch unterschiedliche Aspekte nicht korrekt aufgenommen, was die Herangehensweise von @RodFromGermany betroffen hat (vielleicht war seine Empfehlung von Beginn an auch typisiert gemeint und ich hab sie untypisiert umgesetzt, aufgrund meiner Fehlinterpretation).

    @VaporiZed
    Genau das CareLogFile ist meines Erachtens das DataTable. Ich bekomme von IntelliSense aber immernur die CareLogFileBindingSource zur Verfügung gestellt. Bin ich da an einer Stelle falsch abgebogen oder ist das der entsprechende Verweis, den ich zum Daten befüllen nutzen muss?

    @VB1963
    das werde ich mir mal ansehen, vielen Dank.

    Sam85 schrieb:

    dass ich mit einer .txt Datei auch typisiert arbeiten kann
    Moment. Das passt inhaltlich nicht zusammen. In Deiner Text-Datei kann sonstewas drin stehen. Das ist so ziemlich egal, da die Daten nur Rohdaten sind. Typisiert und untypisiert betrifft die Behandlung Deines tDS mittels Code. Wenn Du schreibst

    VB.NET-Quellcode

    1. Dim CurrentClerk = YourTds.CareLogFile(0).Sachbearbeiter

    dann ist das typisiert.
    Wenn Du hingegen mit solch einem Kram anfängst:

    VB.NET-Quellcode

    1. Dim CurrentText = YourTds.Tables(0).Rows(0).Item(1).ToString()

    oder mit Strings zum Referenzieren/Auffinden einer DataTable/DataColumn anfängst, dann bist Du auf der dunklen Seite der ... bei untypisiert angekommen.

    Dass IntelliSense nur die BindingSource anzeigt, könnte daran liegen, dass Du im Code erst (fast) immer mit dem Namen Deiner tDS-Instanz (nicht dem tDS-Klassennamen) anfangen musst. Eben so, wie ich im typisierten Beispiel schreib. Aber wie VB1963 schon meinte. EdR hat alles relevante in seinen Tutorials schon beschrieben. Das wäre moppelt gedoppelt, wenn ich hier alles nochmal beschreibe.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Ah ok, also so muss es dann so sein?
    Wenn ich jetzt die BindingSource nutze, wird aber nur einmal ein Wert eingetragen und wenn ich dann eine andere Zeile auswähle, ändert sich nichts.
    Scheint also doch noch irgendwas nicht richtig zu sein.

    VB.NET-Quellcode

    1. Sub RunDT()
    2. Dim m As String = CB_Month.Text
    3. Dim dataFile As String = "\\rs-win1\ablage\300archiv\log\" & m & "\log.txt"
    4. Dim dsB = Care_log
    5. Dim dsT = dsB.CareLogFile
    6. Dim i As Integer
    7. Dim tFile() As String = System.IO.File.ReadAllLines(dataFile)
    8. Dim cntColumns As Integer = dsT.Columns.Count
    9. For Each line As String In tFile
    10. Dim split() As String = line.Split(";"c)
    11. Dim row As DataRow = dsT.NewRow
    12. For i = 0 To cntColumns - 1
    13. row(i) = split(i)
    14. Next i
    15. dsT.Rows.Add(row)
    16. Next line
    17. CareLogFileDGV.DataSource = dsT
    18. End Sub
    Was soll denn dauernd der Hunz mit dem temporären tDS? Lösch Zeile#5 und #6 raus und arbeite mit dem, was Du hast:
    Care_log ist der Name Deiner tDS-Instanz für jenes Formular. Und CareLogFile Deine DataTable. Dann benutz die doch. Ohne Umwege.
    Und mit Zeile#16 bist Du bei untypisiert angekommen. row sollte keine DataRow sein, sondern eine CareLogFileRow. Dort untypisiert irgendwelche DataRowItems zuzuordnen scheint vielleicht momentan praktisch, wird m.E. Dir irgendwann aber richtig schön ins Knie schießen, wenn da keine Strings mehr in der DataTable erwartet werden.
    Und Zeile#26? Wozu hast Du Deine BindingSource, wenn Du sie übergehst? Das CareLogFileDGV hat das Datenquelle die BindingSource. Die BindingSource hat als Datenquelle Care_log. Ich weiß zwar nicht, was im DGV angezeigt werden soll. Aber sobald Du Dein tDS änderst, ändert sich der Inhalt der BindingSource-DataSource und somit auch der Inhalt des DGV. Ganz von allein. Ohne Zusatzcodezeilen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Danke, jetzt funktioniert es. :thumbsup:

    Kann ich Dim ds = Care_log und Dim dt = ds.CareLogFile dennoch lassen oder ist das ein unglückliches Coding?

    VB.NET-Quellcode

    1. Sub RunData()
    2. Dim m As String = CB_Month.Text
    3. Dim dataFile As String = "\\rs-win1\ablage\300archiv\log\" & m & "\log.txt"
    4. Dim ds = Care_log
    5. Dim dt = ds.CareLogFile
    6. Dim i As Integer
    7. Dim tFile() As String = System.IO.File.ReadAllLines(dataFile)
    8. Dim cntColumns As Integer = dt.Columns.Count
    9. For Each line As String In tFile
    10. Dim split() As String = line.Split(";"c)
    11. Dim row As care_log.CareLogFileRow = dt.NewCareLogFileRow
    12. For i = 0 To cntColumns - 1
    13. row(i) = split(i)
    14. Next i
    15. dt.Rows.Add(row)
    16. Next line
    17. End Sub

    Sam85 schrieb:

    Kann ich Dim ds = Care_log und Dim dt = ds.CareLogFile dennoch lassen oder ist das ein unglückliches Coding?

    Ich beziehe mich jetzt auf deinen Eingangspost, wo du dein Datenmodel angezeigt hast...
    Ich nenne das typ. Dataset DtsCareLog und die Tabelle CareLogFile ...
    Weiters habe ich auf Grund deines Datenmaterials die Columns der Tabelle mit folgenden Datentypen festgelegt:
    LogTA3 = String
    Rechnung = Integer
    Monat = Integer
    Imageempfaenger = Integer
    Kostentraeger = Integer
    Sachbearbeiter = String
    Status = String
    Auf meine Verlinkung im Post #10 (Tutorial 'CSV importieren' von EDR) sollte die Datenübertragung dann so aussehen, wenn dein Dataset wie oben beschrieben aufgebaut ist:

    VB.NET-Quellcode

    1. Private Sub LoadLogData(ByVal pathDataFile As String)
    2. Using tfp = New Microsoft.VisualBasic.FileIO.TextFieldParser(pathDataFile, Encoding.Default)
    3. tfp.SetDelimiters(";")
    4. Do
    5. Dim fields = tfp.ReadFields
    6. If fields Is Nothing Then Return 'bei diesem eintrag sind keine Felder mehr vorhanden
    7. '
    8. 'die Felder mit dem richtigen Datentyp erfassen...
    9. Dim LogTA3 = fields(0)
    10. Dim Rechnung = CInt(fields(1))
    11. Dim Monat = CInt(fields(2))
    12. Dim Imageempfaenger = CInt(fields(3))
    13. Dim Kostentraeger = CInt(fields(4))
    14. Dim Sachbearbeiter = fields(5)
    15. Dim Status = fields(6)
    16. '
    17. 'die Felder auf dem typ. Weg übergeben...
    18. DtsCareLog.CareLogFile.AddCareLogFileRow(LogTA3,
    19. Rechnung,
    20. Monat,
    21. Imageempfaenger,
    22. Kostentraeger,
    23. Sachbearbeiter,
    24. Status)
    25. Loop
    26. End Using
    27. End Sub
    Schaue dir die Zeilen #17-#24 einmal an...
    Hier ist es sehr wichtig, dass die Felder aus dem LogFile in die richtigen Datentypen umgewandelt werden können und mit jenen im typ. DS zusammenpassen...
    @VB1963

    Ist die andere Methode nicht zu empfehlen?
    ich versuch das Andere mal.

    Encoding.Default kann ich bei mir nicht eingeben, es kommt dann zur Auswahl z. B. defaultEncoding:=. Ist das gleichbedeutend? Und wenn ja, was soll ich dann hinter dem = eingeben?

    Sam85 schrieb:

    Ist die andere Methode nicht zu empfehlen?
    Nein - du verwendest dein Dataset dort untypisiert und die Einlesecode kann falsche Ergebnisse liefern (lese bitte dazu meine Verlinkungen!)
    Verwende die 4. Signatur (siehe Bildchen dazu) und verwende beim 2.Argument die Encoding-Enumeration mit Default...

    @VB1963
    Vielen Dank, ja hätte ich selber sehen müssen..

    VB.NET-Quellcode

    1. Sub RunData()
    2. Dim m As String = CB_Month.Text
    3. Dim dataFile As String = "\\rs-win1\ablage\300archiv\log\" & m & "\log.txt"
    4. Using tfp = New Microsoft.VisualBasic.FileIO.TextFieldParser(dataFile, System.Text.Encoding.Default)
    5. tfp.SetDelimiters(";")
    6. Do
    7. Dim fields = tfp.ReadFields
    8. If fields Is Nothing Then Return
    9. Dim TA3Log = fields(0)
    10. Dim ID = CInt(fields(1))
    11. Dim Rechnung = CInt(fields(2))
    12. Dim Monat = CInt(fields(3))
    13. Dim ImageempfängerIK = CInt(fields(4))
    14. Dim KostenträgerIK = CInt(fields(5))
    15. Dim Sachbearbeiter = fields(6)
    16. Dim Korrekturstatus = CInt(fields(7))
    17. Care_log.CareLogFile.AddCareLogFileRow(TA3Log, ID, Rechnung, Monat, ImageempfängerIK, KostenträgerIK, Sachbearbeiter, Korrekturstatus)
    18. Loop
    19. End Using
    20. End Sub
    Nun wo das funktioniert, wie kann ich neue Zeilen in das DataSet schreiben und speichern?

    Schreiben mache ich jetzt mit dem Code unten, aber wie bekomme ich die Daten zurück in .txt Datei?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Care_log.CareLogFile.Rows.Add(indexABRP, indexRECP, RG, Monat, TA4_IK, KST, MA, index, APOK)

    Du musst Dir nen eigenen Miniexporter schreiben, der Deine DataRow auseinanderpfriemelt und die einzelnen Werte in ne Textdatei schiebt. Automatik geht von Haus aus nur, dass Du ne XML-Datei erzeugst.
    Also Rolle rückwärts, hier mit Semikolon getrennt:

    VB.NET-Quellcode

    1. Dim FinalText As New Text.StringBuilder
    2. For Each Row In Care_log.CareLogFile
    3. FinalText.AppendLine($"{Row.TA3Log.ToString()};{Row.ID.ToString()};...")
    4. Next
    5. IO.File.WriteAllText(FinalText.ToString())

    So auf die Schnelle aus'm Kopf heraus.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.