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.

Event-Objekt auswählen

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.

Tabelle tabNachricht

Zur Eingabe der Daten dient das Endlosformular frmNachrichtenzentrale.

Formular Nachrichtenzentrale

Die zuletzt aktualisierte Nachricht soll im Formular frmNewsticker anzeigt werden.

Formular Newsticker

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.

{jd_file file==100}