Home > Artikel > Ausgabe 4/2017 > Alle Ereignisse im Hauptformular

Alle Ereignisse im Hauptformular

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).

Wenn Sie mit Haupt- und Unterformularen arbeiten und Ereignisprozeduren sowohl in der Code behind-Klasse des Haupt- und des Unterformulars angelegt haben, kann es manchmal unübersichtlich werden. Das ist vor allem dann der Fall, wenn Ereignisse im Unterformular sich auf die Abläufe im Hauptformular auswirken. Dieser Artikel zeigt, wie Sie die Ereignisse, die durch ein Unterformular ausgelöst werden, im Klassenmodul des Hauptformulars implementieren. Damit können Sie Ereignisse, Objekte und Variablen in nur noch einem Modul nutzen.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1704_EreignisseImHauptformular.accdb.

Beispielkonfiguration

In unserem Beispiel wollen wir die Einträge einer Tabelle namens tblArtikel in einem Unterformular anzeigen. Das Hauptformular soll Steuer­elemente zum Hinzufügen eines neuen Artikels, zum Löschen eines Artikels oder zum Bearbeiten eines bestehenden Artikels enthalten. Dazu ist es aus Gründen der Ergonomie notwendig, dass die Schaltflächen zum Anzeigen eines Datensatzes zum Bearbeiten und zum Löschen des aktuell markierten Datensatzes nur aktiviert sind, wenn der Benutzer auch einen Datensatz im Datenblatt markiert hat.

Das Unterformular versehen wir daher mit der Tabelle tblArtikel als Datenherkunft und ziehen alle Felder dieser Tabelle aus der Feldliste in den Detailbereich des Entwurfs. Außerdem stellen wir die Eigenschaft Standardansicht des Formulars auf Datenblatt ein (siehe Bild 1). Speichern Sie das Unterformular unter dem Namen sfmArtikeluebersicht und schließen Sie es. Dann legen Sie ein neues Formular namens frmArtikeluebersicht an und ziehen das Unterformular sfmArtikeluebersicht aus dem Navigationsbereich in den Detailbereich des neuen Formulars.

Entwurf des Unterformulars mit der Datenblattansicht

Bild 1: Entwurf des Unterformulars mit der Datenblattansicht

Außerdem fügen Sie noch drei Schaltflächen namens cmdNeu, cmdBearbeiten und cmdLoeschen zu diesem Hauptformular hinzu. Ordnen Sie die Steuer­elemente wie in Bild 2 an und stellen Sie außerdem die beiden Eigenschaften Horizontaler Anker und Vertikaler Anker des Unterformular-Steuerelements aus Beide ein. Für die unter diesem Steuer­element befindlichen Schaltflächen müssen Sie entsprechend Horizontaler Anker auf Unten einstellen, damit sich das Unterformular beim Vergrößern des Hauptformulars nicht über die Schaltflächen legt.

Haupt- und Unterformular in der Entwurfsansicht

Bild 2: Haupt- und Unterformular in der Entwurfsansicht

Da das Hauptformular selbst keine Daten anzeigt, können Sie dessen Eigenschaften Navigationsschaltflächen, Datensatzmarkierer, Trennlinien und Bildlaufleisten auf Nein einstellen sowie Automatisch zentrieren auf Ja.

Nun wollen wir dafür sorgen, dass die beiden Schaltflächen cmdBearbeiten und cmdLoeschen deaktiviert werden, wenn der Datensatzzeiger im Unterformular nicht auf einen Datensatz zeigt – also beispielsweise der neue Datensatz markiert ist wie in Bild 3.

Die beiden Schaltflächen cmdBearbeiten und cmdLoeschen sollen deaktiviert sein, wenn im Unterformular kein Datensatz markiert ist.

Bild 3: Die beiden Schaltflächen cmdBearbeiten und cmdLoeschen sollen deaktiviert sein, wenn im Unterformular kein Datensatz markiert ist.

Klassisch erledigen wir das wie folgt: Wir nutzen das Ereignis Beim Anzeigen des Unterformulars, indem wir die entsprechende Eigenschaft den Wert [Ereignisprozedur] auswählen und dann auf die Schaltfläche mit den drei Punkten rechts von der Eigenschaft klicken. Dann ergänzen wir die im VBA-Editor angelegte Ereignisprozedur wie in Listing 1. Das Ereignis wird jeweils beim Verschieben des Datensatzzeigers auf einen der Datensätze ausgelöst, auch beim Verschieben auf den leeren, neuen Datensatz.

