Listen-Klasse mit Datenbefüllen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Mabbi.

    Listen-Klasse mit Datenbefüllen

    Hi,

    ich habe eine Klasse erstellt ( nach dieser Vorlage: https://docs.microsoft.com/de-de/dotnet/visual-basic/programming-guide/concepts/linq/how-to-create-a-list-of-items )

    VB.NET-Quellcode

    1. Public Class WW_Liste
    2. Public Property Hersteller As String
    3. Public Property Typ As String
    4. Public Property Model As String
    5. Public Property Jahr As String
    6. Public Property Wert1 As String
    7. Public Property Wert2 As String
    8. Public Property Wert3 As String
    9. Public Property Wert4 As String
    10. Public Property Wert5 As String
    11. Public Property Wert6 As String
    12. Public Property Wert7 As String
    13. Public Sub New(ByVal sHersteller As String, ByVal sTyp As String, ByVal sModel As String, ByVal sJahr As String, _
    14. ByVal sWert1 As String, ByVal sWert2 As String, ByVal sWert3 As String, ByVal sWert4 As String, ByVal sWert5 As String, _
    15. ByVal sWert6 As String, ByVal sWert7 As String)
    16. Hersteller = sHersteller
    17. Typ = sTyp
    18. Model = sModel
    19. Jahr = sJahr
    20. Wert1 = sWert1
    21. Wert2 = sWert2
    22. Wert3 = sWert3
    23. Wert4 = sWert4
    24. Wert5 = sWert5
    25. Wert6 = sWert6
    26. Wert7 = sWert7
    27. End Sub
    28. End Class


    rufe diese dann hier auf: (Dim WW_Liste = Get_WW_Liste())

    VB.NET-Quellcode

    1. Function Get_WW_Liste() As IEnumerable(Of WW_Liste)
    2. Return New List(Of WW_Liste) From
    3. {
    4. New WW_Liste("Adria", "Scandic", "740 HP", "87/88", "1", "2", "3", "4", "5", "6", "7"),
    5. New WW_Liste("Adria", "Scandic2", "741 HP", "87/88", "1", "2", "3", "4", "5", "6", "7")
    6. }
    7. End Function


    Soweit funktioniert das auch, ich kann wie folgt auf die Daten zugreifen:

    VB.NET-Quellcode

    1. 'Display WW_List(Hersteller)
    2. For i As Integer = 0 To WW_Liste.Count - 1
    3. MsgBox("Hersteller: " & WW_Liste.AsEnumerable(i).Hersteller)
    4. Next


    Nun möchte ich aber hier

    "New WW_Liste("Adria", "Scandic", "740 HP", "87/88", "1", "2", "3", "4", "5", "6", "7")"

    aus einem mehrdimensionalem

    Dim AlleZeilenSplit As New List(Of String())

    Also "AlleZeilen" kann ich per .count-1 durchlaufen und habe in jeder "Zeile" genau 11 Werte als Strings drin stehen (eingelesen aus einer .csv Datei.)

    Wie kann ich die "New WW_Liste ..." mit einer For-Next Schleife ersetzen in dem Code oben ? Ich komme da aktuell einfach nicht weiter.

    Vielen Dank im voraus für Eure hilfe.
    @Mabbi Für jede Art, wie Du eine Instanz Deiner Datenklasser erzeugen willst, kannst Du einen separaten Konstruktor schreiben.
    Du kannst da auch einen Konstruktor schreiben, dem Du eine Zeile der CSV-Datei übergibst und diese dann dort splittest.
    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!
    Du kannst auch die ganzen Konstruktoren weglassen, und in etwa sowas fabrizieren:

    VB.NET-Quellcode


    Achnee - erstmal bennene deine Klasse um.
    WW_Liste ist genau der Name, den die Klasse nicht haben darf, weil es ist keine Liste.
    Objekte dieser Klasse sind ja nur Elemente, welche dann einer wirklichen Liste zugefügt werden.
    Und du bist bereits mitten drin, das durcheinanderzubringen.
    Also ändere den Namen der klasse - gib ihr den richtigen Namen, der ausdrückt, was es sein soll.
    Meinetwegen DingensMitSiebenWerten - tut mir leid, einen sinnvolleren Namen kann ich nicht vorschlagen, der Inhalt der Klasse gibt nicht mehr her.

    Dann erklär ich, wie du die Konstruktoren auch weglassen kannst.

    (Ach guck - FFF - bin ein bisserl zu spät, dafür aber ausführlicher)
    Ok, das habe ich nun verstanden.
    Ich habe mich bei Liste an der Bennenung von Microsoft (list of items) orientiert und fehlleiten lassen. WW steht in diesem fall für Wohnwagen, ich bin ein bissel tippfaul :) wenn ich probiere Teile meines Programms zu refakturieren oder durch bessere Lösungen zu ersetzen.

    Aktuell war der Ansatz so:
    Ich lade eine .csv Datei mit UTF7 Codierung, splitte die in einezelne Zeilen (vbCrLf) und generiere dann per 2. Split (;) die EInzelwerte, und kloppe die ganzen Daten mit Schwung in eine List of Strings() rein. (DImensionen: viele Zeilen mit jeweils 7 EinzelwertenWerten, also verschachtelt.
    Auf die greife ich dann in etwa so zu: (bin leider gerade nicht an meinem Arbeitsrechner...sorry wenn es nicht ganz richtig geschrieben ist)

    Wert = WW_Werte(index).atindex(index2)

    Fand ich super, bis ich festgestellt habe wie komplizoert es ist, Werte in so einem Listen-Konglomerat zu verändern...war also defacto ein sinnloser Ansatz.
    Dann habe ich bei meiner Recherche die Idee mit der Klasse gefunden, mir das auf MS (link oben) durchgelesen und probiert umzusetzen...und bin erstmal gestrandet.

    Danke schonmal für Eure HIlfe vorab. los gehts:

    Ich bennen WW_Liste nach WW_Werte um.
    Wie geht es dann weiter ?

    Mabbi schrieb:

    WW_Werte
    ? Das ist eine Besserung in der Benennung, aber immer noch ganz weit vom Optimum entfernt. Warum nicht einfach Wohnwagen? Und Wert1-Wert7? Dann kannste gleich a, b, c nehmen. Ist kürzer und genauso nichtssagend. Was sagt denn Wert5 über den Wohnwagen aus? MotorleistungInPS? AnzahlDerBetten? TankvolumenInLiter? So sollte die Variable benannt werden.
    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.

    Mabbi schrieb:

    ich bin ein bissel tippfau
    Ich auch, aber da haste definitiv an der falschen Stelle gespart - die 8 buchstaben sollte man aufwenden.
    Also ich nenne deine Klasse jetzt mal Wohnwagen, dann weiss man gleich: "Aha - das bedeutet: 'Wohnwagen' (und ich dachte schon 'WirtschaftsWissenschaft' oder 'WeltWirtschaft' oder 'WirtschaftsWut' - könnte ja sein)"

    VB.NET-Quellcode

    1. Public Class Wohnwagen
    2. Public Property Hersteller As String
    3. Public Property Typ As String
    4. Public Property Model As String
    5. Public Property Jahr As String
    6. Public Property Wert1 As String
    7. Public Property Wert2 As String
    8. Public Property Wert3 As String
    9. Public Property Wert4 As String
    10. Public Property Wert5 As String
    11. Public Property Wert6 As String
    12. Public Property Wert7 As String
    13. End Class
    Boah ey!
    Ja, und nun wie versprochen, wie man ohne einen oder mehrere Konstruktoren (alias Sub New) da Wohnwagen einer Liste hinzufügt.
    (Ich mache das in einer For i - Schleife, und bastel das i überall ein):

    VB.NET-Quellcode

    1. 'in Form1
    2. Private _Wohnwagens As New List(Of Wohnwagen)
    3. Private Sub LadeWohnwagens()
    4. For i = 0 To 5
    5. Dim ww = New Wohnwagen With {.Hersteller = "Hersteller" & i, .Jahr = "Jahr" & i, .Model = "Model" & i,
    6. .Typ = "Typ" & i, .Wert1 = "Wert1" & i, .Wert2 = "Wert2" & i, .Wert3 = "Wert3" & i, .Wert4 = "Wert4" & i,
    7. .Wert5 = "Wert5" & i, .Wert6 = "Wert6" & i, .Wert7 = "Wert7" & i}
    8. _Wohnwagens.Add(ww)
    9. Next
    10. End Sub
    Wie du siehst, in Zeile #3 - daaa!! ist die Liste, und diese Liste muss Liste heissen. Weil das ist eine Liste. Alles andere hier im Code gezeigte ist keine Liste, und heisst deswegen auh nicht so.
    Die Liste hab ich aber nicht Liste genannt, sondern - bin ja tippfaul - verwende ich einfach den Plural von Wohnwagen.
    Das ist ja im Denglischen, wie jedermann weiss: Wohnwagens (ok, ich hab noch den Prefix _ davor, dass man weiss, es ist eine Klassenvariable).

    Also Benamungs-Vorschlag: Wenn es mehrere sind, nimm den Plural. Es ist ja eine Sprache, wenn auch nur eine Programmiersprache.
    Und Sprachen nehmen, wenn von mehreren gesprochen wird, den Plural.
    Dabei ists egal, ob die mehreren eine List(Of T) sind oder ein Array oder noch was schlimmeres. Plural nehmen, wenn es mehrere sind, und Plural nicht!!! nehmen, wenn es nicht mehrere sind.

    Übrigens zeigt das Beisplie gleich noch ein Benamungs-Prinzip: Lokale Variablen werden nämlich kurz gehalten - extrem kurz sogar: ww.
    Das kann man machen, weil es eben lokale Variablen sind, wenn deren Gültigkeit sich über nur wenige Zeilen erstreckt, und wo aus dem Kontext klar ersichtlich ist, um was es sich handelt.



    Ich bin jetzt übrigens mal deinem Link gefolgt - da die Klasse heisst ja auch Student, und nicht StudentList. Und diese komische Methode GetStudents() - naja bei mir heisst es eben LadeWohnwagens() und tut nix getten, sondern lädt etwas (kannst ja mal überlegen, was der Unterschied ist).

    Wie dem auch sei - noch viel mehr Wortklauberei kannst du hier finden: Grundlagen: Fachbegriffe

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

    @'ErfinderDesRades: Das hat mir sehr weitergeholfen, vielen Dank.

    Hier mein aktueller Modul-Code:

    VB.NET-Quellcode

    1. Public _Wohnwagen As New List(Of Wohnwagen)
    2. Public Sub WW_DB_generieren()
    3. Dim ex As Microsoft.VisualBasic.FileIO.MalformedLineException
    4. Dim AlleZeilen As New List(Of String())
    5. 'alle Dateien des Ordners
    6. Dim oDir As New System.IO.DirectoryInfo(DateiPfadWW_DB)
    7. Dim oFiles As System.IO.FileInfo() = oDir.GetFiles()
    8. Dim File As System.IO.FileInfo
    9. 'alle WW.csv laden
    10. For Each File In oFiles
    11. Dim Einzeltabelle = New List(Of String())
    12. '.csv abrufen
    13. If System.IO.File.Exists(File.FullName) Then
    14. If FileInUse(File.FullName) = False Then
    15. Try
    16. For Each line In IO.File.ReadLines(File.FullName, System.Text.Encoding.UTF7)
    17. Dim parts() = line.Split(";"c)
    18. AlleZeilen.Add(parts)
    19. Next
    20. Catch ex
    21. MsgBox(File.FullName & " laden Fehler:" & ex.Message)
    22. Exit Sub
    23. End Try
    24. Else
    25. MsgBox(File.FullName & " laden Fehler: INUSE!")
    26. Exit Sub
    27. End If
    28. End If
    29. Next File
    30. Call LadeWohnwagenDaten(AlleZeilen)
    31. 'Aufräumen
    32. oDir = Nothing
    33. oFiles = Nothing
    34. File = Nothing
    35. AlleZeilen.Clear()
    36. AlleZeilen = Nothing
    37. End Sub
    38. Private Sub LadeWohnwagenDaten(ByVal AlleZeilen As List(Of String()))
    39. 'Gesamtliste aus diversen .csv Dateinen (zerlegt nach Zeilen und Zellen) zeilenweise durcharbeiten
    40. For i As Integer = 0 To AlleZeilen.Count - 1
    41. 'Eintrag in _Wohnwagen generieren
    42. 'HIER müssen noch die korrekten Bezeichner rein
    43. Dim ww = New Wohnwagen With {.Hersteller = AlleZeilen(i).ElementAt(0),
    44. .Jahr = AlleZeilen(i).ElementAt(1),
    45. .Model = AlleZeilen(i).ElementAt(2),
    46. .Typ = AlleZeilen(i).ElementAt(3),
    47. .Wert1 = AlleZeilen(i).ElementAt(4),
    48. .Wert2 = AlleZeilen(i).ElementAt(5),
    49. .Wert3 = AlleZeilen(i).ElementAt(6),
    50. .Wert4 = AlleZeilen(i).ElementAt(7),
    51. .Wert5 = AlleZeilen(i).ElementAt(8),
    52. .Wert6 = AlleZeilen(i).ElementAt(9),
    53. .Wert7 = AlleZeilen(i).ElementAt(10)}
    54. _Wohnwagen.Add(ww)
    55. Next
    56. End Sub
    57. Public Class Wohnwagen
    58. 'HIER müssen noch die korrekten Bezeichner rein
    59. Public Property Hersteller As String
    60. Public Property Typ As String
    61. Public Property Model As String
    62. Public Property Jahr As String
    63. Public Property Wert1 As String
    64. Public Property Wert2 As String
    65. Public Property Wert3 As String
    66. Public Property Wert4 As String
    67. Public Property Wert5 As String
    68. Public Property Wert6 As String
    69. Public Property Wert7 As String
    70. End Class


    Der Code ist echt schnell und macht nun genau das, was ich von Ihm erwarte. Vielen Dank für die Hilfe.
    :thumbsup: ...wieder etwas dazu gelernt

    P.S.: Gibt es in meinem Code eigentlich noch verbesserungswürdige Stellen ?
    ( ... ich mag "Wohnwagens" nicht obwohl mir der Unterschied singular und plural in der Bezeichnung schon klar ist und auch notwendig, arbeite noch an der richtigen Bezeichnung ...)
    Ich weiß, dass ich die _Wohnwagen.Add(ww) schon in der .csv Ladeprozedur reinpacken könnte, aber ich will die geladenen Daten noch bearbeiten bevor ich die hinzufüge.

    Dieser Beitrag wurde bereits 14 mal editiert, zuletzt von „Mabbi“ ()

    Ja.
    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden. Das betrifft zum Beispiel die VB6-MsgBox.
    Über Wert1 bis Wert7 habe ich mich schon geäußert.
    Dass alle Propertys sinnvollerweise vom Typ String sind, halte ich für unwahrscheinlich. Das Jahr wär für mich ein Integer. Es sei denn, da stünde neunzehnhundertachtundneunzig drin. Dass Du andere Typen aus einem String parsen/konvertieren müsstest, ist klar. Aber eine Sortierung mit String wird bei manchen Angaben nicht zum gewünschten Ziel führen. Da kommt dann z.B. die Reihenfolge "10", "121", "34", "99" raus.
    Sind das eigentlich Wohnwagen oder Wohnmobile?
    Call wird fast nicht mehr gebraucht, in Deinem Fall brauchst Du es nicht.
    Den Aufräumen-Teil brauchst Du nicht, darum kümmert sich der GarbageCollector.
    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:
    Alles Wohnwagen, insgesamt fast 20k, Listen des kompletten deutschen Marktes aller auf diversen Messen ausgestellten Wohnwagen die von unseren Technikern vermessen worden sind seit ca. 1955. Alte Daten aus Karteikarten wurden irgendwann in den 80 oder 90ern manuell digitalisiert.
    Hier sind pro Fahrzeug neben Hersteller, Baujahr, Model, und Typ noch diverse Messstrecken und Abwicklungs-Maße hinterlegt.

    Bei Wohnwagen wurde früher eigentlich nur das sogenannte Umlaufmaß hinterlegt, faktisch die Abwicklung des eingzogenen Zeltes als Längenmaß.
    Heute werden zusätzlich diverse Teilabwicklungen im Front und Heckbereich des Wohnwagens, Bugform, Form des Radkastens und viele andere Teilmaße erfasst.

    Dementsprechend sind die Tabllen sehr chaotisch und nicht konsistent, vieles muss einfach gelöscht oder nachbearbeitet werden.

    Ein Umlaufmaß kann aus einer 3-4 stelligen Zahl, 2 Zahlen mit den Präfix L und R oder 3-4 Werten mit anderem Präfix wenn noch Abwicklungen als Teilstrecken hinterlegt sind, das alles natürlich immer schön in einer Zelle der .csv Datei.

    Baujahr existiert in mindestens 3 Varianten. 70, 1970 oder (Modelljahr) 70/71

    Hersteller LMC (Lord Münsterland Caravans) habe ich bis dato 6 Schreibweisen gefunden.

    Ich verarbeite die Daten schon seit 4 Jahren digital in vba weiter, habe also schon einen langwierig erstellten Import Datenfilter.
    Den programmiere ich neu/nach und setz den dann als Funktion beim Auslesen von AlleZeilen --> .add dazwischen.

    Deswegen lade ich die Daten als String und bearbeite Teile der Daten nach, um konsistente Daten zur Weiterverarbeitung aus den alten .csv Tabellen zu generieren.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Mabbi“ ()

    Hier Überarbeitung:

    VB.NET-Quellcode

    1. Public _Wohnwagen As New List(Of Wohnwagen)
    2. Public Sub WW_DB_generieren() ' Falscher Name - es wird nichts generiert: es werden Dateien eingelesen
    3. Dim AlleZeilen As New List(Of String())
    4. 'alle Dateien des Ordners
    5. Dim oDir As New System.IO.DirectoryInfo(DateiPfadWW_DB)
    6. Dim oFiles As System.IO.FileInfo() = oDir.GetFiles()
    7. Dim File As System.IO.FileInfo
    8. 'alle WW.csv einlesen
    9. For Each File In oFiles 'File ist schlechter Name, weil es gibt einen gleichnamigen, wichtigen! Namespace
    10. Dim Einzeltabelle = New List(Of String())
    11. '.csv abrufen
    12. If System.IO.File.Exists(File.FullName) Then
    13. If FileInUse(File.FullName) = False Then
    14. Try
    15. For Each line In IO.File.ReadLines(File.FullName, System.Text.Encoding.UTF7)
    16. Dim parts() = line.Split(";"c)
    17. AlleZeilen.Add(parts)
    18. Next
    19. Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException ' so geht das mit Exceptions
    20. MsgBox(File.FullName & " laden Fehler:" & ex.Message)
    21. Exit Sub
    22. End Try
    23. Else
    24. MsgBox(File.FullName & " laden Fehler: INUSE!")
    25. Exit Sub
    26. End If
    27. End If
    28. Next File
    29. LadeWohnwagenDaten(AlleZeilen)
    30. End Sub
    31. Private Sub LadeWohnwagenDaten(ByVal AlleZeilen As List(Of String()))
    32. 'Gesamtliste aus diversen .csv Dateinen (zerlegt nach Zeilen und Zellen) zeilenweise durcharbeiten
    33. For i As Integer = 0 To AlleZeilen.Count - 1
    34. 'Eintrag in _Wohnwagen generieren
    35. 'HIER müssen noch die korrekten Bezeichner rein
    36. Dim ww = New Wohnwagen With {.Hersteller = AlleZeilen(i)(0),
    37. .Jahr = AlleZeilen(i)(1),
    38. .Model = AlleZeilen(i)(2),
    39. .Typ = AlleZeilen(i)(3),
    40. .Wert1 = AlleZeilen(i)(4),
    41. .Wert2 = AlleZeilen(i)(5),
    42. .Wert3 = AlleZeilen(i)(6),
    43. .Wert4 = AlleZeilen(i)(7),
    44. .Wert5 = AlleZeilen(i)(8),
    45. .Wert6 = AlleZeilen(i)(9),
    46. .Wert7 = AlleZeilen(i)(10)}
    47. _Wohnwagen.Add(ww)
    48. Next
    49. End Sub
    50. Public Class Wohnwagen
    51. 'HIER müssen noch die korrekten Bezeichner rein
    52. Public Property Hersteller As String
    53. Public Property Typ As String
    54. Public Property Model As String
    55. Public Property Jahr As String
    56. Public Property Wert1 As String
    57. Public Property Wert2 As String
    58. Public Property Wert3 As String
    59. Public Property Wert4 As String
    60. Public Property Wert5 As String
    61. Public Property Wert6 As String
    62. Public Property Wert7 As String
    63. End Class
    64. End Class
    wichtig das mit der Exception, und dass man .ElementAt() bei Arrays nicht braucht.
    Visual Studio - Empfohlene Einstellungen
    unbenommen, und auch die anderen VaporiZed-Überlegungen zu den korrekten Datentypen deiner Wohnwagen-Klasse-Properties.
    Alles String ist NoGo. Datentypen sind verschieden, und deren Verschiedenheit hat Gründe, Sinn und Zweck.
    Man fährt vor Wand, wenn man dieses Sprach-Feature ignoriert, statt es zu nutzen.