Szukaj…


Składnia

  • Moduł źródłowy : [Public] Event [identifier]([argument_list])

  • Moduł obsługi : Dim|Private|Public WithEvents [identifier] As [type]

Uwagi

  • Wydarzenie może być tylko Public . Modyfikator jest opcjonalny, ponieważ elementy modułu klasy (w tym zdarzenia) są domyślnie domyślnie Public .

  • Zmienna WithEvents może być Private lub Public , ale nie może być Friend . Modyfikator jest obowiązkowy, ponieważ WithEvents nie jest słowem kluczowym deklarującym zmienną, ale słowem kluczowym modyfikatora składni deklaracji zmiennej. Dlatego też należy użyć słowa kluczowego Dim jeśli nie ma modyfikatora dostępu.

Źródła i handlowcy

Jakie są wydarzenia?

VBA jest sterowany zdarzeniami : kod VBA jest uruchamiany w odpowiedzi na zdarzenia wywołane przez aplikację hosta lub dokument hosta - zrozumienie zdarzeń jest podstawą zrozumienia VBA.

Interfejsy API często ujawniają obiekty, które wywołują szereg zdarzeń w odpowiedzi na różne stany. Na przykład obiekt Excel.Application wywołuje zdarzenie za każdym razem, gdy nowy skoroszyt jest tworzony, otwierany, aktywowany lub zamykany. Lub za każdym razem, gdy obliczany jest arkusz roboczy. Lub tuż przed zapisaniem pliku. Lub natychmiast po. Przycisk w formularzu wywołuje zdarzenie Click , gdy użytkownik je kliknie, sam formularz wywołuje zdarzenie tuż po jego aktywacji, a kolejne tuż przed jego zamknięciem.

Z punktu widzenia interfejsu API zdarzenia są punktami rozszerzenia : kod klienta może wdrożyć kod, który obsługuje te zdarzenia, i wykonać kod niestandardowy przy każdym uruchomieniu tych zdarzeń: w ten sposób można wykonać kod niestandardowy automatycznie za każdym razem, gdy wybór zostanie zmieniony w dowolnym arkuszu - przez obsługę zdarzenia uruchamianego, gdy wybór zmienia się w dowolnym arkuszu.

Obiekt ujawniający zdarzenia jest źródłem zdarzenia . Metodą obsługującą zdarzenie jest moduł obsługi .


Handlery

Moduły dokumentów VBA (np. ThisDocument , ThisWorkbook , Sheet1 itd.) I moduły UserForm moduły klasowe, które implementują specjalne interfejsy, które ujawniają szereg zdarzeń . Możesz przeglądać te interfejsy w menu po lewej stronie u góry okienka kodu:

Ten moduł Workbook implementuje zdarzenia skoroszytu

Lista rozwijana po prawej stronie zawiera listę elementów interfejsu wybranych w menu rozwijanym po lewej stronie:

Moduły arkusza mogą obsługiwać zdarzenia arkusza

VBE automatycznie generuje kod pośrednika obsługi zdarzeń, gdy element jest zaznaczony na liście po prawej stronie, lub nawiguje tam, jeśli moduł obsługi istnieje.

Możesz zdefiniować zmienną WithEvents o WithEvents w dowolnym module:

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

Każda deklaracja WithEvents staje się dostępna do wyboru z menu po lewej stronie. Po wybraniu zdarzenia z menu rozwijanego po prawej stronie VBE generuje WithEvents pośrednika obsługi zdarzeń o nazwie po obiekcie WithEvents i nazwie zdarzenia, połączony znakiem podkreślenia:

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

Tylko typy, które ujawniają co najmniej jedno zdarzenie, mogą być używane z WithEvents , a deklaracjom WithEvents nie można przypisać odwołania na miejscu za pomocą słowa kluczowego New . Ten kod jest nielegalny:

Private WithEvents Foo As New Workbook 'illegal

Odwołanie do obiektu musi być Set jawnie; w module klasy dobrym miejscem do tego jest często Class_Initialize obsługi Class_Initialize , ponieważ wtedy klasa obsługuje zdarzenia tego obiektu tak długo, jak długo istnieje jego instancja.


Źródła

Dowolny moduł klasy (lub moduł dokumentu lub formularz użytkownika) może być źródłem zdarzenia. Użyj słowa kluczowego Event aby zdefiniować podpis zdarzenia, w sekcji deklaracji modułu:

Public Event SomethingHappened(ByVal something As String)

Podpis zdarzenia określa, w jaki sposób zdarzenie jest wywoływane i jak będą wyglądać procedury obsługi zdarzeń.

Zdarzenia mogą być wywoływane tylko w ramach klasy, w której są zdefiniowane - kod klienta może je obsłużyć . Zdarzenia są wywoływane za pomocą słowa kluczowego RaiseEvent ; w tym miejscu podano argumenty zdarzenia:

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

Bez kodu obsługującego zdarzenie SomethingHappened uruchomienie procedury DoSomething będzie nadal wywoływać zdarzenie, ale nic się nie stanie. Zakładając, że źródłem zdarzenia jest powyższy kod w klasie o nazwie Something , ten kod w ThisWorkbook wyświetlałby komunikat „cześć” za każdym razem, gdy test.DoSomething zostanie wywołany:

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

Przekazywanie danych z powrotem do źródła zdarzenia

Korzystanie z parametrów przekazanych przez odniesienie

Zdarzenie może zdefiniować parametr ByRef , który ma zostać zwrócony dzwoniącemu:

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

Jeśli zdarzenie BeforeSomething ma BeforeSomething obsługi, który ustawia parametr cancel na wartość True , wówczas po powrocie wykonania z procedury obsługi cancel będzie miało wartość True a program AfterSomething nigdy nie zostanie zgłoszony.

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

Zakładając, że odniesienie do obiektu foo jest gdzieś przypisane, gdy działa foo.DoSomething , okno komunikatu pyta, czy anulować, a drugie okno komunikatu mówi „nie anulowano” tylko wtedy, gdy foo.DoSomething Nie .


Korzystanie ze zmiennych obiektów

Możesz także przekazać kopię obiektu zmiennego ByVal i pozwolić ByVal obsługi modyfikować właściwości tego obiektu; osoba dzwoniąca może następnie odczytać zmodyfikowane wartości właściwości i podjąć odpowiednie działania.

'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

W połączeniu z typem Variant można tego użyć do stworzenia raczej nieoczywistych sposobów zwracania wartości do osoby dzwoniącej:

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

Program obsługi wyglądałby następująco:

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow