Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.
Datenblattereignisse mit Klasse
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 HauptformularUm 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 objDatasheetFormIn 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 Steuerelement, 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 KlassenAuf der rechten Seite sehen Sie die Klasse clsDatasheetForm. Darin befindet sich die Auflistung colControls, die wiederum einige Elemente des Typs clsDatasheetControl 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 clsDatasheetForm 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
Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.