Klassenmember an eine Sub übergeben und auswerten

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Klassenmember an eine Sub übergeben und auswerten

    Hallo,

    bin von einfachen Variablen auf Klassenprogrammierung gewechselt. Ist es möglich die Members einer Klasse in einer Sub auszuwerten? Beispiel. Habe eine Klasse mit 36 Members. Datensatz.FN01 bis Datensatz.FN36 vom Type String. Die Members FN04 bis FN36 will ich nun auf die gleiche Weise auswerten. Hier bietet sich ja eigentlich eine Unterprogramm (Sub) an.

    1.) Wie kann man die Members an die Sub übergeben?

    Sub Felder_auswerten(Memberfeld as object) funktioniert nicht

    2.) Da meine Members durch nummeriert sind, gibt es vielleicht die Möglichkeit, sie in einer for next schleife in die sub zu schicken?



    Vielen Dank im voraus
    Gruß Markus
    Du solltest die Members in der Klasse als Items einer List(Of T) handhaben. Das ist bei dieser Menge deutlich einfacher zu handeln.
    So ne List kannst du beinah endlos dynamisch erweitern und mit Schleifen (For Each) durchlaufen, Items hinzufügen, entfernen, sortieren usw.
    Mit Sub Felderauswerten(Byref Liste as List(Of Members) kannste dann alles machen.

    Fiel Fergnügen
    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Hört sich sehr vorteilhaft an, aber wie realisiert man das nun?

    VB.NET-Quellcode

    1. Public Class CTest
    2. Dim _Feld As List(Of String)
    3. Property Feld() As List(Of String)
    4. Get
    5. Return _Feld
    6. End Get
    7. Set(ByVal value As List(Of String))
    8. _Feld = value
    9. End Set
    10. End Property
    11. End Class


    VB.NET-Quellcode

    1. Public Test As New CTest
    2. With Test
    3. .Feld(0) = "Hallo"
    4. End With


    hier erhalte ich nun die Fehlermeldung Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
    Gruß Markus
    Hallo und guten Morgen,

    habe das mit new auch schon versucht. Erhalte dann bei

    Test.Feld(0) = "irgendwas" die Fehlermeldung

    Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein. Parametername: index
    Gruß Markus
    Hallo, vielen Dank für eure Hilfe.

    Bekomme das irgendwie nicht auf die Reihe. Vielleicht auch zu sehr vorbelastet durch mein altes GWBASIC. Bei einfachen Variablen kenne ich das ja so:

    Dim Datenfeld(36) as string

    Datenfeld(1) = "irgendwas"

    Datenfeld(2) = "irgendwasmehr"

    Dann kann ich die Datenfelder 1 bis 36 in einer for-next-Schleife problemlos ansprechen.

    for i as integer = 1 to 36 step 1

    Datensatz(i) = "einwert"

    next i

    bekomme das einfach nicht hin.
    Gruß Markus
    Du hast als Property dein gesamtes Feld ausgewiesen. D.h. du kannst darauf nur zugreifen mit

    VB.NET-Quellcode

    1. Public Test As New CTest
    2. Dim TempList as new List(Of String) =Test.Feld
    3. TempList.Add("wasauchimmer")
    4. Test.Feld=TempList
    Das is eher unpraktisch. Besser wäre du würdest Feld als public deklarieren. Dann kannst du mit Test.Feld.Add() oder ... Remove usw. arbeiten.
    Deine Methoden zum Auswerten der Liste setzt du dann auch als Public Sub odr Funktion in die Klasse und kannst sie dann mit Test.SubX() usw. aufrufen.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    Westerwälder schrieb:

    Bekomme das irgendwie nicht auf die Reihe. Vielleicht auch zu sehr vorbelastet durch mein altes GWBASIC. Bei einfachen Variablen kenne ich das ja so:

    So langsam wird die Konfusion bei Dir/uns grösser als kleiner befürchte ich.

    Wenn Du von GWBASIC Arrays gewohnt warst, so kannst Du sie auch hier ohne Probleme verwenden. Auch in .NET gibt es

    VB.NET-Quellcode

    1. Dim Datenfeld(36) as String
    2. ....
    3. Datenfeld(0)="Feld 0"
    4. Datenfeld(1)="Feld 1"
    5. ...
    6. Datenfeld(35)="Feld 36"

    wobei zu beachten ist, dass in .NET die Indices bei 0 anfangen, d.h. im obigen Beispiel gibt es Datenfeld(36) nicht !

    Allerdings haben sogenannte typsichere Listen List (of T) die Arrays zum grossen Teil abgelöst, weil sie komfortabler zu handhaben sind. Sie sind unbegrenzt, müssen also nicht wie oben mit einer festen Grenze definiert werden, und bieten wie Vatter schon erwähnt hat zusätzliche Methoden wie Sortieren, Konvertieren, Löschen, etc .

    Zurück zum Array: Dein Problem scheint zu sein, dieses in Deiner Klasse richtig zu füllen, schliesslich geht das schlecht bei der Definition. Dazu benutzt Du den Constructor New der Klasse.

    Machen wir ein Beispiel:

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    4. ' neue Instanz anlegen
    5. Dim datensatz1 As Datensatz = New Datensatz
    6. ' mit schleife durchlaufen, Index fängt bei 0 an !
    7. For i As Integer = 0 To 2
    8. MessageBox.Show(datensatz1.Felder.Item(i))
    9. Next
    10. End Sub
    11. End Class
    12. Public Class Datensatz
    13. Public Felder As New List(Of String) ' meine Liste der verwendeten strings
    14. ' Constructor New der Klasse, wird immer als erstes bei einer neuen Instanz aufgerufen
    15. Public Sub New()
    16. Felder.Add("Feld 0")
    17. Felder.Add("Feld 1")
    18. Felder.Add("Feld 2")
    19. End Sub
    20. End Class

    Noch eine Bemerkung zu Deiner Klasse: Du hast jetzt eine Property für Deinen "Array" genommen, weil Vatter es so vorgeschlagen hatte, benutzt es aber genauso wie eine Membervariable. Properties sind (meistens) nbur dann sinvoll wenn Du beim Lesen /Setzen einer Variable noch Prüfungen vornehmen willst, ansonsten kannst Du auch gleich bei einer normalen Variable bleiben.
    Hallo und nochmals Dank.

    Weiss, dass ist nicht immer ganz einfach mit mir (sagt meine Frau auch schonmal).

    War fast schon so weit die Klassenprogrammierung wieder aufzugeben und zu den normalen Variablen zurück zukehren. Doch habe erkannt, dass die Klassenprogrammierung sehr viele Vorteile bietet und es zu keinen ungewollten Datenüberschreibungen kommen kann. Habe nun den letzten Vorschlag übernommen und es funktioniert nach meinen Vorstellungen. Finde es wirklich gut, dass man in diesem Forum auch wirklich umfangreiche Unterstützung bekommt.

    Gruss Markus
    Gruß Markus
    Zwecks leichter Erkennbarkeit/Verwendbarkeit der Felder würde ich noch eine Enumeration einbauen.
    Beispiel:

    VB.NET-Quellcode

    1. Public Class Datensatz
    2. Public Enum FeldName As Integer
    3. Nachname = 0
    4. Vorname = 1
    5. Strasse = 2
    6. Hausnummer = 3
    7. PLZ = 4
    8. Ort = 5
    9. End Enum
    10. Private _MaxLength As Integer = 5
    11. Private _Felder(_MaxLength) As String
    12. Public Sub New()
    13. End Sub
    14. Public ReadOnly Property Felder() As String()
    15. Get
    16. Return _Felder
    17. End Get
    18. End Property
    19. Public ReadOnly Property MaxLength() As Integer
    20. Get
    21. Return _MaxLength
    22. End Get
    23. End Property
    24. Public Function GetValue(ByVal feld As FeldName) As String
    25. Return _Felder(feld)
    26. End Function
    27. Public Sub SetValue(ByVal feld As FeldName, ByVal Value As String)
    28. _Felder(feld) = Value
    29. End Sub
    30. Public Sub ResetValues()
    31. For index As Integer = 0 To Me.MaxLength
    32. _Felder(index) = String.Empty
    33. Next
    34. End Sub
    35. Public Overrides Function ToString() As String
    36. Return String.Join(";", _Felder)
    37. End Function
    38. Public Property Nachname() As String
    39. Get
    40. Return Me.GetValue(FeldName.Nachname)
    41. End Get
    42. Set(ByVal value As String)
    43. Me.SetValue(FeldName.Nachname, value)
    44. End Set
    45. End Property
    46. Public Property Vorname() As String
    47. Get
    48. Return Me.GetValue(FeldName.Vorname)
    49. End Get
    50. Set(ByVal value As String)
    51. Me.SetValue(FeldName.Vorname, value)
    52. End Set
    53. End Property
    54. ' weitere Properties
    55. End Class

    Anwendung

    VB.NET-Quellcode

    1. Dim myDatensatz As New Datensatz
    2. myDatensatz.Nachname = "Mustermann"
    3. ' oder
    4. myDatensatz.SetValue(Datensatz.FeldName.Nachname, "Mustermann")
    5. Dim vorname As String = myDatensatz.Vorname
    6. ' oder
    7. vorname = myDatensatz.GetValue(Datensatz.FeldName.Vorname)
    8. ' Ausgabe aller Felder, getrennt durch Semicolon
    9. Debug.WriteLine(myDatensatz.ToString)
    Danke für die weitere Anregung.

    Programmiere momentan eine Programmvorlage. Die 36 Datenfelder spiegeln die Tabelle einer Accsess-Datenbank wieder. Mit 36 Datenfelder habe ich - nach meinen Erfahrungen genügend Datenfelder (incl. Reserve) - zur Verfügung. Es macht hier also keinen Sinn die Felder zu spezifizieren, da sie in unterschiedlichen Projekte, unterschiedliche Dateninhalten und Maximallängen haben werden. Es ging mir darum, die Felder über eine Schleife ansprechen zu können.
    Gruß Markus