Suche…


Syntax

  • Quellmodul : [Public] Event [identifier]([argument_list])

  • Handler-Modul : Dim|Private|Public WithEvents [identifier] As [type]

Bemerkungen

  • Eine Veranstaltung kann nur Public . Der Modifizierer ist optional, da die Mitglieder des Klassenmoduls (einschließlich der Ereignisse) standardmäßig implizit Public .

  • Eine WithEvents Variable kann Private oder Public , nicht jedoch Friend . Der Modifikator ist obligatorisch, da WithEvents kein Schlüsselwort ist, das eine Variable deklariert, sondern ein Modifikatorschlüsselwort, das Teil der Variablendeklarationssyntax ist. Daher muss das Dim Schlüsselwort verwendet werden, wenn kein Zugriffsmodifizierer vorhanden ist.

Quellen und Handler

Was sind Ereignisse?

VBA ist ereignisgesteuert : VBA-Code wird als Reaktion auf Ereignisse ausgeführt, die von der Hostanwendung oder dem Hostdokument ausgelöst werden. Das Verständnis von Ereignissen ist für das Verständnis von VBA von grundlegender Bedeutung.

APIs setzen häufig Objekte frei, die eine Reihe von Ereignissen als Reaktion auf verschiedene Zustände auslösen. Ein Excel.Application Objekt löst beispielsweise ein Ereignis aus, wenn eine neue Arbeitsmappe erstellt, geöffnet, aktiviert oder geschlossen wird. Oder wann immer ein Arbeitsblatt berechnet wird. Oder kurz bevor eine Datei gespeichert wird. Oder gleich danach. Eine Schaltfläche in einem Formular löst ein Click Ereignis aus, wenn der Benutzer darauf klickt, das Benutzerformular selbst ein Ereignis auslöst, unmittelbar nachdem es aktiviert wurde, und ein anderes unmittelbar vor dem Schließen.

Aus API-Sicht sind Ereignisse Erweiterungspunkte : Der Clientcode kann auswählen, dass Code implementiert wird, der diese Ereignisse verarbeitet, und benutzerdefinierten Code ausführen, wenn diese Ereignisse ausgelöst werden. Auf diese Weise können Sie Ihren benutzerdefinierten Code bei jeder Änderung der Auswahl in einem Arbeitsblatt automatisch ausführen - durch Behandeln des Ereignisses, das ausgelöst wird, wenn sich die Auswahl in einem Arbeitsblatt ändert.

Ein Objekt, das Ereignisse verfügbar macht, ist eine Ereignisquelle . Eine Methode, die ein Ereignis behandelt, ist ein Handler .


Handler

VBA-Dokumentmodule (z. B. ThisDocument , ThisWorkbook , Sheet1 usw.) und UserForm Module sind Klassenmodule , die spezielle Schnittstellen implementieren , die eine Reihe von Ereignissen UserForm . Sie können diese Schnittstellen in der linken Dropdown-Liste oben im Codefenster durchsuchen:

Dieses Arbeitsbuchmodul implementiert Arbeitsmappenereignisse

In der rechten Dropdownliste werden die Mitglieder der in der linken Dropdownliste ausgewählten Benutzeroberfläche aufgelistet:

Arbeitsblattmodule können Arbeitsblattereignisse verarbeiten

Die VBE generiert automatisch einen Event-Handler-Stub, wenn ein Element in der rechten Liste ausgewählt wird, oder navigiert dorthin, wenn der Handler vorhanden ist.

In jedem Modul können Sie eine WithEvents Variable mit WithEvents definieren:

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

Jede WithEvents Deklaration kann aus der Dropdown-Liste auf der linken Seite ausgewählt werden. Wenn ein Ereignis in der rechten Dropdown-Liste ausgewählt wird, generiert die VBE einen Ereignishandler-Stub, der nach dem WithEvents Objekt und dem Namen des Ereignisses benannt ist, verbunden mit einem Unterstrich:

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

Private Sub Foo_Open()

End Sub

Private Sub Bar_SelectionChange(ByVal Target As Range)

End Sub

Mit WithEvents können nur Typen verwendet werden, die mindestens ein Ereignis WithEvents . Mit WithEvents Deklarationen kann vor Ort keine Referenz mit dem Schlüsselwort New zugewiesen werden. Dieser Code ist illegal:

Private WithEvents Foo As New Workbook 'illegal

