Variablen eines Moduls / Klasse iterieren

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

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

    Variablen eines Moduls / Klasse iterieren

    Moin,

    ich habe Variablen die eine Hardwareanbindung haben und deswegen Global sind und ich muss diese zu beginn meines Programms einem initalisieren (haben eine eigene Klasse als Datentyp).
    Diese Variablen stehen jetzt einfach in einem Modul und ich mochte diese gerne beim Programmstart in einer Schleife durchlaufen. Alle Varis in ein Array oder List schreiben funktioniert nicht, weil der Kompilier ja nur Kopien erstellen.

    Hat jemand einen Tipp für mich, wie ich die Elemente in einer Schleife durchlaufen kann? Wäre echt eine große Hilfe und habe gerade keine Idee mehr =/
    Ich kann momentan nicht erfassen, was der Text inhaltlich bedeutet. Kannst Du das mal irgendwie anders erklären? Wie können Variablen eine Hardwareanbindung haben? Warum sind sie in einem Modul und warum willst Du sie in einer Schleife durchlaufen lassen? Mit welchem Zweck? Und was hat es mit den vermuteten Kopien auf sich? Wie ist denn der Programmablau an sich. Erklär dies mal bitte an einer konkreten Variable.
    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.
    Moin,

    Das sind Variablen die über ihre Klasse auf eine SPS zugreifen und die sie auslesen oder schreiben. Die habe ich jetzt einfach in einem Modul untereinander weggeschrieben:

    VB.NET-Quellcode

    1. Module MVariablenDefinitionen
    2. 'Variablen....
    3. Public WithEvents Brk_referenziert As MeldVariable
    4. Public WithEvents Brk_faehrt_vor As MeldVariable
    5. Public WithEvents Brk_faehrt_zurueck As MeldVariable
    6. Public WithEvents Brk_Position As MeldVariable
    7. Public WithEvents Brk_Geschwindigkeit As MeldVariable
    8. Public WithEvents Brk_Ziel_erreicht As MeldVariable
    9. Public WithEvents Brk_Steinindex_Handauswahl As MeldVariable
    10. Public WithEvents FW_Geschwindigkeit As MeldVariable
    11. Public WithEvents FW_Position As MeldVariable
    12. Public WithEvents FW_referenziert As MeldVariable
    13. Public WithEvents FW_ueberBrett1 As MeldVariable
    14. Public WithEvents FW_ueberBrett2 As MeldVariable
    15. '.....
    16. End Module


    Den Typ der Variablen muss ich zu Programmstart initalisieren, weil die Klasse information zum Typ, Steuerung usw braucht, das hole ich mir alles aus einer Datenbank und sowieso sind die Variablen ja sonst nothing.

    Ich möchte aber nicht jede einzelne Variable vom Modul einzeln initialisieren, sondern würde gerne eine schleife dafür nutzen, in der ich die Variablen aus dem Modul durchlaufe. Ich habe dafür aber keine Möglichkeit gefunden.

    Ich möchte also:

    VB.NET-Quellcode

    1. For each Vari in MVariablenDefinitionen
    2. 'initialisieren ...
    3. Next

    VaporiZed schrieb:

    Erklär dies mal bitte an einer konkreten Variable.
    Naja, das ist wohl erstmal gescheitert …

    VB.NET-Quellcode

    1. For Each Vari In {MVariablenDefinitionen.Brk_referenziert, MVariablenDefinitionen.Brk_faehrt_vor, MVariablenDefinitionen.Brk_faehrt_zurueck, …}


    Was heißt denn konkret initialisieren?

    Nur: Das Datenmodell kommt mir komisch vor. Daher nochmal: Wie ist der Komplettverwendungsablauf einer Variable?
    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.
    Okay dann versuch mal den Ablauf zu erklären:

    Ich habe eine Variable in besagten Modul angelegt (z.b. : Brk_referenziert ) :


    VB.NET-Quellcode

    1. Module MVariablenDefinitionen
    2. 'Variablen....
    3. Public WithEvents Brk_referenziert As MeldVariable
    4. '.....
    5. End Module


    Dann ruf mein Startfenster die Initialisierung auf:

    VB.NET-Quellcode

    1. Brk_referenziert = new MeldVariable(...)


    und das ruft halt den Konstruktor auf ...

    VB.NET-Quellcode

    1. Sub New(Variablennamen As String, Groupname As String, ByRef ProzessDataset As ProzessDaten)
    2. If ProzessDataset Is Nothing Then Return
    3. Me._MeldunggruppeBindingSource.DataMember = "Meldunggruppe"
    4. Me._MeldunggruppeBindingSource.DataSource = ProzessDataset
    5. Me._MeldungBindingSource.DataMember = "FK_Meldunggruppe_Meldung"
    6. Me._MeldungBindingSource.DataSource = Me._MeldunggruppeBindingSource
    7. Me._OldValue = Nothing
    8. Me.value = Nothing
    9. Me._Singlevalue = Nothing
    10. For Each Meldgroup As DataRowView In Me._MeldunggruppeBindingSource
    11. If Regex.IsMatch(CType(CType(_MeldunggruppeBindingSource.Current, DataRowView).Row, ProzessDaten.MeldunggruppeRow).Name, Groupname, RegexOptions.IgnoreCase) Then
    12. For Each Meldung As DataRowView In Me._MeldungBindingSource
    13. If CType(Meldung.Row, ProzessDaten.MeldungRow).Name = Variablennamen Then
    14. With CType(Meldung.Row, ProzessDaten.MeldungRow)
    15. _Meldestrukt.Adresse = .Adresse
    16. _Meldestrukt.BausteinNr = CType(CType(_MeldunggruppeBindingSource.Current, DataRowView).Row, ProzessDaten.MeldunggruppeRow).DatenbausteinNr
    17. _Meldestrukt.Bitnummer = .Bitnummer
    18. _Meldestrukt.Datentyp = .Datentyp
    19. _Meldestrukt.Variable = Me
    20. _Meldestrukt.ID = .ID
    21. _ID = .ID
    22. End With
    23. Return
    24. End If
    25. Next
    26. End If
    27. _MeldunggruppeBindingSource.Position += 1
    28. Next
    29. End Sub


    Und jetzt kann ich über propertys den Status des Bits in der SPS auslesen, z.b.:

    VB.NET-Quellcode

    1. If Brk_referenziert.state then
    2. '...
    3. end if


    Oder wenn das bit sich ändert werden Events gefeuert die ich verarbeiteten kann:

    VB.NET-Quellcode

    1. Private Sub BruckeReferenziert(ByVal sender As Object, ByVal e As MeldVariableIntegerEventArgs) handles Brk_referenziert.change
    2. if e.state then
    3. '...
    4. end if
    5. End Sub


    Und diese Variablen muss ich halt in Unterschiedlichen Formularen nutzen und viele Anzeigen sind direkt auf dem Hauptfenster. Deswegen möchte ich für jede variable vorher einmal den Konstruktor aufrufen.

    Wird mein vorgehen ein wenig klarer?
    @Rizzle Wenn Deine Variablen Klassen sind, gib ihnen eine gemeinsame Basisklasse oder ein Interface, darüber kannst Du dann alle erreichen.
    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!
    Nicht bei diesem Konstruktor, da jede Variable ihre eigenen Parameter zu haben scheint. Oder wie kommt eine Variable zu ihren Konstruktor-Parametern? Sind die im Code festgelegt oder stehen die irgendwo anders fix? Oder sind die gar variabel?

    btw: das DataSet musst Du nicht ByRef übergeben, weil Du keins in jener Methode erzeugst.
    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.
    Ja richtig jede Variable hat eigene Parameter, sonst würde ich keine Datenbank brauchen. Es sind quasi "die Schwestervariablen" derjenigen die in der Steuerung laufen.

    Jetzt melde ich halt zu beginn die Varialben ungefähr so an:

    VB.NET-Quellcode

    1. Private Sub MakeAllgemeinVariablenSPS()
    2. m_SendRecieve.MakeMeldeVariable(Allg_Automatik, NameOf(Allg_Automatik), MeldGroupsNames(MeldungenGroups.Allgemein))
    3. m_SendRecieve.MakeMeldeVariable(Allg_Handbetrieb, NameOf(Allg_Handbetrieb), MeldGroupsNames(MeldungenGroups.Allgemein))
    4. m_SendRecieve.MakeMeldeVariable(Allg_Einrichtbetrieb, NameOf(Allg_Einrichtbetrieb), MeldGroupsNames(MeldungenGroups.Allgemein))
    5. m_SendRecieve.MakeMeldeVariable(Allg_Referenzierung_aktiv, NameOf(Allg_Referenzierung_aktiv), MeldGroupsNames(MeldungenGroups.Allgemein))
    6. '...
    7. m_SendRecieve.MakeMeldeVariable(Allg_GutBrett_leer, NameOf(Allg_GutBrett_leer), MeldGroupsNames(MeldungenGroups.Allgemein))
    8. m_SendRecieve.MakeMeldeVariable(Allg_GutBrett_voll, NameOf(Allg_GutBrett_voll), MeldGroupsNames(MeldungenGroups.Allgemein))
    9. m_SendRecieve.MakeMeldeVariable(Allg_Schlechtbrett_leer, NameOf(Allg_Schlechtbrett_leer), MeldGroupsNames(MeldungenGroups.Allgemein))
    10. m_SendRecieve.MakeMeldeVariable(Allg_SchlechtBrett_voll, NameOf(Allg_SchlechtBrett_voll), MeldGroupsNames(MeldungenGroups.Allgemein))
    11. m_SendRecieve.MakeMeldeVariable(Allg_Mld_AutofillIsOn, NameOf(Allg_Mld_AutofillIsOn), MeldGroupsNames(MeldungenGroups.Allgemein))
    12. m_SendRecieve.MakeMeldeVariable(Allg_WartungStehtAn, NameOf(Allg_WartungStehtAn), MeldGroupsNames(MeldungenGroups.Allgemein))
    13. End Sub



    Das gefällt mir so aber nicht =/
    8| Das bedeutet, dass jede Variable genauso heißen muss wie im DataSet hinterlegt?
    Ist die Anzahl der WithEvents-Variablen auf absehbare Zeit fest oder ändert sich da ggf. alle paar Wochen was?
    Passiert bei jedem Change-EventHandler was anderes oder ist das für viele bis alle Variablen gleich?
    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 schrieb:

    8| Das bedeutet, dass jede Variable genauso heißen muss wie im DataSet hinterlegt?


    Genau der Name ist der Key, ist am einfachsten.

    VaporiZed schrieb:

    8|
    Ist die Anzahl der WithEvents-Variablen auf absehbare Zeit fest oder ändert sich da ggf. alle paar Wochen was?


    Ja das Gerät wird funktioniel die ganze Zeit erweitert, darum hätte ich ja gerne eine andere Lösung. Als das Projekt noch klein war, hat mich das nicht gestört.

    VaporiZed schrieb:

    8|
    Passiert bei jedem Change-EventHandler was anderes oder ist das für viele bis alle Variablen gleich?


    Nein jedes Change-Event behandelt eigene Prozeduren mit anderen Aufgaben.
    Die Zuordnung von Hardwarekomponente und Variable seh ich jetzt noch nicht im Code. Event und EventArgs scheinen ja Eigenbau zu sein, das lässt zumindest MeldVariableIntegerEventArgs vermuten. Da stellt sich die Frage, wodurch das Event gefeuert wird. Wird da über einen Port ein Stück Hardware überwacht? Was passiert ungefähr in den EventHandlern? Große Änderungen am Programm, was dazu führt, dass bei jeder neuen MeldVariable-Instanz, die hinzukommt, das Programm an mehreren Stellen umgebaut werden muss? Das wäre für eine Problemlösung ein Stolperstein.
    Falls nicht: Ggf. ist es möglich, ein PlugIn-System zu entwickeln, wobei quasi für jede Variable ein neues DLL-Projekt erzeugt wird und bei Programmstart werden alle PlugIns geladen. So könnte das Hauptprogramm unangetastet bleiben und bei Änderungen oder Ergänzungen einer Hardwareüberwachung wird nur ein PlugIn-Projekt angefasst.

    Beispiele für sowas wären z.B.:
    • Bildbearbeitung: Das Hauptprogramm bindet Filter ein, die Pixel entgegennehmen und verändert zurückgeben (Bild invertieren, Farbton anpassen, Unschärfe ändern, Wasserzeichen einbauen, …)
    • Produktionschargenprüfer: Das Hauptprogramm schickt eine Chargenbezeichnung an ein gewähltes Berechnungsplugin und das spuckt dann aus, wann und wo ein Artikel hergestellt wurde oder wann er verfällt (wenn es kein Verfalldatum auf der Packung gibt (z.B. viele Kosmetika))
    • Datenspeicherverwaltung: Ein Programm soll gewisse Daten speichern und sendet diese nacheinander an diverse Plugins, die z.B. die Daten komprimieren, verschlüsseln und am Ende irgendwohin irgendwie speichern. Der User kann dann durch PlugIn-Auswahl entscheiden, was in welcher Reihenfolge passiert und wo es gespeichert werden soll
    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.
    Uff wie erkläre ich das denn am Besten.

    Also alle Variablen die habe werden im Hintergrund von Thread kontinulier gepollt. Also jede Variable hat eine Adresse in der Steuerung und wird per RFC Protokoll gelesen. Wenn der Wert der neugelesen wurde <> Alte wert ist, feuert der ein Event.

    So bekomm ich die Werteänderungen mit. Das ganze läuft schon in einer .dll

    Finde dein Ansatz aber gerade sehr interessant gerade wegen der Modulisierung.