PDA

Vollständige Version anzeigen : Verschachtelteste Unterformulare EINFACHST händeln;-)


clsOOP
20.03.2013, 23:15
Hallo,

es gibt zwar überall, auch bei uns im Forum, dazu Beiträge, wie man sich von Formular zu Unterformular zu Unterformular und dann zu den Steuerelementen des nächsten Unterformulars durchhangeln kann. Bei mehreren Unterformularen kommt man evtl. leicht ins Stolpern und und es passieren dann merkwürdige Dinge in Formularen, die man eigentlich gar nicht antasten wollte. Bei Ausdrücken wie: Me.Ufo1.Form.Ufo2.Form.Ufo3.Form.Controls("Irgendeins").Width = ...
' oder wieder zurück:
Me.Parent.Parent.Parent.Form.Controls("Irgendeins").Width = ... ist das auch kein Wunder.
Wie schön einfach kann man doch einfach in einem Hauptformular auf dessen Steuerelemente zugreifen oder auf seine Formulareigenschaften:
Me.BackColor = ...
' und
Me.controls("Irgendeins").Width = ...Wäre es nicht traumhaft, Unterformulare ganz genauso ansprechen zu können? Ganz einfach auf alle Eigenschaften des Formulars, sowie auf seine Steuerelemente zuzugreifen ohne sich Gedanken über einen Riesenausdruck zu machen? Der dann evtl. nichtmal auf Anhieb funktioniert.

Dazu habe ich mir ein paar Gedanken gemacht: Im Rahmen eines anderen Projektes, bei dem es um Mehrsprachigkeit ging, wurden meine Unterformulare nicht wie gewünscht auf die neue Sprache umgestellt. Es war Zeit für die Universallösung "Unterformulare".

Dafür habe ich zwei Klassen erstellt und ein normales Modul: Über die Modulfunktionen werden die Klassen ins Spiel gebracht.
Die Handhabung ist dann wirklich sehr sehr einfach, man braucht sich überhaupt nicht um die Klassen zu kümmern, die machen ihr Ding von ganz allein.
Man sollte sich aber mal das Modul ansehen, das ja alle wichtigen Funktionen zur Verfügung stellt, die man wie jede andere normale Funktion oder Prozedur aufrufen kann.
In den Formularen sind selbst auch Klassenvariablen überflüssig.
Um die Klassen in Euern eigenen Projekten zu verwenden, müßt ihr sie einfach importieren, darin sollte möglichst auch nichts verändert werden.
Private sForm As String 'wird hier im Beispiel verwendet
Initialisierung:
Das einzige was man machen muß, ist das jeweilige Formular erstmal "anzumelden". Das passiert im Form_Load und sieht so aus:
Init_clsOOP_Form Me
Laden der Unterformulare:
Jetzt kann man das oder die Unterformulare laden z.B. über einen Button - in dem Fall lade ich gleich zwei Unterformulare, so daß dann ein Hauptformular mit Unterformular, das noch ein weiteres Unterformular enthält, geöffnet sind:
LoadUfo Me.Name, Me.Ufo1.Name, "Frm_Main_1"
LoadUfo "Frm_Main_1", "Main_1_Container", "Frm_Test_1"Der 1. Parameter: in welches Formular wird geladen
Der 2. Parameter: wie heißt der Unterformular-Container, in den geladen werden soll, der sich auf dem Formular (s. 1. Parameter) befinden muß
Der 3. Parameter: Wie heißt das Formular, das als Unterformular dargestellt werden soll.
Wichtig dabei ist, daß natürlich die Hierarchie eingehalten wird. Man kann also ein Formular nur in ein anderes Formular laden, wenn dieses bereits geladen wurde.

Entladen der Unterformulare:
Um statt eines Unterformulares ein anderes anzuzeigen, muß das geladene Formular erstmal entladen werden:
UnLoadUfo strFormNameDazu ist als Parameter nur der Name des Formulars anzugeben, das entladen werden soll.

Ermitteln welches Unterformular in welchem Ufo-Container auf welchem Formular gerade geladen ist:
Manchmal muß das Programm wissen, welches Unterformular in einem bestimmten Ufo-Container steckt. Um das rauszukriegen nimmt man einfach: sForm = GetUfo("Frm_Main", "Ufo1")
GetUfo verlangt den Namen des Formulars und den Namen des Unterformular-Containers.

Auf Formulare und deren Eigenschaften sowie Controls und deren Eigenschaften zugreifen:
Diese Funktionalität war für mich ausschlaggebend. Es ist sooooo einfach und die Ausdrücke passen alle auf eine Codezeile und man sieht genau, was der Code macht:
clsOOP_Form("Frm_Main_1").UfoControls("FillOut").Value = Me.FillOut.Text
clsOOP_Form(sForm).UfoControls("FillOut").Value = Me.FillOut.Text
clsOOP_Form(sForm).Form.Section(acHeader).BackColor = vbYellow
clsOOP_Form("Frm_Main_1").GetParentUfoContainer.Width = 12345
clsOOP_Form("Frm_Main_1").GetUfoContainer("Ufo1").Width = 10000Egal in welchem Formular, oder zu wievieltem Male geschachtelten Unterformular man sich gerade bewegt, man gibt einfach nur den Namen des Formulars an und kann dann direkt auf die Klasse zugreifen, die das Formular verwaltet.
Sollte das betreffende Formular ein Hauptformular sein, was also kein Parent.Form besitzt, und man will an seine Steuerelemente ran, nimmt man ebenfalls "UfoControls". Das würde man dann benötigen, wenn man von einem Unterformular aus, Steuerelemente, die sich auf dem Hauptformular befinden, verändern will.
Im obigen Beispiel:
.UfoControls - Zugriff auf die Steuerelemnte des angegebenen Formulars
.Form - Zugriff auf die Formulareigenschaften des angegebenen Formulars
.GetParentUfoContainer - Zugriff auf den UfoContainer, in dem das angegebene Formular selber steckt
.GetUfoContainer(sUfoContainerName) - Zugriff auf einen bestimmten durch seinen Namen angegebenen UfoContainer - manche Formulare haben ja durchaus mehrere Unterformulare.

Abmelden der Formulare:
Jedes Formular, das geschlossen wird, muß auch noch von der Klasse abgemeldet werden, um den Speicher wieder frei zu geben. Das machen aber auch die Klassen ganz alleine. Im Formular selbst braucht also keine extra "Unload_Form"-Prozedur aufgerufen werden.

Noch ein Hinweis:
Falls Fehler auftreten, dann in der Entwurfsansicht mal nachsehen, ob der Ufo-Container leer ist. Falls darin noch ein Formular sichtbar ist, ist das die Fehlerquelle.
Wer möchte, kann die Klasse ja um die Fehlerbehandlung für diesen Fall erweitern;-)

Beispieldatenbank:
Die Datenbank enthält neben der Klassen und des Moduls noch 4 Formulare, die über die entsprechenden Schaltflächen geladen werden können.

Würde mich sehr freuen, wenn ihr die Klassen mal bei Euch ausprobiert (auch in höheren Access-Versionen) und Eure Erfahrungen mitteilt, der Test ist schnell gemacht. Die Erstellung und das Testen haben mich 3 Tage gekostet.

Ansonsten viel Spaß damit