Die Objektreferenz muss Set explizit; In einem Klassenmodul befindet sich ein guter Ort dafür häufig im Class_Initialize Handler, da die Klasse dann die Ereignisse dieses Objekts so lange behandelt, wie ihre Instanz vorhanden ist.


Quellen

Jedes Klassenmodul (oder Dokumentmodul oder Benutzerformular) kann eine Ereignisquelle sein. Verwenden Sie das Event , um die Signatur für das Ereignis im Deklarationsabschnitt des Moduls zu definieren:

Public Event SomethingHappened(ByVal something As String)

Die Signatur des Ereignisses bestimmt, wie das Ereignis ausgelöst wird und wie die Ereignishandler aussehen.

Ereignisse können nur innerhalb der Klasse ausgelöst werden , in der sie definiert sind - Client-Code kann sie nur verarbeiten . Ereignisse werden mit dem Schlüsselwort RaiseEvent . Die Argumente des Ereignisses werden an dieser Stelle bereitgestellt:

Public Sub DoSomething()
    RaiseEvent SomethingHappened("hello")
End Sub

Ohne Code, der das SomethingHappened Ereignis behandelt, wird das Ausführen der DoSomething Prozedur immer noch das Ereignis DoSomething , aber nichts passiert. Angenommen, die Ereignisquelle ist der obige Code in einer Klasse mit dem Namen Something . Dieser Code in ThisWorkbook zeigt ein Meldungsfeld mit der Aufschrift "Hallo" an, wenn test.DoSomething aufgerufen wird:

Private WithEvents test As Something

Private Sub Workbook_Open()
    Set test = New Something
    test.DoSomething
End Sub

Private Sub test_SomethingHappened(ByVal bar As String)
'this procedure runs whenever 'test' raises the 'SomethingHappened' event
    MsgBox bar
End Sub

Zurückgeben von Daten an die Ereignisquelle

Verwenden von Parametern, die als Referenz übergeben werden

Ein Ereignis kann einen ByRef Parameter definieren, der an den Aufrufer zurückgegeben werden soll:

Public Event BeforeSomething(ByRef cancel As Boolean)
Public Event AfterSomething()

Public Sub DoSomething()
    Dim cancel As Boolean
    RaiseEvent BeforeSomething(cancel)
    If cancel Then Exit Sub

    'todo: actually do something

    RaiseEvent AfterSomething
End Sub

Wenn das BeforeSomething Ereignis hat einen Handler, der seine Sets cancel Parameter auf True , dann , wenn die Ausführung kehrt aus dem Handler, cancel wird True und AfterSomething nie angehoben werden.

Private WithEvents foo As Something

Private Sub foo_BeforeSomething(ByRef cancel As Boolean)
    cancel = MsgBox("Cancel?", vbYesNo) = vbYes
End Sub

Private Sub foo_AfterSomething()
    MsgBox "Didn't cancel!"
End Sub

Angenommen, die foo Objektreferenz wird irgendwo zugewiesen, wenn foo.DoSomething , werden Sie in einem Meldungsfeld gefragt, ob Sie den foo.DoSomething abbrechen foo.DoSomething , und in einem zweiten Meldungsfeld wird die Meldung "nicht abgebrochen" nur foo.DoSomething , wenn Nein ausgewählt wurde.


Verwenden von veränderlichen Objekten

Sie können auch eine Kopie des veränderlichen Objekts ByVal und Handler die Eigenschaften dieses Objekts ändern lassen. Der Aufrufer kann dann die geänderten Eigenschaftswerte lesen und entsprechend handeln.

'class module ReturnBoolean
Option Explicit
Private encapsulated As Boolean

Public Property Get ReturnValue() As Boolean
'Attribute ReturnValue.VB_UserMemId = 0
    ReturnValue = encapsulated
End Property

Public Property Let ReturnValue(ByVal value As Boolean)
    encapsulated = value
End Property

Kombiniert mit dem Variant Typ kann dies verwendet werden, um auf nicht offensichtliche Weise einen Wert an den Aufrufer zurückzugeben:

Public Event SomeEvent(ByVal foo As Variant)

Public Sub DoSomething()
    Dim result As ReturnBoolean
    result = New ReturnBoolean

    RaiseEvent SomeEvent(result)

    If result Then ' If result.ReturnValue Then
        'handler changed the value to True
    Else
        'handler didn't modify the value
    End If
End Sub

Der Handler würde so aussehen:

Private Sub source_SomeEvent(ByVal foo As Variant) 'foo is actually a ReturnBoolean object
    foo = True 'True is actually assigned to foo.ReturnValue, the class' default member
End Sub


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow