VB Textfiles nach Spalten durchsuchen

  • VB.NET

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    So jetzt mit Option Strict On, hab es diesmal in ein Sub gemacht und Listbox so ähnlich ist es bei mir im Programm. Der erste Schritt wäre vermutlich das in eine Funktion zu machen. Ich vermute der Backgroundworker wäre angebracht. Noch irgendwelche Verbesserungsvorschläge?

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.ComponentModel
    3. Imports System.IO
    4. Public Class Form1
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. Dim suchzeile As String
    7. Dim suchbegriff As String
    8. suchbegriff = TextBox1.Text
    9. Dim x As Integer 'ausgewählte Spalte
    10. x = 1
    11. Dim suchergebnisse As New ArrayList
    12. For Each file As String In My.Computer.FileSystem.GetFiles("C:\Neuer Ordner", FileIO.SearchOption.SearchAllSubDirectories, "*txt")
    13. Dim sr1 As New System.IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read)
    14. Dim reader1 As New System.IO.StreamReader(sr1)
    15. Do Until reader1.EndOfStream
    16. suchzeile = reader1.ReadLine
    17. If suchzeile.Contains(suchbegriff) Then
    18. Dim spalten = Split(suchzeile, vbTab)
    19. If spalten(x).Contains(suchbegriff) Then
    20. suchergebnisse.Add(suchzeile)
    21. End If
    22. End If
    23. Loop
    24. Next
    25. For Each ergebnis In suchergebnisse
    26. ListBox1.Items.Add(ergebnis)
    27. Next
    28. End Sub
    29. End Class

    So?? Sorry bin Anfänger... Weiss nicht so genau was du meinst...

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.ComponentModel
    3. Imports System.IO
    4. Public Class Form1
    5. Public Function test() As String
    6. Dim suchzeile As String
    7. Dim suchbegriff As String
    8. suchbegriff = TextBox1.Text
    9. Dim x As Integer 'ausgewählte Spalte
    10. Dim suchergebnisse As New ArrayList
    11. For Each file As String In My.Computer.FileSystem.GetFiles("C:\Neuer Ordner", FileIO.SearchOption.SearchAllSubDirectories, "*txt")
    12. Dim sr1 As New System.IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read)
    13. Dim reader1 As New System.IO.StreamReader(sr1)
    14. Do Until reader1.EndOfStream
    15. suchzeile = reader1.ReadLine
    16. If suchzeile.Contains(suchbegriff) Then
    17. Dim spalten = Split(suchzeile, vbTab)
    18. If spalten(x).Contains(suchbegriff) Then
    19. Return suchzeile
    20. End If
    21. End If
    22. Loop
    23. Next
    24. End Function
    25. End Class
    ist nicht ungewöhnlich, wenn man erstmalig damit konfrontiert wird, dass es in OOP-Sprachen verschiedene Datentypen gibt.
    Deine funtion test returnt nun Datentyp String, also wenn du die aufrufst (was ich bezweifel), so liefert die dir einen String zurück.
    Ein string ist aber gänzlich nutzlos, um in eine Listbox gefüllt zu werden, die Listbox willst du ja mit vielen Strings füllen, oder?

    Also mach, dass deine function test viele Strings returnt, zB eine List(of String). Dann wird auf einmal alles ganz einfach:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. ListBox1.DataSource = Txtdurchsuchen(TextBox1.Text, 1)
    3. End Sub
    4. Private Function Txtdurchsuchen(suchbegriff As String, x As Integer) As List(Of String)
    5. Dim suchergebnisse As New List(Of String)
    6. For Each filename In System.IO.Directory.GetFiles("C:\Neuer Ordner", "*.txt", SearchOption.AllDirectories)
    7. For Each suchzeile In File.ReadLines(filename)
    8. Dim spalten = suchzeile.Split(Microsoft.VisualBasic.ControlChars.Tab)
    9. If spalten(x).Contains(suchbegriff) Then suchergebnisse.Add(suchzeile)
    10. Next
    11. Next
    12. Return suchergebnisse
    13. End Function


    Und befolge auch den anderen Hinweis, der in Visual Studio - Empfohlene Einstellungen empfohlen wird - nämlich den Deppen-Namespace rauszuwerfen.
    Ich fürchte allerdings, du wirst dir sehr schwer damit tun, evtl. hast du hunderte oder gar tausende Zeilen Code, und der ist jetzt großflächig umzustellen auf OOP.
    Ist aber letztlich egal, das lohnt sich auf alle Fälle, und in vielerlei Hinsicht:
    • der Code wird effizienter
    • er wird leichter verständlich
    • er wird für Verbesserungen / Veränderungen leichter zugänglich (Stichwort "Entwicklung")
    • sicherer
    • du lernst, Datentypen zu unterscheiden
    • du lernst Objekte objektorientiert anzusprechen
    • ...

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

    RodFromGermany schrieb:

    VB.NET-Quellcode

    1. For Each line In File.ReadLines("deine txt")

    gitarre94 schrieb:

    VB.NET-Quellcode

    1. Dim reader1 As New System.IO.StreamReader(sr1)

    gitarre94 schrieb:

    Verbesserungsvorschläge
    Beratungsresistent?
    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!
    @RodFromGermany
    Wieso ist deine Variante mit for Each line besser? Habe beide Varainten ausgetestet ( Zwar nicht bei einer soo großen datei) aber die Laufzeiten zwischen meiner und deiner Variante ist so ziemlich fast identisch.

    @mox
    wenn ich alles in eine Datetable schreiben will muss ich jede einzelne Zeile in der Textdatei spliten und in die Datatable hineinschreiben. Ich vermute dass das sehr viel Laufzeit kostet.
    Mit der Streamreader Variante muss ich nur die Zeilen in denen der Suchbegriff vorkommt spliten --> meine Vermutung dass es schneller ist. Kann aber auch unrecht haben.

    gitarre94 schrieb:

    besser
    Sie ist kürzer und übersichtlicher, besser lesbar.
    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!

    gitarre94 schrieb:

    wenn ich alles in eine Datetable schreiben will muss ich jede einzelne Zeile in der Textdatei spliten und in die Datatable hineinschreiben
    Die Idee dahinter war, das durch einen optimierten DB-Provider machen zu lassen (z.B. ODBC.net).
    Grundidee: htmlgoodies.com/primers/databa…ta-access-components.html
    Damit kannst du deine CSV-Datei wie eine Datenbanktabelle ansprechen und beliebige SELECT-Methoden darauf anwenden.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    ich frag mich grad, was hier diskutiert wird.
    Zunächstmal täte mich freuen zu erfahren, ob meine Lösung in post#25 funktioniert.
    Die ist nämlich auf minimalen Speicherbedarf bei (fast) beliebig großen Dateien hin optimiert, und glaub auch kaum an Geschwindigkeit zu überbieten.
    Klar haben andere Ansätze Vor- und Nachteile, bei mir ist die Optimalität halt dadurch erkauft, dass die "Abfrage" recht unflexibel hardcodet ist - andere Ansätze mögen da Vorzüge haben (durcht andere Nachteile erkauft).

    Aber bevor jetzt alle Tauben des Himmels besprochen werden möchte ich wenigstens drauf hinweisen, dass wir bereits einen Spatz in der Hand haben - einfach, dass das nicht vergessen wird ;)
    @ErfinderDesRades
    kann bestötigen dass das funktioniert und vermutlich auch die schnellste Lösung ist. Danke!

    ErfinderDesRades schrieb:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. ListBox1.DataSource = Txtdurchsuchen(TextBox1.Text, 1)
    3. End Sub
    4. Private Function Txtdurchsuchen(suchbegriff As String, x As Integer) As List(Of String)
    5. Dim suchergebnisse As New List(Of String)
    6. For Each filename In System.IO.Directory.GetFiles("C:\Neuer Ordner", "*.txt", SearchOption.AllDirectories)
    7. For Each suchzeile In File.ReadLines(filename)
    8. Dim spalten = suchzeile.Split(Microsoft.VisualBasic.ControlChars.Tab)
    9. If spalten(x).Contains(suchbegriff) Then suchergebnisse.Add(suchzeile)
    10. Next
    11. Next
    12. Return suchergebnisse
    13. End Function



    Ich glaube, es schadet nichts zu wissen, wie eine Taube aussieht.
    Auch wenn man sich heute mit einem Spatz zufrieden geben kann, könnte es sein, dass beim nächsten Mal eine Taube gefordert ist.
    Wenn man dann weiß, wie sie aussieht und wie man sie fangen kann, ist schon mal ein Schritt in die richtige Richtung getan.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    jo, haste auch recht.
    Und dein Täubchen gfallt mir sogar recht gut, weil es lädt eben auch nicht die ganze Datei in ein Dataset, sondern nur die Ergebnisse.
    Und das ist allerdings vorteilhaft zur Weiterverarbeitung.
    Weil wie's bisher ist - einfach die Treffer-Zeilen in einer Listbox - viel gscheit was anfangen kann man damit nicht, meiner Meinung nach.