TextFieldParser Function

  • VB.NET

Es gibt 33 Antworten in diesem Thema. Der letzte Beitrag () ist von hate_regex.

    TextFieldParser Function

    Servus :)

    Ich habe mir eine Funktion gebaut, mit der ich CSV-Daten parsen kann. Idealerweise direkt in ein DataGrid:

    VB.NET-Quellcode

    1. Function LoadCSV(ByVal Pfad As String)
    2. Using Parser = New Microsoft.VisualBasic.FileIO.TextFieldParser(Pfad, Encoding.Default)
    3. Parser.SetDelimiters(";")
    4. Dim CSVType As Integer = Parser.ReadFields.Length
    5. Select Case CSVType
    6. Case 3 'Attribute
    7. Dim List = New List(Of Attribut)
    8. Dim Fields = Parser.ReadFields
    9. Dim LineCount As Integer = 0
    10. While Fields IsNot Nothing
    11. LineCount = LineCount + 1
    12. List.Add(New Attribut(LineCount, "?", Fields(0), Fields(1), Fields(2)))
    13. Fields = Parser.ReadFields
    14. End While
    15. Return List
    16. Case 8 'Komponente
    17. Dim List = New List(Of Komponente)
    18. Dim Fields = Parser.ReadFields
    19. Dim LineCount As Integer = 0
    20. While Fields IsNot Nothing
    21. LineCount = LineCount + 1
    22. List.Add(New Komponente(LineCount, "?", Fields(0), Fields(1), Fields(2), Fields(3), Fields(4), Fields(5), Fields(6), Fields(7)))
    23. Fields = Parser.ReadFields
    24. End While
    25. Return List
    26. Case 15 'System
    27. Dim List = New List(Of System)
    28. Dim Fields = Parser.ReadFields
    29. Dim LineCount As Integer = 0
    30. While Fields IsNot Nothing
    31. LineCount = LineCount + 1
    32. List.Add(New System(LineCount, "?", Fields(0), Fields(1), Fields(2), Fields(3), Fields(4), Fields(5), Fields(6), Fields(7), Fields(8), Fields(9), Fields(10), Fields(11), Fields(12), Fields(13), Fields(14)))
    33. Fields = Parser.ReadFields
    34. End While
    35. Return List
    36. End Select
    37. End Using
    38. End Function

    Die Listen selbst habe ich als Property angelegt:

    VB.NET-Quellcode

    1. Private LINE_VALUE As String
    2. Public Property LINE() As String
    3. Get
    4. Return LINE_VALUE
    5. End Get
    6. Set(ByVal value As String)
    7. LINE_VALUE = value
    8. End Set
    9. End Property

    Sofern ich das ganze als Module anlege, kann ich problemlos darauf zugreifen, als Klasse: Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis.
    Was mache ich hier falsch?

    Weiter: Return-Werte. Wie man sieht liefert der Code nicht in allen Pfaden ein Ergebnis zurück. Funktioniert, aber eben unsauber. Da ich die Liste erst im Case definiere, wüsste ich nicht, wie ich das Returnvalue anders übergeben sollte. Ich wollte das wenn möglich gleich als ReturnType angeben: Function LoadCSV(ByVal Pfad As String) as List(of ?)

    Vielen Dank!

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

    hate_regex schrieb:

    Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis.
    Erstell eine Instanz per New und greif darauf über die betreffende Instanz zu oder mach die Prozedur Shared.
    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!
    @ErfinderDesRades:: Jou.
    @hate_regex:: Und schreib, in welcher Zeile der Fehler auftritt.
    Du kannst nicht eine Funktion machen, die in verschiedenen Cases unterschiedliche Return-Values hat.
    Da solltest Du Dich mal mit den Grundlagen von Funktionen befassen, gugst Du z.B. hier.
    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!
    Fehler 2 - Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis (in Main_Form.vb)
    Zeile 8, Spalte 34

    In der Zeile habe ich den Funktionsaufruf:

    VB.NET-Quellcode

    1. Me.DataGrid.DataSource = CSV_Import.LoadCSV("C:\sys.csv")

    Option Strict On - damit wollte ich mich erst beschäftigen, wenn ich die Funktion grundlegend verstanden habe/es funktkioniert. An welcher Stelle habe ich denn unterschiedliche Return-Values? Sollten doch alle vom Typ List sein?

    Die Grundlagen habe ich mir angesehen. Darum fragte ich ja, wie ich z.b. eine Liste als ReturnType übergeben kann.



    Edit:

    Option Strict On

    Quellcode

    1. Fehler 1 "Option Strict On" erfordert, dass alle Funktions-, Eigenschafts- und Operatordeklarationen eine As-Klausel enthalten.
    Damit wieder zurück zur Fragen, wie ich dort eine Liste übergeben kann.
    Machma so:

    VB.NET-Quellcode

    1. Dim csv As New CSV_Import
    2. Me.DataGrid.DataSource = csv.LoadCSV("C:\sys.csv")
    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 denke mal du hast ein Problem mit dem CSV_Import. Wo genau wird der deklariert?
    Instanziere das mit 'New' . Andernfalls musst du wahrscheinlich Public Shared davor schreiben. In C# wäre das 'public static'.
    Wenn du das in Zukunft machst, dann rate ich dir das in eine eigene Klasse zu packen und ein Singelton-Pattern zu implementieren. Option Strict auch immer auf On schalten! Die Fehler sind dann leicht zu beheben.

    Edit:// Man ey, aufm iPad bin ich immer so lahm X(
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    hate_regex schrieb:

    das ganze im ReturnType
    Mach Dir ggf. ein Dataset, wo das alles in je eine Spalte reinpasst oder eine Klasse mit 3 Properties.
    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!
    List ist kein Datentype, List (Of String) ist eins. D.h. du hast 3 unterschiedliche Datentypen in deiner Funktion und das geht nicht als Returnparameter.
    Mach doch 3 Funktionen (GetAttributeList, GetComponentList usw) und rufe in deinen Cases einfach die richtige auf (mit Parameterübergabe von Parser).

    hate_regex schrieb:

    Wie übergebe ich das ganze im ReturnType um Option Strict einzuhalten?
    Das geht nicht.

    Und das ist die wesentliche Lehre, die hier aus Strict On zu ziehen ist.
    Du befüllst 3 ganz verschiedene Listen, mal eine List(Of Attribut), mal eine List(Of Component) und nochwas. Eine Function hat aber nur einen festgelegten Rückgabe-Typ, den kannman nicht wechseln wie die Socken.

    Pest! - zu spät! :cursing:
    Das es mit List() nicht funktioniert leuchtet ein :)

    Ich hatte es als List(of String) versucht, da ich der Meinung war, ich die Deklaration wäre einheitlich (Property Value ist ebenfalls String).

    3 Funktionen wollte ich nicht verwenden, da ich dachte es lässt sich in einer verwurschten.

    @Trade

    Hatte ich gar nicht (korrekt) deklariert. Rod war so freundlich, mich darauf hinzuweisen:

    VB.NET-Quellcode

    1. Dim CSV As New CSV_Import
    2. Me.DataGrid.DataSource = CSV.LoadCSV("C:\sys.csv")


    Mach doch 3 Funktionen (GetAttributeList, GetComponentList usw) und rufe in deinen Cases einfach die richtige auf (mit Parameterübergabe von Parser).
    Dazu müsste ich im Vorfeld wissen, von welchem Typ (Attribut, Komponente,..) die Datei ist. Das weiß ich jedoch erst nachdem ich die Spaltenanzahl kenne (also nach dem Laden. Case of ..)

    Ok, vergiss das. Geschnallt :P

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „hate_regex“ ()

    hate_regex schrieb:

    Dazu müsste ich im Vorfeld wissen, ob von welchem Typ (Attribut, Komponente,..) die Datei ist. Das weiß ich jedoch erst nachdem ich die Spaltenanzahl kenne (also nach dem Laden. Case of ..)

    Wieso denn das? Du weißt doch im Case, welchen Typ du hast und genau da rufst du die jeweilige Funktion auf.

    sonne75 schrieb:

    rufe in deinen Cases einfach die richtige auf


    EDIT: Gut, dann hast du aber immer noch das gleiche Problem, dass du die unterschiedlichen List in de Cases hast. Was willst du mit den Daten denn anstellen?
    Ich habs nun mit 3 Klassen versucht. Problem hierbei: Ich weiss nicht wie ich den Parser übergeben kann.

    @sonne75

    Kurzfassung: Eine CSV in ein Datagrid übertragen. Es gibt 3 mögliche Grid-Modelle: 3, 8 und 15 Spalten, die ich in die Liste Attribut, Komponente oder System parse. Die Daten werden dann via BMC Remedy API verarbeitet (Datenbankprüfungen/abgleich).

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

    hate_regex schrieb:

    Ich habs nun mit 3 Klassen versucht.
    Nö. Lieber so:

    RodFromGermany schrieb:

    eine Klasse mit 3 Properties.
    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!
    Warum muss die Load-Funktion die List zurückgeben? Kannst du die 3 verschiedene Lists einfach als Property in deiner Klasse deklarieren und sie dann befüllen? Dann brauchst du 3 Grids, jeder an die jeweilige List gebunden. Und du blendest einfach den richtigen Grid ein (mit .Visible oder auf verschiedenen TabPages).
    Ich denke, dein Ansatz taugt nix.
    Zielführend wäre ein typDataset mit 3 verschiedenen Tabellen, und je nach csv wird diese oder jene Tabelle befüllt.
    Und ebenso je nach csv wird ein anneres DatagridView angezeigt, und die DGVs werden im Designer designed.
    gugge vier Views-Videos, oder CSV importieren - das ist ja auch bisserl designed, aber in 4Views wird gezeigt, wies gemacht wird.
    Weitere Design-Möglichkeiten bietet Ownerdrawing, aber das ist dann erst die nächste Baustelle.

    Ich nehme auch an, dass in der Datenbank 3 verschiedene Tabellen existieren, also wenn du nicht von einem Problem ins nächste stolpern willst:
    3 csv-Typen - 3 typisierte DataTables - 3 gestylte DGVs - 3 Funktionen zum DB-Abgleich
    @ErfinderDesRades

    Vielen Dank, das sehe ich mir an. Den CSV Import-Post von dir hatte ich gelesen, danach meinte ich meine Funktion aufgebaut zu haben. Ich werd also nochmal genauer hinsehen.

    P.S. In dem Zusammenhang noch eine Frage. Ich prüfe zellenweise den Inhalt. Nicht das gesamte Grid, nur selected Cells. Wenn ich nun bsw. 50 Werte via BMC API prüfe (Cell Value auslesen, an API übergeben, vergleichen, ins Grid zurückschreiben) und die Rückgabewerte zelleweise direkt ins Grid schreibe, ist das ganze extrem langsam (ca. 1-2 Values pro Sekunde). Blende ich das Grid während der Abfrage aus (visible=false) und erst nach der Rückgabe aller Werte wieder ein, schaffe ich Faktor ~10.

    Ist das Grid derart langsam, wenn dort > 10.000 Cells befüllt sind/werden, oder mach ich hier wieder syntaktisch etwas unklug?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „hate_regex“ ()