Seit Access 2000 können benutzerdefinierte Ereignisse erstellt werden. Vermutlich jeder Access-Anwendungsentwickler benutzt die eingebauten Access-Ereignisse. Trotzdem werden benutzerdefinierte Ereignisse selten verwendet, obwohl Access-Objekte damit sehr flexibel verbunden werden können.
Ereignisse - Was ist das?
Ereignisse werden in Klassen deklariert und von den Instanzen dieser Klasse ausgelöst.
Ereignisse könnte man mit einem Nachrichtensender vergleichen, der über das Eintreten von bestimmten Zuständen informiert. Es werden allerdings nur jene, die beim Nachrichtensender zuhören, diese Informationen erhalten.
Deklaration
Public Event Newsticker(ByVal Nachricht As String)
Auslösen des Ereignisses
RaiseEvent Newsticker("Es gibt Neuigkeiten!")
Das Berichten von Neuigkeiten ohne Zuhörer ist allerdings kein besonders zweckmäßiger Informationsaustausch. Daher muss man andere Objekte dazu bringen, diesen Dienst in Anspruch zu nehmen.
Event-Handler definieren
Private WithEvents m_Nachrichtensender As Nachrichtendienst
Diese Zeile deklariert die Objektvariable m_Nachrichtensender
mit WithEvents
. Damit wird VBA mitgeteilt, dass im Code auf die Ereignisse der Klasse Nachrichtendienst
reagiert werden soll.
Nach erfolgter Deklaration ist m_Nachrichtensender
im VBA-Editor in der linken oberen Auswahlbox enthalten.
Die Syntax für den Ereignis-Handler ist Ihnen bestimmt bekannt.
Private Sub m_Nachrichtensender_Newsticker(ByVal Nachricht As String) MsgBox Nachricht End Sub
Vergleichen Sie diese Zeilen mit
Private Sub Form_Current() ... End Sub
Im ersten Teil dieser Prozedurbezeichnungen ist die auslösende Objektvariable und im zweiten Teil die Ereignisbezeichnung enthalten.
Diese Prozeduren werde oftmals fälschlicherweise als Ereignis bezeichnet, da man in der Access-Oberfläche die Ereignis-Handler für die eingebauten Prozeduren über die Registerseite "Ereignisse" in den Formulareigenschaften erstellen kann. (Eintrag „Ereignisprozedur“)
Damit die Nachrichten gesendet und empfangen werden können, sind Instanzen der beiden Klassen erforderlich und die Objektvariable m_Nachrichtensender
muss die Referenz zur Instanz der Klasse Nachrichtendienst
.
Mit einem Beispiel wird es anschaulicher ...
Beispiel: Newsticker
Zum Deklarieren von Ereignissen und Ereignis-Handler sind Klassen erforderlich. In einem allgemeinen Modul ist dies nicht möglich. Allerdings müssen Ereignisse nicht zwangsweise in allgemeinen Klassenmodulen deklariert werden. Das kann ebenso in einer Formular-Klasse erfolgen.
Für das Beispiel Newsticker werden wir zwei Formulare einsetzen. In einem Formular werden die Nachrichten erfasst. Im zweiten Formular soll die zuletzt geänderte Nachricht angezeigt werden.
Damit die Nachrichten gespeichert werden können, wird die Tabelle tabNachrichten angelegt.
Zur Eingabe der Daten dient das Endlosformular frmNachrichtenzentrale.
Die zuletzt aktualisierte Nachricht soll im Formular frmNewsticker anzeigt werden.
Nachrichtensender erstellen
Sobald im Formular frmNachrichtenzentrale Änderungen erfolgen, soll ein Ereignis ausgelöst werden, das vom Formular frmNewsticker empfangen werden kann und die geänderte Nachricht übermittelt.
Dafür wird das Ereignis Newsticker im Klassencode des Formulars frmNachrichtenzentrale deklariert und als Reaktion auf das Form-Ereignis BeforeUpdate ausgelöst.
Public Event Newsticker(ByVal Nachricht As String, ByVal NachrichtIstNeu As Boolean) 'Ereignis bei Datensatzänderung auslösen Private Sub Form_BeforeUpdate(Cancel As Integer) RaiseEvent Newsticker(Me.txtNachricht.Value, Me.NewRecord) End Sub
Damit neu erfasste Nachrichten gekennzeichnet werden können, wird der Parameter NachrichtIstNeu
befüllt. Das ermöglicht später die Unterscheidung zw. neuen und aktualisierten Nachrichten.
Nachrichtenempfänger erstellen
Im Formular frmNewsticker muss auf dieses Ereignis reagiert werden. Dafür muss eine Objektvariable von frmNachrichtenzentrale mit WithEvents deklariert werden.
Private WithEvents m_NachrichtenSender As Form_frmNachrichtenzentrale
Anschließend kann der Ereignishandler eingestellt werden.
Private Sub m_NachrichtenSender_Newsticker(ByVal Nachricht As String, ByVal NachrichtIstNeu As Boolean) 'Bezeichnungsfeld befüllen Me.labNachricht.Caption = Nachricht End Sub
m_NachrichtenSender
in der linken oberen Auswahlbox im VBA-Editor auswählen, dann wird der Ereignis-Handler vom Editor automatisch angelegt. Da nur ein Ereignis zur Verfügung steht, ist eine zusätzliche Auswahl in der rechten Box nicht erforderlich.
Sender und Empfänger verbinden
Ein wichtiger Punkt fehlt noch: Die Objektvariable m_NachrichtenSender
wird nicht befüllt. Dafür wird eine Property-Prozedur eingesetzt.
Public Property Set NachrichtenSender(ByRef formRef As Form_frmNachrichtenzentrale) Set m_NachrichtenSender = formRef End Property
Diese Eigenschaft wird beim Aufruf des Newsticker-Formulars über die Schaltfläche in der Nachrichtenzentrale mit der Formular-Referenz versorgt.
Private Sub cmdOpenNewsticker_Click() Const conNewstickerFormName As String = "frmNewsticker" 'Formular öffnen DoCmd.OpenForm conNewstickerFormName 'Objektrefenz übergeben Set Forms(conNewstickerFormName).NachrichtenSender = Me End Sub
Nun ist es Zeit für den ersten Funktionstest. Öffnen Sie die Nachrichtenzentrale und von dort aus den Newsticker über die Schaltfläche. Sobald Sie eine Nachricht ändern oder eine neue anfügen, wird dies im Newsticker angezeigt.
Zu umständlich?
Sie sind der Meinung, dass das mit dem Ereignis zu umständlich ist, da dieses Vorgehen auch direkt über das Ansprechen des Formulars frmNewsticker möglich wäre?
Private Sub Form_BeforeUpdate(Cancel As Integer) Forms("frmNewsticker").Controls("labNachricht").Caption = Me.txtNachricht.Value End Sub
Dann testen Sie einmal, was passiert, wenn das Formular "frmNewsticker" nicht geöffnet ist. Bei dieser Variante müsste jedesmal geprüft werden, ob die Formular-Instanz noch verfügbar ist.
Bei der Ereignis-Variante ist diese Prüfung nicht erforderlich. Dann gibt es eben niemanden der auf das Ereignis reagiert. Dem auslösenden Formular wird das egal sein.
Ein weiterer Vorteil der Ereignis-Variante ist die Möglichkeit, dass nicht nur ein Formular, sondern auch mehrere Formulare auf das Ereignis reagieren können. Damit kann später der Code ohne großen Aufwand erweitert werden.
Erstellen Sie z. B. eine Kopie vom Formular frmNewsticker und ändern sie den Code so ab, dass nur neue Nachrichten angezeigt werden.
Private Sub m_NachrichtenSender_Newsticker(ByVal Nachricht As String, ByVal NachrichtIstNeu As Boolean) 'Bezeichnungsfeld bei neuen Nachrichten befüllen If NachrichtIstNeu Then Me.labNachricht.Caption = Nachricht End If End Sub
Im Formular frmNachrichtenzentrale ergänzen Sie noch den Code, damit beide Newsticker-Formulare geöffnet werden. Nach der Eingabe neuer bzw. Überarbeitung vorhandener Nachrichten sollte erkennbar werden, dass die Verwendung von Ereignissen einen sehr flexiblen Codeaufbau ermöglicht.