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ślniePublic
.Zmienna
WithEvents
może byćPrivate
lubPublic
, 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 kluczowegoDim
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:
Lista rozwijana po prawej stronie zawiera listę elementów interfejsu wybranych w menu rozwijanym po lewej stronie:
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