Home > Artikel > Ausgabe 11/2016 > Ereignisse anderer Objekte nutzen

Ereignisse anderer Objekte nutzen

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Normalerweise implementieren Sie Ereignisse immer in dem Klassenmodul des Objekts, durch das sie ausgelöst werden. Beispiele sind »Beim Laden« oder »Beim Anzeigen« eines Formulars oder auch »Beim Klicken« einer Schaltfläche. Aber wussten Sie, dass Sie auch von anderen Klassenmodulen aus die Ereignisse von externen Objekten wie Formularen oder Steuerelementen implementieren können? Dieser Artikel zeigt, wie das gelingt und welche Vorteile Sie dadurch erlangen.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1611_EreignisseAndererObjekteNutzen.accdb.

Fremde Ereignisse implementieren

Die grundlegende Technik zeigen wir an einem einfachen Beispiel. Dabei wollen wir ein Formular öffnen, die Eingabe des Benutzers abwarten und dann vor demSchließen die eingegebenen Daten im aufrufenden Formular einlesen. Üblicherweise würden Sie von einem Formular aus dazu die folgende Anweisung nutzen:

DoCmd.OpenForm "frmQuelle", WindowMode:=acDialog

Dies hält den Code der aufrufenden Prozedur an. Sie würden das aufgerufene Formular dann beim Klick auf die Schaltfläche OK mit der folgenden Anweisung unsichtbar machen:

Me.Visible = False

Die aufrufende Prozedur würde dies dann als Beenden des Dialog interpretieren, prüfen, ob das Formular zwar unsichtbar, aber noch geöffnet ist, und die gewünschten Daten auslesen, bevor sie das Formular endgültig schließt:

DoCmd.Close acForm, "frmQuelle"

Zu dieser Vorgehensweise gibt es eine elegante Alternative, die es nicht erfordert, das aufgerufene Formular erst noch unsichtbar zu schalten und dann im aufrufenden Formular zu prüfen, ob dieses überhaupt noch vorhanden ist.

Beispielformular

Wir wollen uns diese beiden Vorgehensweisen im Vergleich anschauen. Dazu legen wir ein Formular namens frmZiel an, welches zwei Schaltflächen zum Öffnen zweier Formulare mit jeweils einer der beiden Methoden enthält. Außerdem besitzt dieses Formular zwei Textfelder, in welche die in die geöffneten Formulare eingegebenen Texte beim Schließen übertragen werden sollen (siehe Bild 1).

Formular, das andere Formular aufruft und vor dem Schließen deren Werte einliest

Bild 1: Formular, das andere Formular aufruft und vor dem Schließen deren Werte einliest

Methode 1: Öffnen mit DoCmd.OpenForm

Die erste Schaltfläche namens cmdOpenForm verwendet die folgende Prozedur, um das Formular frmQuelle1 mit der DoCmd.OpenForm-Methode als modalen Dialog zu öffnen:

Private Sub cmdOpenForm_Click()

DoCmd.OpenForm "frmQuelle1", WindowMode:=acDialog

If IstFormularGeoeffnet("frmQuelle1") Then

Me!txtZiel1 = Forms!frmQuelle1!txtEingabe

DoCmd.Close acForm, "frmQuelle1"

End If

End Sub

Nach dem Öffnen gibt der Benutzer einen Text in das einzige Textfeld dieses Formulars ein und klickt auf die Schaltfläche OK, um das Formular wieder zu schließen. Dies lässt die aufrufende Prozedur weiterlaufen, die dann mit der Hilfsfunktion IstFormularGeoeffnet aus dem Modul mdlTools prüft, ob das geöffnete Formular überhaupt noch geöffnet ist. Falls ja, wurde der modale Modus durch Setzen der Eigenschaft Visible auf den Wert True aufgehoben.

In diesem Fall trägt die erste Zeile innerhalb der If...Then-Bedingung den Wert des Textfeldes txtEingabe des Formulars frmQuelle1 in das Textfeld txtZiel1 des Formular frmZiel ein. Die zweite Anweisung schließt das noch geöffnete, aber unsichtbare Formular frmQuelle nun endgültig.

