Form über Formnamen als String aufrufen

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Form über Formnamen als String aufrufen

    Hallo Ihr Wissenen,

    Ich habe mehrere Forms die den selben Aufbau haben und jewels ein DataGridView besitzen.
    Nun möchte ich einen Code erstellen, der für alle anderen Formen auch anwendbar ist.
    Dazu muss ich den Namen der Form übertragen. Wie?

    Mein Ansatz:

    VB.NET-Quellcode

    1. Public Sub Grid_Laden(Byval FormName as Form, Byval GridName as String)
    2. Dim iName As DataGridView = FormName.Controls(GridName)
    3. End Sub


    ODER

    VB.NET-Quellcode

    1. Public Sub Grid_Laden(Byval Form_Name as String, Byval GridName as String)
    2. Dim FormName as Form = ??????????????????????
    3. Dim iName As DataGridView = FormName.Controls(GridName)
    4. End Sub


    Vielen Dank im Voraus.

    Lieben GRuß,
    Chris
    @Hotdogxxxx:: Gib diesen Formen eine gemeinsame Klasse / Form als Basisklasse.
    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!
    Jede Form hat eine eigene Klasse, da viele unterschiedliche Sub laufen und mir das in einer Zu unübersichtlich wird und mir auch die Übersichlichkeit verloren geht.

    Es gibt aber eine Codesammlung unter der alle Subs oder Funktionen hinterlegt sind, die gemeinsam verwendet werden.

    Das funktioniert soweit auch sehr gut.

    Doch diesesmal muss ich die jeweilige FOrm ansprechen aber ich weiß nicht wie.

    Mir ist zwar klar das mein erster Ansatz funktionieren sollte aber ich weiß nicht wie ich die Form übertragen soll also wie ich dann Grid_Laden aus der jeweilgen Form aufrufen soll.

    VB.NET-Quellcode

    1. Sub Test()
    2. Grid_Laden(???????????,"gd_Grid")
    3. End Sub
    4. Public Sub Grid_Laden(Byval FormName as Form, Byval GridName as String)
    5. Dim iName As DataGridView = FormName.Controls(GridName)
    6. End Sub


    Daher der zweite Ansatz wo ich den Namen der Form beim Aufrufen Übertrage. Den ich weiß das ich den Namen einfach über 'Name' auslesen kann. Aber im zweiten Beisßiel weil ich eben nicht wie ich eine Form über den String namen auslesen soll.

    In Excel VBA würde ein ähnlichen Beispiel so deklariert werden: 'Sheets("TEST")

    VB.NET-Quellcode

    1. My.Application.OpenForms

    ruft eine Auflistung aller geöffneten Formulare ab.
    Formen sind dann ansprechbar über den Index oder den name as string:

    VB.NET-Quellcode

    1. My.Application.OpenForms("FromName")


    ist es das was du suchst?
    Puh... also so wie du dir das denkst, sollte das hier klappen:

    VB.NET-Quellcode

    1. Public Sub GridLaden(ByVal Formname As String, ByVal GridName As String)
    2. Dim frm As Form = Application.OpenForms(Formname)
    3. If frm IsNot Nothing Then
    4. Dim grid As DataGridView = CType(frm.Controls(GridName), DataGridView)
    5. '... hier was mit dem DataGridView machen
    6. End If
    7. End Sub


    Aber den Vorschlag mit der von Form abgeleiteten gemeinsamen Basisklasse solltest du wirklich nochmal überdenken. Im Zweifel kann dir diesbezüglich hier ebenfalls geholfen werden.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Erkläre bitte das letztendliche Ziel Deines Programms. Es ist der falsche Weg, irgendwas über seinen Namen anzusprechen. Jedes Objekt ist immer klar identifiziert.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ich muss mich leider korrigieren.

    Es funktioniert doch nicht. Als Fehler wird ausgeworfen: "Objektverweis wurde nicht auf eine Objektinstanz festgelegt."
    Habe es erst nicht gemerkt, da Fehler in ein Fehlerprotokol geladen werden.

    VB.NET-Quellcode

    1. Dim Form_Name As String = "FORMNAME"
    2. Dim FormName As Form = Application.OpenForms(Form_Name)
    3. FormName.Show()


    Um die vorher gestellte Frage zu beantworten:
    Der Sinn des Programms ist es, Informationen aus verschiedenen Quellen zu laden, und diese auf einem SQL Server abzuspeichern.
    Das Programm umfasst viele Form's die wiederum unterschiedliche Quelle abruft z.B. Xml Dateien, InternetSeiten, TextDateien.

    Da die Quelle nicht einheitlich ist, muss eben der Code auf jede Quelle und jeden Task angepasst werden.

    Es gibt aber eben auch Codesubs oder Funktionen, die alle Form's gleich haben.

    Bei besagten Problem geht es darum: Bei jedem Ausführen der einzelnen Tasks werden unterschiedliche LOG Protokolle (TxT Dateien) befüllt. z.B. Hat der Run des Codes geklappt, wieviele Daten wurden übertragen, welche Fehler sind aufgetreten usw.
    Beim öffnen der einzelnen Form soll einfach das jeweilige LOG Protokoll in ein DataGripView geladen werden. Dazu habe ich bisher einen entsprechenden Code beim erstellen in jede einzelne Form gespeichert. Daher hat es auch gut funktioniert. Jetzt möchte ich aber eben diesen Code so gestallten, dass ich einfach die Variabeln ändern kann und der Code dann entsprechend für die entsprechende Form ausgeführt wird.

    Hier ist der entsprechende Gesamte Code:

    VB.NET-Quellcode

    1. Public Sub LogFile_in_Grid_Einlesen(ByVal Form_Name As String, ByVal DataGrindName As String, Optional ByVal LogFileName As String = "\LOG File.txt")
    2. On Error GoTo Ende
    3. Dim FormName As Form = Application.OpenForms(Form_Name)
    4. If FormName Is Nothing Then Exit Sub
    5. Dim Grid As DataGridView = CType(FormName.Controls(DataGrindName), DataGridView)
    6. Dim LogExists As Boolean = My.Computer.FileSystem.FileExists(Application.StartupPath & "\LOGFILES" & LogFileName)
    7. 'Wenn Logfile noch nicht angelegt wurde dann abbrechen
    8. If LogExists = False Then Exit Sub
    9. 'Löscht das alte Grid
    10. Grid.Rows.Clear()
    11. 'Liest das Logfile in das Grid
    12. Dim TsTR = My.Computer.FileSystem.OpenTextFileReader(Application.StartupPath & "\LOGFILES" & LogFileName)
    13. Do Until TsTR.EndOfStream
    14. Dim Text As String = TsTR.ReadLine
    15. Dim Stringarray() As String = Split(Text, ";")
    16. 'Ins Grid speichern
    17. If Text <> "" Then Grid.Rows.Add(Stringarray)
    18. Loop
    19. TsTR.Close()
    20. 'Spalten sortieren
    21. Grid.Sort(Grid.Columns(0), System.ComponentModel.ListSortDirection.Descending)
    22. Ende:
    23. End Sub


    Aufgerufen wird es dann mit:

    VB.NET-Quellcode

    1. LogFile_in_Grid_Einlesen("Startseite", "dgFileLog", "\LOG File.txt")


    PS: Ich bin mir sicher, dass es vielleicht elegantere Möglichkeiten gibt. Ich arbeite erst seit 6 Monaten mit VB und habe bisher nur mit Excel VBA gearbeitet. Ich habe das nicht Studiert oder Professionell erlernt, sondern nutze es nur als Hobby um die täglichen Arbeiten in der Firma zu erleichern. Also bitte nicht Prügeln wenn manches vielleicht nicht Lehrstuhl konform ist. :love:

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

    Hotdogxxxx schrieb:

    Hier ist der entsprechende Gesamte Code
    der totaler VB6-Ranz-Code ist.

    VB.NET-Quellcode

    1. Dim Form_Name As String = "FORMNAME"
    2. Dim FormName As Form = Application.OpenForms(Form_Name)
    Krasse Namensgebung.

    VB.NET-Quellcode

    1. On Error GoTo Ende
    Weg damit, Du willst Fehler finden, nicht verschleiern.
    Fehlerbehandlung belommen wir später.
    Mach mal

    VB.NET-Quellcode

    1. Dim FormName As Form = Application.OpenForms(Form_Name)
    2. If FormName Is Nothing Then
    3. MessageBox.Show(Form_Name & " War nix")
    4. Else
    5. FormName.Show()
    6. End If
    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!
    ?(

    Ergebnis:
    "Startseite war nix"

    Startseite existiert als Formname ist aber vorher nicht gestartet worden.

    Wenn ich die Beschreibung von Application.Openform richtig verstehe "Listet es alle Namen der geöffneten Form's auf", dann habe ich das gefühl, dass er die Formdeshalb nicht findet, weil sie vorher nicht angesprochen wurde. Falsch?

    Hotdogxxxx schrieb:

    dann habe ich das gefühl
    Was ist mit Eigeninitiative?
    Du postest hier im Hauptforum.
    Mach Dir ein kleines Testprogramm mit 4 Buttons und 5 Formen und probier es aus. Lies die MSDN zu diesem Thema.
    Poste das Ergebnis.
    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!
    @Rod das ist mein 7 Post in diesem Forum, die hälfte davon heute. Ich wußte nicht das man im Hauptforum nicht posten darf. Ich dachte es würde hier darum gehen, dass man ein thementypisches Problem hat und man daher die Hilfe des Kollektiv's in Anspruch nehmen möchte.

    Bezüglich Eigeninitiative... Ich bin ständig am Testen und permanent am Google suchen und nachlesen wie ich das machen könnte.

    Als Lösung wurde mir Application.Openform genannt. Da es nicht funktioniert habe ich nachgelesen was Openform bedeutet und festgestellt, dass hier der Fehler liegt.

    Mit application.Forms funktioniert es auch nicht.

    Wenn du also die Lösung kennst, dann sag es doch und ich werde dir auf ewig Dankbar sein.
    Klick mit der Maus auf ein (syntaktisch richtiges) Keyword. Drück dann die Taste F1 und die MSDN tut sich auf. Dort findest Du eine korrekte Beschreibung des Befehls und auch Beispiele dafür.
    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!
    @Rod: Danke für deinen Versuch mir zu helfen aber du hilfst mir nicht.

    Ich mache alles auf Anfang und belasse die Code Schnipsel in den einzelnen Formen. Ist zwar scheiße aber es hat funktioniert.

    NACHTRAG:
    @Rod: Ich muss echt lachen... Du sagst mir ich soll folgenden Code probieren, was ich mache und nicht funktioniert, und dann sagst du ich soll es selbst versuchen.

    Versuch doch bitte deinen Code, er funktioniert nicht:

    VB.NET-Quellcode

    1. 'Ergänzung zu Testzwecken
    2. Dim Form_Name as String = "Startseite"
    3. Dim FormName As Form = Application.OpenForms(Form_Name)
    4. If FormName Is Nothing Then
    5. MessageBox.Show(Form_Name & " War nix")
    6. Else
    7. FormName.Show()
    8. End If


    Wenn ich die aber folgendes mache:

    VB.NET-Quellcode

    1. 'Ergänzung zu Testzwecken
    2. Startseite.show()
    3. Dim Form_Name as String = "Startseite"
    4. Dim FormName As Form = Application.OpenForms(Form_Name)
    5. If FormName Is Nothing Then
    6. MessageBox.Show(Form_Name & " War nix")
    7. Else
    8. FormName.close()
    9. End If


    Wenn ich also erst die Form öffne und ich die dann anspreche dann funktioniert es.
    Ich brauche also ein Keywort, dass die Form über einen String-Namen anspricht.

    Wenn also jemand weiß, wie dieses Keywort heißt, würde ich mich freuen, wenn er mir helfen könnte, den ich weiß und finde es nicht.

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

    Hotdogxxxx schrieb:

    aber du hilfst mir nicht.
    Wenn Dir nur mit fertigem Code geholfen ist, ist das nicht gut.
    Du musst lernen, Dir relevante Informationen zu beschaffen, und da ist Frau Google nicht in der 1. Reihe, sondern die MSDN.
    Das Forum kommt da noch lange nicht!
    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!
    Wozu brauchst Du die Formen überhaupt? Du sagst, Du sammelst Daten aus verschiedenen Quellen. Gut. Sammle Deine Daten, bereite sie auf, bringe sie in ein einheitliches Format und zeige sie gesammelt an. Dies kapselst Du in Klassen. Diese Klassen verwaltest Du in Deinem Hauptprogramm/MainForm. So hast Du jederzeit Zugriff auf die richtige Klasse, ohne überhaupt in Verlegenheit zu kommen, sie durch einen String anzusprechen. Selbiges gilt auch für Forms. Forms sind nichts anderes als Klassen. Erstelle Deine Instanzen im Hauptprogramm und verwalte sie von dort aus. Möchte eine Kindklasse etwas mitteilen, so löst sie ein Event aus, welches vom Hauptprogramm empfangen wird. Umgekehrt greift das Hauptprogramm auf die Properties/Methoden der Kindklasse zu, um dort etwas zu verändern.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

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

    @Space: Das Programm stellt die gesammelten Daten nicht dar, sondern sammelt sie, bereitet sie auf und speichert diese in der SQL Datenbank.

    Da jede Datenquelle anderst aufgebaut ist, habe ich für jede Datenquelle eine eigene Form erstellt. Im Code der Form befinden sich dann die Codeabläufe die gebraucht werden um die entsprechende Quelle auszulesen, umzuwandeln und in die Datenbank abzuspeichern. Um mir die Arbeit zu vereinfachen, habe ich eine leere Codedatei dem Projekt hinzugefüht, in dem die Codes gespeichert sind, die gemeinsam über alle Formen genutzt werden. Zum Beispiel der Zugriff auf die Datenbank, Funktionen usw.

    Vielleicht ist das nicht wirklich Regelkonform. Ich habe mir das vielleicht durch VBA angewöhnt, den dort habe ich eben Standardmodule die ich eben in allen MakroExcel Dateien verwende. Beim öffnen der Excel Datei werden die Standard Module jeweils automatisch neu geladen und somit habe ich in allen Excel Tabellen die gleiche Basis und kann bei Fehlern diese Zentral beheben und muss nicht 100 Excel Dateien bearbeiten oder wiederkehrende Funktionen jedesmal neu Schreiben.

    Egal, in diesem VB Fall gibt es insgesamt 24 Formen ergo 24 unterschiedliche Quellen die bearbeitet und in die Datenbank übertragen werden. Die jeweilige Form selbst ist nur eine GUI die eine Protokoll txt-Datei abruft und in ein DataGridView überträgt. Manche Forms sind aber auch deutlich komplexer und es macht keinen Sinn alle unter ein Dach zu bringen. Es würde auch vom Code her zu unübersichtlich werden.

    Nun musste ich gestern aber etwas an dem Code ändern, der die Log Datei in das Grid überträgt. Daher musste ich alle 24 Form's einzeln aufrufen, um das zu ändern. Daher dachte ich mir, bei Gelegenheit schieb ich diesen gemeinsamen Codeabschnitt einfach auch in die "SammelCodeDatei", steuere es dort Zentral.

    Dazu muss ich aber wissen wie man die einzelnen Forms über dessen String-Namen anspricht.

    Wie man sie Anspricht, wenn sie bereits geöffnet sind weiß ich ja nun. Danke nochmal, Rod.

    Da ich nun aber heute fast den ganzen Tag damit aufgebracht habe dieses vorhaben zu realisieren, belasse ich es einfach wie es ist, und hoffe das ich den Code nicht nochmal ändern muss.

    @Rod: Ich habe vor 6 Monaten in VB fast bei null angefangen betreibe VBA aber seit Jahren als Hobby und beruflich als Arbeitserleichterung. Ich habe mein letztes Posting oben nochmal um ein paar Zeilen ergänzt, den es geht nicht darum das ich nicht bereit bin selbst weiter zu machen, sondern das ich einfach nicht weiß wie, und deine Hilfe nicht funktioniert. Wann kommt deiner Meinung nach das HilfeForum wenn man nach Stundenlangem probieren, suchen in Visual Studio und Google noch immer keine Lösung hat.
    Egal, du hast wenigstens versucht zu helfen und das rechne ich dir hoch an. Vielen Dank dafür.
    Das Problem ist gelöst! Was mich die ganze Zeit gestört hat, war die Überlegung "Warum soll der Fehler entstehen wenn er versucht auf die Form zuzugreifen, den sie ist ja geöffnet." Also sollte OpenForm funktionieren, denn es ist ja offen. Also konnte der Fehler auch beim ansprechen des DataGridView bestehen. Und so war es auch. Irgendwie funktionierte das Ansprechen nicht, wenn ich das Grid versuche über den Stringnamen des Grids anzusprechen. Egal nun spreche ich das Grid direkt an und es funktioniert. Ich spreche nun das Grid direkt an und es geht.

    Danke nochmal für die Hilfe.

    Hotdogxxxx schrieb:

    nun spreche ich das Grid direkt an und es funktioniert.
    Informiere Dich mal über 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!