Private Sub Form_Current()

     Me.Parent!cmdBearbeiten.Enabled = Not IsNull(Me!ArtikelID)

     Me.Parent!cmdLoeschen.Enabled = Not IsNull(Me!ArtikelID)

End Sub

Listing 1: Diese Prozedur aktiviert und deaktiviert die Schaltflächen.

In der Ereignisprozedur stellen wir die Eigenschaft Enabled der beiden Schaltflächen jeweils auf den Wert des Ausdrucks Not IsNull(Me!ArtikelID) ein. Me!Artikel hat immer einen Wert, wenn der Datensatzzeiger auf einen Datensatz zeigt, im Falle des leeren, neuen Datensatzes liefert dies jedoch den Wert Null. In diesem Fall werden die beiden Schaltflächen dann wie in der Abbildung deaktiviert. Beim Wechsel zu einem anderen Datensatz aktiviert die Ereignisprozedur die beiden Schaltflächen jedoch wieder.

Beim Einstellen der Eigenschaft Enabled der beiden Schaltflächen müssen wir diese über die Parent-Eigenschaft des Formulars, von dem aus die Ereignisprozedur ausgelöst wird, referenzieren. Das Problem hierbei ist die wechselseitige Abhängigkeit von Haupt- und Unterformular. Das Hauptformular ist vom Unterformular abhängig, weil es diese im Unterformularsteuerelement anzeigt. Das Unterformular ist wiederum vom Hauptformular abhängig, weil es auf über die Parent-Eigenschaft auf dessen Steuer­elemente zugreift. Wenn wir das Unterformular nun wiederverwenden wollen, etwa in einem anderen Hauptformular, dass die beiden Schaltflächen cmdBearbeiten und cmdLoeschen nicht enthält, lösen wir beim Versuch des Zugriffs über die Ereignisprozedur einen Fehler aus, weil die Steuer­elemente fehlen.

Ereignisprozedur in das Hauptformular verschieben

Und nun kommt der Trick: Wir implementieren das Ereignis Beim Anzeigen des Unterformulars nun nicht mehr im Klassenmodul des Unterformulars, sondern im Klassenmodul des Hauptformulars. Wie soll das gehen? Beim Füllen der Ereigniseigenschaft Beim Anzeigen mit [Ereignisprozedur] legt Access automatisch eine Prozedur wie Form_Current an. Form ist dabei eine implizit deklarierte Variable für die Implementierung der Klasse des aktuelle Formulars. Sie könnten über Form auch auf die enthaltenen Steuerelemente zugreifen:

MsgBox Form.ArtikelID

Was ist nun, wenn wir die ganzen Ereignisprozeduren nicht nur im Klassenmodul des Formulars selbst implementieren können, sondern auch in den Klassenmodulen anderer Formulare oder auch in reinen Klassenmodulen? Und wie würde das aussehen?

Ganz einfach: Dazu müssen wir statt der implizit deklarierten Objektvariablen Form einfach eine explizit deklarierte Objektvariable vorsehen. Diese deklarieren wir dann beispielsweise im Klassenmodul des Hauptformulars. Dabei verwenden wir als Datentyp der Variablen das Präfix Form_ und den Namen des Formulars, hier also etwa Form_sfmArtikeluebersicht.

Um dies zu erledigen, benötigen wir erst einmal ein Klassenmodul für das Hauptformular frmArtikeluebersicht, welches wir, wenn wir nicht gleich eine Ereignisprozedur anlegen möchten, über das Einstellen der Eigenschaft Enthält Modul auf den Wert Ja erstellen. Nach dem Wechsel zum VBA-Editor, etwa über die Tastenkombination Alt + F11, finden Sie dort im Projekt-Explorer neben Form_sfmArtikeluebersicht die noch leere Klasse Form_frmArtikeluebersicht (Achtung: Der Unterschied besteht lediglich im Präfix der Formularbezeichnung!). Hier legen wir nun die Objektvariable mit der Bezeichnung sfm und dem Typ Form an (siehe Bild 4).

Deklarieren eines Objekts der Klasse Form_sfmArtikeluebersicht

Bild 4: Deklarieren eines Objekts der Klasse Form_sfmArtikeluebersicht

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!