Hinweis: Diese Technik steht ab der Version Access 2002 zur Verfügung.
Nehmen wir mal an, wir möchten die Anzahl der Änderungen in einem Textfeld-Steuerelement (ggf. sogar in sämtlichen) zählen und diese Anzahl soll über ein Steuerelement im Formular angezeigt werden.
Angenommen unser Eingabe-Steuerelement trägt den Namen Suchname und die Anzahl der Änderungen soll im Steuerelement mit dem Namen txtAnzAenderungen ausgegeben werden.
Eine simple Aufgabe!
Und hier ist dann auch gleich die einfache Lösung:
Private
Sub Suchname_AfterUpdate()
Me.txtAnzAenderungen = Me.txtAnzAenderungen
+ 1
End
Sub
Sollte jedoch diese Funktionalität für mehrer Textfelder (z.B. alle im Formular) benötigt werden, dann muss im Code für jedes einzelne Textfeld eine Event-Prozedur angelegt werden. Das wird sehr unübersichtlich und erzeugt schnell langen Code.
Vielleicht wird diese Funktionalität sogar in anderen Formularen auch noch benötigt.
Und wieder muss der exakt gleiche Code vervielfältigt werden.
Und plötzlich wird unsere einfache Lösung zu einem riesen Konstrukt!
Möchten wir das? Nein! Daher lagern wir die Funktionalität und auch die Events in einem Klassenmodul einfach aus.
Unser selbstdefinierte Klassenmodul mit dem Namen clsEventManager sieht dann so aus:
Option Compare Database
Option Explicit
Dim cTargetControl As
Access.TextBox
Private WithEvents cTxtBox As
Access.TextBox
Private WithEvents cFrm As
Access.Form
Public Function Ini(MyTextBox As
Access.TextBox _
, Optional TargetControl As Access.TextBox) As Boolean
'Hier wird auf das Formular vom Steuerelement
MyTextBox referenziert
Set cFrm = MyTextBox.Parent
'Aktivierung der gewünschten Event-Prozeduren vom Formular
cFrm.AfterUpdate = "[Event Procedure]"
cFrm.OnUndo = "[Event
Procedure]"
'Hier wird auf das Steuerelement MyTextBox
referenziert
Set cTxtBox = MyTextBox
'Aktivierung der gewünschten Event-Prozedur vom Steuerelement
cTxtBox.AfterUpdate = "[Event Procedure]"
Set cTargetControl = TargetControl
Ini = True
End Function
Private Sub cTxtBox_AfterUpdate()
If Not cTargetControl Is Nothing
Then cTargetControl = cTargetControl + 1
End Sub
Private Sub cFrm_AfterUpdate()
'Zähler auf 0 setzen,da alle Änderungen im Datensatz
gerade gespeichert wurden
If Not cTargetControl Is Nothing Then cTargetControl =
0
End Sub
Private Sub cFrm_Undo(Cancel As Integer)
'Zähler auf 0 setzen, weil alle Änderugen im
Datensatz abgebrochen wurden
If Not cTargetControl Is Nothing Then cTargetControl =
0
End
Sub
In der Objektvariable cTargetControl ist das Ziel-Textfeld (txtAnzAenderungen) von unserem Formular gespeichert, im welchen die Anzahl der Änderungen ausgegeben wird.
In der Objektvariable cTextBox ist das Textfeld (Suchname) von unserem Formular in dem die Änderungen gemacht werden gespeichert. Damit diese mit Events belegt werden kann, wurde diese mit Private WithEvents dimensioniert.
In der Objektvariable cFrm ist das Formular in dem die Änderungen gemacht werden gespeichert. Diese wurde auch mit Private WithEvents dimensioniert, da wir auch hier Events benötigen.
Die Aktivierung der Events über die Objektvariablen findet mit dem Eintrag ...= "[Event Procedure]" statt.
Das ist im Prinzip das Entscheidende, um Events auslagern zu können.
In unserem Formular muss jetzt nur noch die Klasse aktiviert (instanziiert) werden und dabei das gewünschte Textfeld (über die Funktion Ini) übergeben werden:
Option
Compare Database
Option
Explicit
Dim EM As
clsEventManager
Private Sub Form_Load()
'Klasse wird
instanziiert und in der Objektvariable EM gespeichert
Set EM = New clsEventManager 'Die betreffenden Steuerelemente werden der Klasse bekannt gemacht
EM.Ini Me.Suchname, Me.txtAnzAenderungen
End
Sub
Wir stellen fest, in unserem Formular werden keine Event-Prozeduren mehr benötigt, die Klasse muss nur einmal instanziiert werden (geschieht hier beim Öffnen des Forms) und alles anderen übernimmt die Klasse inkl. Events!
Möchten wir jetzt mehrere Textfelder mit dieser Funktionalität belegen, dann brauchen wir einfach nur weitere Klassen zu instanziieren. Dies würde dann so aussehen:
Option
Compare Database
Option
Explicit
Dim EM1 As
clsEventManager
Dim EM2 As
clsEventManager
Dim EM3 As
clsEventManager
Private Sub Form_Load()
Set
EM1 = New clsEventManager
EM1.Ini Me.Suchname, Me.txtAnzAenderungen
Set EM2 = New clsEventManager
EM2.Ini Me.Bemerkung, Me.txtAnzAenderungen
Set EM3 = New
clsEventManager
EM3.Ini
Me.Hobbies, Me.txtAnzAenderungen
End Sub
Und wir sind nun sogar in der Lage diese Funktionalität inkl. Events in weiteren Formularen zu integrieren, lediglich die Textfelder müssen angepasst werden. Cool Sache, oder?!
Was ist aber wenn wir diese Funktionalität auf sehr viele Textfelder setzen möchten, ggf. sogar alle Textfelder vom Formular.
Dafür benötigen wir abermals eine elegante Lösung, und hier kommt die Collection ins Spiel.
Das Prinzip ist recht einfach, über eine Schleife finden wir alle Textfelder vom Formular heraus, und instanziieren für jedes eine Klasse. Die instanziiert Klasse wird dann in einer Collection gespeichert, so wie im nachfolgenden Code beschrieben ist:
Option Compare Database
Option Compare Database
Option
Explicit
'Diese Variable
speichert alle Klassenmodule die instanziiert werden
Dim colEM As New Collection
Private Sub Form_Load()
Dim EM As
clsEventManager
Dim ctl As
Access.Control
'Schleife
durch alle Controls im aktuellen Formular
For Each ctl
In Me.Controls
If ctl.ControlType =
acTextBox Then
'Es handelt sich um ein
Textfeld-Steuerelement
Set
EM = New clsEventManager
If
EM.Ini(ctl, Me.txtAnzAenderungen) Then
'Die instanziierte Klasse wird der Collection gespeichert
colEM.Add
Item:=EM, Key:=ctl.Name
End If
Set EM = Nothing 'EM wird nicht mehr benötigt, da in Collection
End If
Next
End subDieser Code kann nun in jedes Formular integriert werden, lediglich das Textfeld
txtAnzAenderungen muss angepasst werden.
Klasse das bis hierhin durchgehalten wurde :-), an dieser Stelle kann die Beispiel-Datei heruntergeladen werden