Der Ablauf sieht so wie in Bild 2 aus. Die Schaltfläche cmdOK von frmQuelle1 löst die folgende Ereignisprozedur aus:

Aufruf und Übergabe des Textes von Formular zu Formular

Bild 2: Aufruf und Übergabe des Textes von Formular zu Formular

Private Sub cmdOK_Click()

Me.Visible = False

End Sub

Methode 2: Öffnen per New und Reaktion auf das Schließen per Implementierung von OnClose

Die zweite Methode ist ähnlich aufgebaut, aber verwendet einen etwas anderen Code. Voraussetzung für das Funktionieren ist die Deklaration einer Variablen, mit dem wir das zu öffnende Formular referenzieren können. Die Deklaration muss im Kopf des Klassenmoduls Form_frmZiel erfolgen, damit die Variable nach dem Initialisieren immer noch verfügbar ist. Zusätzlich benötigen wir ein spezielles Schlüsselwort, nämlich WithEvents – mehr dazu gleich:

Dim WithEvents frm As Form

Die zweite Schaltfläche namens cmdNewInstance löst nun beim Anklicken die folgende Ereignisprozedur aus:

Private Sub cmdNewInstance_Click()

Set frm = New Form_frmQuelle2

With frm

.Modal = True

.Visible = True

.OnClose = "[Event Procedure]"

End With

End Sub

Diese erstellt eine neue Instanz des Formulars frmQuelle2, wozu es das New-Schlüsselwort mit dem Klassenmodul dieses Formulars verwendet. Das Ergebnis landet in der Variablen frm. Für diese legen wir nun die Eigenschaft Modal auf den Wert True fest, damit das Formular als modaler Dialog geöffnet wird. Mit Visible = True wird das noch unsichtbare Formular eingeblendet. Danach folgt eine Anweisung, die mit dem zuvor verwendeten Schlüsselwort WithEvents in Zusammenhang steht:

frm.OnClose = "[Event Procedure]"

Dies sorgt dafür, dass wir in dem Klassenmodul, in dem auch die Variable frm deklariert ist, eine Implementierung des Ereignisses OnClose hinterlegen können, die dann ausgelöst wird, wenn das Ereignis Beim Schließen dieses Formulars ausgelöst wird. Im Prinzipiell entspricht dies dem Setzen der Eigenschaft Beim Schließen des Formulars auf den Wert [Ereigniseigenschaft]. Wir sorgen damit und mit der Angabe des Schlüsselworts WithEvents bei der Deklaration der Form-Variablen dafür, dass im aktuellen Modul nach einer Implementierung dieses Ereignisses in Form einer entsprechenden Ereignismethode gesucht wird.

Die Implementierung dieser Ereignisprozedur können wir dann mit wenigen Mausklicks umsetzen (siehe Bild 3):

Anlegen der Implementierung eines Ereignisses

Bild 3: Anlegen der Implementierung eines Ereignisses

Private Sub frm_Close()

Me!txtZiel2 = frm!txtEingabe

End Sub

Das war es schon – wenn Sie nun das Formular frmQuelle2 über die Schaltfläche cmdNewInstance öffnen, dort einen Wert eingeben und das Formular schließen, landet der Wert des Textfeldes des geöffneten Formulars im Textfeld des aufrufenden Formulars.

Formularklasse bei WithEvents nicht vorhanden?

Die Variable, die das zu öffnende Formular aufnehmen soll, können Sie mit dem Typ Form deklarieren. Beim Erstellen der neuen Formular-Instanz müssen Sie allerdings den konkreten Typ angeben, also den Namen des Klassenmoduls des Formulars. Dabei handelt es sich um den Namen des Formulars mit vorangestelltem Form_, hier beispielsweise Form_frmQuelle2. Wenn Sie nun ein neues, leeres Formular etwa namens frmTest anlegen und dieses mit der New-Anweisung erstellen wollen, finden Sie den gewünschten Typ per IntelliSense möglicherweise nicht (siehe Bild 4).

Die gesuchte Klasse Form_frmTest fehlt.

Bild 4: Die gesuchte Klasse Form_frmTest fehlt.

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!