Problem mit Public Variable

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    Problem mit Public Variable

    Hey Leute,

    Suche ergab keine Treffer, deswegen hier:

    In Form1 wird ein Integer einer Datenbank (Beispielwert 1) als "Public myID As Integer" gespeichert. Wenn dieser in Form2 aufgerufen wird, wird er gelöscht, d.h. als Integer zeigt er 0 an, wenn er als String läuft ("Public myID as String" und DB nvchar), zeigt er nichts an, ist daher leer.

    Woran kann das liegen? Quellcode ist leicht umfangreich, kann bei Bedarf nachgereicht werden.
    Verstehe ich das richtig, du hast in Form1 eine Variable myId (Integer) und in Form2 eine Variable myId (String)?
    Ich würde in Form2 eine Methode einbauen

    VB.NET-Quellcode

    1. ​Public Sub setMyId(ByVal id as Integer)
    2. myId = id.ToString()
    3. End Sub

    und in Form1

    VB.NET-Quellcode

    1. ​Dim f2 as new Form2
    2. f2.setMyId(myId)
    3. f2.Show()

    Dann brauchst du keine Public-Variablen mehr.
    Nee, hab mich falsch ausgedrückt. Mit dem String wollte ich nur sagen, dass ich das gleiche Problem bereits mit nem String anstelle eines Integer lösen wollte.

    Sprich: Ich habe in Form1 einen Public Integer und dieser wird in Form1 richtig angezeigt, in Form2 wird leider der Inhalt gelöscht (auch mit Form2.myID). Was könnte das Problem sein? Der Integer wird in Form1 aus einer Datenbank (SQL) gelesen und in den Public Integer gespeichert.

    Jonue schrieb:

    Sprich: Ich habe in Form1 einen Public Integer und dieser wird in Form1 richtig angezeigt, in Form2 wird leider der Inhalt gelöscht (auch mit Form2.myID). Was könnte das Problem sein?
    ich versteh ühaupt nix.
    Wenn du den Wert in Form1 hast, hast du ihn in Form1. Wie sollte er ühaupt nach Form2 kommen, der Wert?

    Aber ich glaub, dir ist auch nicht klar, dass Form1, Form2 eiglich gar keine Objekt-Instanzen sind, sondern Datentypen.
    Es ist meist hilfreich, wenn man diese Dinge auseinander halten kann: Instanziierung von Forms und Aufruf von Dialogen

    sonne75 schrieb:


    Da bin ich beruhigt, dass es nicht nur mir so geht. Zumal ich mir nicht vorstellen kann, warum es sinnvoll sein soll, IDs von Datenbanken als Integer in den Formen zu speichern...





    Der Hintergrund ist eig. nur der, dass ich dann nicht erneut die Werte aus der Datenbank fischen muss, sondern leichter aus der Variable benutze. Schwachsinn?

    Hier ein Stück Code (ist insg. sehr viel, deswegen hier nur das Wichtigste):

    C-Quellcode

    1. Public Class Fo02
    2. 'Variablen
    3. Public myUserID As Integer
    4. Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
    5. 'Datenbankabfrage
    6. Dim con As New SqlServerCe.SqlCeConnection
    7. Dim cmd As New SqlServerCe.SqlCeCommand
    8. Dim reader As SqlServerCe.SqlCeDataReader
    9. Try
    10. con.ConnectionString = "Data Source=C:\Database.sdf"
    11. cmd.Connection = con
    12. cmd.CommandText = "select * from Mitarbeiter"
    13. con.Open()
    14. reader = cmd.ExecuteReader()
    15. Do While reader.Read()
    16. If reader("Login") = UsernameTextBox.Text And reader("Passwort") = PasswordTextBox.Text Then
    17. myUserID = reader("ID")
    18. Fo03.Show()
    19. End If
    20. Loop
    21. reader.Close()
    22. con.Close()
    23. Catch ex As Exception
    24. MessageBox.Show(ex.Message)
    25. End Try
    26. End Sub

    Hier wurde jetzt in einem Login-Form geguckt, ob ein Benutzer vorhanden ist und dessen ID als myUserID gespeichert (wichtig für weitere Funktionen, u.a. Termine für eben diesen Benutzer speichern [in allg. Termindatenbank für alle Benutzer, bzw. IDs]).

    C-Quellcode

    1. Public Class Fo30
    2. Private Sub ButtonFo30OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFo30OK.Click
    3. MsgBox(Fo02.myUserID)
    4. End Sub
    5. End Class

    Die zweite Klasse ist jetzt sehr vereinfacht und soll später anders nützlich werden.

    Jetzt stelle man sich vor, dass man in der Datenbank den Benutzer (ID:1 - Login:Jonas - Passwort:Currywurst) hat und diesen im Login-Form eingibt. Dann sollte er für weitere Verwendungen doch als myUserID die 1 speichern. Sobald aber Fo03 geöffnet wird, hat er diese 1 vergessen, obwohl myUserID eine öffentliche Variable ist. Somit gibt er die 0 aus.

    Die Seite mit den Instanziierung von Forms muss ich noch lesen... dazu später mehr.
    Du fragst gerade in Fo30 den Wert von myId in der Klasse Fo02 ab.
    Du müsstest aber auf das Objekt von Fo02 zugreifen.
    (Siehe Post vom ErfinderDesRades)

    Entweder speicherst du deine Benutzer in einem Dataset, auf das du aus jedem Formular zugreifen kannst, oder du nutzt meinen Vorschlag aus meinem ersten Post. (Ohne .ToString())

    Desweiteren solltest du OptionStrictOn schalten.
    Dann könntest du auch keinen reader mit einem String vergleichen.
    Hab eine etwas... schluderigere Lösung. Hab die Variable Fo02.myID an die Variable Fo03.myID gekoppelt, bevor ich die Fo02 geschlossen habe. So wurde der Wert übertragen. Leicht hässlich, klappt aber.

    Habs somit beseitigt... wenn auch hässlich. Werde auf Dauer deine Variante übernehmen, HamburgerJunge. Und das mit den Instanziierungen von Forms ist aufschlussreich. Für den Laien was ganz Neues.

    Danke für die Hilfe, ich bin damit soweit durch!

    Jonue schrieb:

    Der Hintergrund ist eig. nur der, dass ich dann nicht erneut die Werte aus der Datenbank fischen muss, sondern leichter aus der Variable benutze. Schwachsinn?
    nö - die Idee ist genau richtig: Keinesfalls dieselben Werte mehrmals aus der DB abrufen

    Das führt bei mehreren Forms aber auf eine Architektur-Frage, da muss man nämlich letztendlich mit einem Datenmodell-Layer anfangen, welches von den Forms unabhängig ist.

    Aber son popeliges LogIn-Form, das geht noch, denn das kann man als modalen Dialog gestalten, mit frmLogIn.ShowDialog aufzurufen, etc. pp. ach guck! im Form-Instanzieren-Thread hab ich ja genau dazu ein Video eingestellt, das ist eiglich ein Standard-Beispiel, wie man ein Login abhandelt.
    Also das geht noch mit "normalem" Datenmodell - also ich nehm da ja immer typisierte Datasetse für (von mit Datenbank entwickeln halte ich nicht so viel): Datenbänkerei-Einstieg
    Ich kann ErfinderDesRades nur zustimmen. Der Einstieg in die Datasets ist zwar holprig (bei mir zumindest). Aber wenn man sich mal eingearbeitet hat, funktioniert das Ganze recht gut.
    Man kann beliebige Daten speichern und sie von jedem Form aus aufrufen. Es besteht keine (oder nur geringe) Gefahr das dabei etwas durcheinander gerät. Besonders wenn man es schafft
    alles typsiert zu halten.
    Und man braucht nur sehr wenige Zeilen Quellcode.

    E: Besonders geholfen hat mir der Teil: Daten laden, speichern, verarbeiten - einfachste Variante. So greift
    jedes Form auf das selbe Dataset zu und erstellt nicht einzelne instanzen.
    Option strict = on

    If it's stupid and it works it ain't stupid.
    naja - bei nem LogIn kann das schon sinnvoll sein. Nur die UserId muss gemerkt werden, und alle weiteren DB-Zugriffe sind immer mit einem WHERE-Abschnitt auf diese UserId eingeschränkt.

    Nur das leidige Sicherheitsproblem, weil ein Angreifer könnte ja auch SELECTs an die DB schicken, mit ausgedachter UserId oder gar uneingeschränkt.