Last Update: 2024 - 05 - 21 |
Steuern eines Hauptformulars über Unterformular-Steuerelementreferenzenvon Philipp Stiefel, ursprünglich veröffentlicht 2023-03-02 zuletzt bearbeitet 2023-03-02 Foto von Fré Sonneveld auf Unsplash Ich wollte gerade einen Artikel über die Verwendung von Unterformularereignissen im Hauptformular schreiben, um die im Hauptformular angezeigten Daten basierend auf Daten aus dem Unterformular zu aktualisieren. Dabei stellte sich heraus, dass es einen alternativen Ansatz gibt, der einfacher ist und dennoch für die meisten Szenarien zu ähnlichen Ergebnissen führt. Während meine ursprüngliche Idee immer noch ihre Vorzüge hat, möchte ich dir hier erstmal meinen neu entdeckten, alternativen Ansatz vorstellen. Diesen Inhalt gibt es auch als Video auf YouTube: AusgangspunktDu hast ein Hauptformular mit einem Unterformular, um Daten anzuzeigen und dem Benutzer zu ermöglichen, Daten im Unterformular zu bearbeiten. Das Hauptformular zeigt einige, möglicherweise aggregierte, Daten aus dem Unterformular an. Die (Unterformular-)Daten im Hauptformular müssen aktualisiert werden, sobald ein Datensatz im Unterformular ausgewählt oder aktualisiert wird. Steuerelementverweise im SteuerelementinhaltDisclaimer: Ich mag die Verwendung dieser langen, verketteten Verweise auf Steuerelemente in Formularen oder sogar tief verschachtelten Unterformularen mit mehreren Ebenen nicht. Damit stochert man tief in den Eingeweiden der Formobjekte herum, die lieber gekapselt sein und in Ruhe gelassen werden sollten. Trotzdem muss ich zugeben, dass wir mit diesem Ansatz einfach Lösungen umsetzen können, wie sie in diesem Text beschrieben sind, die mit besseren Designprinzipien komplizierter zu implementieren wären. Eine der Hauptfunktionen von Access besteht darin, dass man auf jedes Steuerelement verweisen können, das in einer Datenbankanwendung angezeigt wird, um den Wert des Steuerelements abzurufen. Ein einfaches Beispiel, um den Wert eines Steuerelements in einem völlig unabhängigen Steuerelement anzuzeigen: =Forms![DeinFormularname]![Steuerelementname]
Der Verweis auf ein Steuerelement in einem Unterformular folgt demselben Muster. =Forms![DeinHauptformularname]![SubFormControlName]![ControlNameInSubForm]
Innerhalb des Eltern-Formulars des Unterformulars kann dies auf die Referenz im Kontext des übergeordneten Formulars reduziert werden: =[SubFormControlName]![SteuerelementNameInSubForm]
Alle drei obigen Beispiele rufen automatisch die Value-Eigenschaft des Steuerelements ab. Dieser Ansatz kann nicht verwendet werden, um auf andere Steuerelementeigenschaften zuzugreifen. Der abgerufene Wert wird aktualisiert, sobald sich der Wert in der ursprünglichen Steuerelement ändert. Das kann passieren, weil entweder ein anderer Datensatz im Formular zum aktuellen Datensatz gemacht wurde oder der Datensatz vom Benutzer mit neuen Werten aktualisiert wurde. Dies ist sehr praktisch, da das übergeordnete Formularsteuerelement, das auf diese Weise auf ein Unterformularsteuerelement verweist, automatisch den aktuellen Wert des Unterformularsteuerelements anzeigt. Diese automatische Aktualisierung des Steuerelementinhalts funktioniert nicht nur mit einem direkten Verweis auf das Aktualisierungssteuerelement, sondern auch entlang einer Kette von mehreren Steuerelementen, die auf ein anderes verweisen, und nur das Steuerelement am Ende dieser Kette wird aktualisiert. Wenn es ein Steuerelement namens MySubFormReferenceControl mit der Steuerelementinhalt gibt: =[SubFormControlName]![SteuerelementNameInSubForm]
AnotherControl zeigt dann den Inhalt des MySubFormReferenceControl an: =[MySubFormReferenceControl]
Der Inhalt von AnotherControl wird auch aktualisiert, wenn das ControlNameInSubForm-Steuerelement im Unterformular mit einem neuen Wert aktualisiert wird. Wenn du mehrere Steuerelemente im übergeordneten Formular abhängig von ein und demselben Steuerelement im Unterformular hast, ist es hilfreich, ein solches „Proxy-Steuerelement“ zu erstellen, um die hässliche Referenz in das Unterformular in nur einem Steuerelement zu konsolidieren, während alle die anderen Steuerelemente auf den Wert des „Proxy-Steuerelements“ verweisen und von der Referenz des Unterformulars isoliert sind. Aktualisieren von Berechnungsergebnissen ohne direkte SteuerungsreferenzenWas ist mit Steuerelementen, die indirekt von Unterformulardaten abhängen? D.h. ohne direkten Verweis auf ein Steuerelement im Unterformular. Wenn wir beispielsweise die Summe einer Spalte in der Datenherkunft des Unterformulars anzeigen möchten, würden wir diesen Ausdruck in der Steuerelementinhalt-Eigenschaft des übergeordneten Formularsteuerelements verwenden: =DSum("Amount";"SubFormDatenherkunft")
Der Ausdruck funktioniert durch Abfragen der Datenherkunft des Unterformulars, wird aber nicht automatisch aktualisiert, wenn sich Daten im Unterformular ändern. Wenn wir zum Beispiel einen neuen Datensatz hinzufügen oder den Wert von Amount in einem bestehenden Datensatz ändern, muss du das Steuerelement explizit aktualisieren, um den aktualisierten Wert zu erhalten. Aber es gibt einen schmutzigen Trick, um Access glauben zu machen, dass der Inhalt dieses Steuerelements vom Wert eines Steuerelements im Unterformular abhängt. Ich habe diesen Trick entdeckt, als ich ein etwas abgewandeltes Beispiel erstellt habe. Ich wollte die Summe der Spalte Betrag ohne den Betrag aus dem aktuellen Datensatz des Unterformulars abfragen. Ich habe diese Steuerelementinhalt verwendet: =DSum("Betrag";"SubFormDatenherkunft", "RecordId <> " & [txtRecordId])
RecordId ist der Primärschlüssel der im Unterformular angezeigten Daten und txtRecordId ist ein Steuerelement im aktuellen Formular, das einen Verweis auf das entsprechende RecordId-Steuerelement im Unterformular enthält, wie im vorherigen Absatz beschrieben. Mit dieser Steuerelementinhalt wird die Summe immer automatisch aktualisiert, wenn der aktuelle Datensatz geändert oder aktualisiert wird, oder ein Datensatz hinzugefügt oder gelöscht wird. Das funktioniert, weil Access weiß, dass der RecordId-Wert des Unterformulars für das Ergebnis des Ausdrucks relevant ist und der Ausdruck neu berechnet werden muss, sobald sich der Datensatz des Unterformulars ändert. Was ist, wenn wir Access dazu bringen, zu glauben, dass der Unterformulardatensatz eine relevante Eingabe für den Ausdruck ist, selbst wenn dies nicht der Fall ist? Lass uns in diesem Sinne die Steuerelementinhalt für die Gesamtsumme von oben überarbeiten: =DSum("Amount";" SubFormDatenherkunft ";[txtRecordId] & "=" & [txtRecordId])
Wir haben txtRecordId in die Kriterien des Aufrufs von DSum aufgenommen. Da dieses Kriterium jedoch immer wahr ist, hat es niemals Auswirkungen auf das Ergebnis der DSum-Abfrage. Der entscheidende Punkt ist: Jetzt wird die Gesamtsumme automatisch aktualisiert, sobald der aktuelle Datensatz im Unterformular geändert oder aktualisiert oder ein Datensatz hinzugefügt oder gelöscht wird. Generische Verwendung dieses „Schmutzigen Tricks“Wenn der Ausdruck eine Funktion beinhaltet, die wir zur Aktualisierung erneut ausführen wollen, ist es gar nicht erforderlich, dass der Wert aus dem Datensatz des Unterformulars ein tatsächliches Argument für den Funktionsaufruf ist. Es reicht bereits aus, wenn es nur ein beliebiger Teil des Ausdrucks in der Steuerelementinhalt ist. Wir können also den „schmutzigen Trick“ mit praktisch jedem erdenklichen Ausdruck anwenden, selbst wenn VBA-Funktionen von der Steuerelementinhalt aufgerufen werden. Hier ist ein Beispiel für einen VBA-Funktionsaufruf der ComplexCalculation-Funktion, an die das Ergebnis eines Iif-Ausdrucks angehängt wird, der immer ein leerer String sein wird: =ComplexCalculation() & IIf([txtRecordId]=1;"";"")
Dieses Anhängens einer leeren Zeichenfolge (das Ergebnis des Iif-Ausdrucks) führt jedoch dazu, dass der gesamte Ausdruck zu Textdaten wird, selbst wenn sich der tatsächliche Wert nicht ändert. Daher musst du eine explizite Konvertierung zurück zum ursprünglichen Typ des Ausdrucks hinzufügen, bevor der Hack angewendet wurde. Andernfalls funktionieren die Control-Formatierung und die Textausrichtung im Steuerelement nicht mehr wie vorgesehen. Hier ist ein Beispiel für eine solche Datentypkonvertierung unter Verwendung der CDate-Funktion für einen mit der Now-Funktion abgerufenen Datumswert: =CDate(Now() & IIf([txtRecordId]=1;"";""))
Im Modul Conversion der VBA-Standardbibliothek findest Du für jeden VBA-Datentyp die passende Konvertierungsfunktion. FazitAuch wenn ich die Verwendung von Steuerelement-Referenzen über Formulargrenzen hinaus, wie in diesem Text beschrieben, sehr unschön finde, sind sie ein ziemlich einfaches und dennoch effektives Werkzeug, um automatisch aktualisierte, berechnete Controls zu implementieren. Dieser Ansatz ist auf die Änderung des aktuellen Datensatzes und nach jeder Operation zum Hinzufügen, Löschen oder Aktualisieren eines Datensatzes im Unterformular beschränkt. In diesem Kontext werden sie mit Abstand am häufigsten benötigt. Wenn du auf andere Unterformularereignisse im übergeordneten Formular reagieren möchtest, um den Bildschirm zu aktualisieren oder VBA-Code auszuführen, müssen Sie auf die kompliziertere Lösung zurückgreifen, die ich ursprünglich in diesem Text vorschlagen wollte. (Ich werde hier einen Link ergänzen, sobald der andere Text veröffentlicht ist.) DownloadEine Beispieldatenbank zu diesem Text gibt es auch als Download: SubFormReferences_Demo.zip
Ich werde Deine Email-Addresse niemals weitergeben. Du kannst den Newsletter jederzeit abbestellen. © 1999 - 2024 by Philipp Stiefel - Datenschutzerklärung |