Wenn Sie Ereignisse auslösen möchten, sobald der Benutzer an irgendeine Stelle eines Datensatzes in der Datenblattansicht klickt, müssen Sie theoretisch für jedes einzelne Steuerelement eine entsprechende Ereignisprozedur anlegen. Bei Formularen mit vielen Feldern kann das recht mühselig werden. Daher stellt dieser Beitrag eine Klasse vor, der Sie das Unterformular in der Datenblattansicht übergeben und die Ihnen Ereignisse für die gängigen Ereignisse wie Klick, Doppelklick et cetera bereitstellt. Diese müssen Sie dann nur noch einfach im Hauptformular implementieren.
Die hier vorgestellte Klasse soll folgende Funktionen bieten:
- Erfassung von Klick-, Doppelklick-, Maus auf- und Maus ab-Ereignissen
- Möglichkeit der Implementierung an einer Stelle im Hauptformular, wobei mehrere Informationen übergeben werden sollen – nämlich das Steuerelement, das angeklickt wurde, sowie optional der Primärschlüsselwert des Datensatzes, der angeklickt wurde. Alternativ kann auch der Wert jedes beliebigen anderen Feldes übergeben werden.
- übergabe des markierten Datensatzes auch dann, wenn der Benutzer auf den Datensatzmarkierer klickt
- Optionale Markierung des kompletten Datensatzes beim Anklicken oder Doppelklicken
Im Beispiel aus Bild 1 werten wir beispielsweise den Primärschlüsselwert, die Aktion (also Click, DblClick, MouseUp oder MouseDown) und den Namen des angeklickten Steuerelements aus und zeigen diesen in den drei Textfeldern des Formulars an.
Bild 1: Unterformular mit Ereignisprozeduren im Hauptformular
Um dies zu realisieren, sind, sobald die beiden Klassen clsDatasheetForm und clsDatasheetControl einmal in das Projekt importiert wurden, nur einige wenige Zeilen Code erforderlich.
Dabei deklarieren wir zunächst eine Variable, welche ein Objekt auf Basis der Klasse clsDatasheetForm aufnimmt, und zwar unter dem Namen objDatasheetForm. Außerdem erstellen wir eine Ereignisprozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird. Diese sieht wie in Listing 1 aus (dort finden Sie auch die Deklaration des Objekts objDatasheetForm). Die Prozedur erstellt eine neue Instanz der Klasse clsDatasheetForm und speichert den Verweis auf das neue Objekt in der Variablen objDatasheetForm.
Dim WithEvents objDatasheetForm As clsDataSheetForm Private Sub Form_Load() Set objDatasheetForm = New clsDatasheetForm With objDatasheetForm Set .DatasheetForm = Me!sfmArtikel.Form .PrimaryKey = "ArtikelID" .SelectRowOnClick = True End With End Sub
Listing 1: Ereignisprozedur, welche die Datenblattereignisse zugreifbar macht
Für diese stellt sie nun drei Eigenschaften ein:
- DatasheetForm nimmt einen Verweis auf das Unterformular entgegen, dessen Ereignisse abgegriffen und an das Klassenmodul des Hauptformulars weitergeleitet werden sollen.
- PrimaryKey ist eine optionale Eigenschaft, der Sie den Namen eines Feldes übergeben können, dessen Wert beim Anklicken eines Datensatzes zurückgeliefert werden soll.
- SelectRowOnClick ist eine Boolean-Eigenschaft, mit der Sie festlegen, ob beim Anklicken eines der Steuerelemente des Datensatzes gleich der komplette Datensatz im Unterformular markiert werden soll.
Damit ist die Arbeit noch nicht getan. Schließlich müssen wir noch die Ereignisse definieren, die im Klassenmodul des Hauptformulars ausgelöst werden sollen, wenn ein Benutzer auf ein Feld eines Datensatzes im Unterformular klickt.
Dazu wählen Sie im VBA-Codefenster im linken Kombinationsfeld den Eintrag objDatasheetForm aus und im rechten einen der vier Einträge Click, DblClick, MouseDown oder MouseUp – je nachdem, welches Ereignis Sie implementieren möchten. Der VBA-Editor legt dann automatisch den Prozedurrumpf für das jeweilige Ereignis an – genau so, als ob Sie ein Ereignis eines Formulars oder Steuerelements über das Eigenschaftsfenster der Entwurfsansicht anlegen (s. Bild 2).
Bild 2: Anlegen einer Ereignisprozedur für das Objekt objDatasheetForm
In dieser Liste sehen Sie, dass objDatasheetForm vier Ereignisse anbietet – Click, DblClick, MouseDown und MouseUp.
Wir wollen alle vier implementieren, um Spielmaterial für unsere Beispielanwendung zu haben. So können Sie gut erkennen, wie Sie die Klassen einsetzen können.
Allerdings schauen wir uns nur eine Ereignisprozedur hier an – die übrigen sind alle gleich aufgebaut. Die folgende Prozedur wird ausgelöst, wenn der Benutzer mit der Maus auf eines der Steuerelemente eines Datensatzes im Unterformular klickt – oder auf den Datensatzmarkierer:
Private Sub objDatasheetForm_Click(ctl As Control, _ varPKValue) Me!txtAktion = "Click" If Not ctl Is Nothing Then Me!txtControl = ctl.Name Else Me!txtControl = "Form" End If Me!txtPKWert = varPKValue End Sub
Der Parameter ctl liefert einen Verweis auf das Steu-erelement, das der Benutzer angeklickt hat. Ist ctl leer, bedeutet dies, dass der Benutzer nicht auf ein Steuerelement, sondern auf den Datensatzmarkierer geklickt hat.
Die erste Anweisung trägt den Text Click in das Textfeld txtAktion des Formulars ein. Dass hier das Click-Ereignis ausgelöst wurde, wissen wir natürlich, weil wir uns gerade im objDatasheetForm_Click-Ereignis befinden. Die folgende If…Then-Bedingung prüft, ob ctl nicht den Wert Nothing enthält.
In diesem Fall gibt die Prozedur den Namen des angeklickten Steuerelements im Textfeld txtControl aus. Anderenfalls wissen wir, dass der Benutzer anderswo im Formular geklickt hat, und tragen den Text Form in das Textfeld ein.
Schließlich haben wir dem Objekt für die Eigenschaft PrimaryKey den Wert ArtikelID übergeben. Deshalb liefert die Ereignisprozedur mit dem Parameter varPKValue den Wert dieses Feldes für den angeklickten Datensatz. Auch diesen geben wir aus – diesmal im Textfeld txtPKWert.
Aufgrund der gelieferten Informationen wird deutlich, welche Möglichkeiten sich hier bieten. Sie können etwa über einen Doppelklick auf einen der Datensätze im Unterformular ein Detailformular mit weiteren Informationen zum Datensatz liefern – ohne für jedes einzelne Steuerelement, über das der Benutzer den Datensatz anklicken könnte, eine eigene Ereignisprozedur anlegen zu müssen.
Gut: Im Hintergrund geschieht genau dies. Aber, wie Sie gleich sehen werden, auf dynamische Art und Weise, bei der Sie keine Zeile Code mehr hinzufügen müssen.
Technische Informationen zur Klasse clsDatasheetForm
Die Programmierung der Klassen, die im Hintergrund dafür sorgen, dass die Ereignisse aller Steuerelemente des Datenblattformulars abgefangen und an das Hauptformular weitergegeben werden, scheint auf den ersten Blick recht kompliziert zu sein. Wenn man sich etwas hineinarbeitet, findet man sich allerdings gut zurecht.
Für die bessere übersicht haben wir in Bild 3 ein kleines Schema der beteiligten Elemente aufgezeichnet. Links sind das Formular mit dem Unterformular und einige Steuerelemente.
Bild 3: Schema der Formulare und Klassen
Auf der rechten Seite sehen Sie die Klasse clsData-sheetForm. Darin befindet sich die Auflistung colCon-trols, die wiederum einige Elemente des Typs clsData-sheetControl enthält.
Das Ereignis Beim Laden des Hauptformulars erstellt ein Objekt auf Basis der Klasse clsDatasheetForm. Dabei übergibt dieses einen Verweis auf das Unterformular an das Objekt objDatasheetForm. objDatasheetForm wiederum liest nach dem Zuweisen des Formulars alle Steuerelemente wie Textfelder, Kombinationsfelder, Listenfelder und Kontrollkästchen ein und legt für jedes eine eigene Instanz der Klasse clsDatasheetControl an. Diese landen in der Collection colControls.
Die Instanzen der Klasse clsDatasheetControl referenzieren wiederum jeweils eines der Steuerelemente des Unterformulars.
Dabei implementieren diese Klassen jeweils die Ereignisse Beim Klicken, Beim Doppelklicken, Bei Maustaste ab und Bei Maustaste auf. Das heißt, dass in der Klasse clsDatasheetControl eine Ereignisprozedur ausgelöst wird, wenn der Benutzer auf eines der Steuerelemente klickt.
Die Objekte auf Basis von clsDatasheetControl referenzieren aber nicht nur jeweils das ihnen zugeteilte Steuerelement, sondern auch die Instanz der Klasse clsDatasheetForm, deren Collection colControl sie angehören. Dadurch kann clsDatasheetControl auf die in clsDatasheetForm enthaltenen Prozeduren Click, DblClick, MouseDown und MouseUp zugreifen.
Wenn der Benutzer also auf ein Steuerelement klickt, wird das in der Klasse clsDatasheetControl implementierte Ereignis OnClick ausgelöst. Dieses wiederum ruft die Methode Click der Klasse clsDatasheetForm auf.
Diese löst das Ereignis OnClick der Klasse clsData-sheetForm aus, das seinerseits im Klassenmodul des Hauptformulars implementiert ist. Dort können wir dann das angeklickte Steuerelemente ermitteln und beispielsweise den Primärschlüsselwert des markierten Datensatzes einlesen oder ein weiteres Formular etwa zur Anzeige eines Detaildatensatzes zum angeklickten Datensatz aufrufen.
Aber warum ist das nun so kompliziert Ginge das nicht auch direkt vom Hauptformular aus Natürlich: Sie müssten dort allerdings von Hand für jedes Steuerelement im Unterformular die vier Ereignisse Beim Klicken, Beim Doppelklicken, Bei Maustaste ab und Bei Maustaste auf programmieren.
Bei zehn Steuerelementen sind das schon 40 Ereignisprozeduren, die selbst bei Copy and Paste mit den damit verbundenen Fehlern beim Anpassen eine Menge Arbeit machen. Die beiden Klassen brauchen Sie nur zur Zielanwendung hinzuzufügen und können diese dann mit den oben gezeigten Anweisungen steuern, ohne zig Ereignisprozeduren programmieren zu müssen.
Code der Klasse clsDatasheetForm
Die Klasse clsDatasheetForm deklariert vier Variablen. Diese nehmen den Verweis auf das Unterformular, die Collection zum Speichern der Instanzen der Klasse clsDatasheetControl, den Namen des Primärschlüsselfelds (m_PrimaryKey) und einen Boolean-Wert namens m_SelectRow auf, der festlegt, ob die gesamte Zeile beim Anklicken markiert werden soll:
Private WithEvents m_Form As Access.Form Private colControls As Collection Private m_PrimaryKey As String Private m_SelectRow As Boolean
Für das Erstellen der Objekte auf Basis der Klasse clsDatasheetCollection deklarieren wir außerdem folgende Variable:
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo