Sök…
Syntax
Källmodul :
[Public] Event [identifier]([argument_list])
Handler Module :
Dim|Private|Public WithEvents [identifier] As [type]
Anmärkningar
En händelse kan endast vara
Public
. Modifieraren är valfri eftersom klassmodulmedlemmar (inklusive händelser) implicit ärPublic
standard.En
WithEvents
variabel kan varaPrivate
ellerPublic
, men inteFriend
. Modifieraren är obligatorisk eftersomWithEvents
inte är ett nyckelord som deklarerar en variabel, utan en modifieringsnyckeldel i variabeldeklarationssyntaxen. Därför måste nyckelordetDim
användas om en åtkomstmodifierare inte finns.
Källor och hanterare
Vad är händelser?
VBA är händelsestyrd : VBA-kod körs som svar på händelser som tas upp i värdapplikationen eller värddokumentet - att förstå händelser är grundläggande för att förstå VBA.
API: er exponerar ofta objekt som höjer ett antal händelser som svar på olika tillstånd. Exempelvis höjer ett Excel.Application
objekt en händelse när en ny arbetsbok skapas, öppnas, aktiveras eller stängs. Eller när ett kalkylblad beräknas. Eller strax innan en fil sparas. Eller omedelbart efter. En knapp på ett formulär höjer en Click
när användaren klickar på den, användarformuläret själv höjer en händelse strax efter att den har aktiverats, och en annan strax innan den är stängd.
Ur ett API-perspektiv är händelser förlängningspunkter : klientkoden kan välja att implementera kod som hanterar dessa händelser och köra anpassad kod när dessa händelser avfyras: det är så du kan köra din anpassade kod automatiskt varje gång valet ändras på ett kalkylblad - genom att hantera händelsen som avfyras när markeringen ändras på ett kalkylblad.
Ett objekt som exponerar händelser är en händelsekälla . En metod som hanterar en händelse är en hanterare .
Handlar
VBA-dokumentmoduler (t.ex. ThisDocument
, ThisWorkbook
, Sheet1
, etc.) och UserForm
moduler är klassmoduler som implementerar specialgränssnitt som avslöjar ett antal händelser . Du kan bläddra bland dessa gränssnitt i rullgardinsmenyn till vänster högst upp i kodrutan:
På rullgardinsmenyn till höger listas medlemmarna på gränssnittet som valts i rullgardinsmenyn till vänster:
VBE genererar automatiskt en händelseshanterare-stubb när ett objekt väljs i högerlistan eller navigerar dit om hanteraren finns.
Du kan definiera en modul-scoped WithEvents
variabel i valfri modul:
Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet
Varje WithEvents
deklaration blir tillgänglig att välja från WithEvents
till vänster. När en händelse är vald i rullgardinsmen till höger, genererar VBE en händelseshanterare-stubb uppkallad efter WithEvents
objektet och namnet på händelsen, tillsammans med en understruk:
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
Endast typer som exponerar minst en händelse kan användas med WithEvents
, och WithEvents
deklarationer kan inte tilldelas en referens på plats med det New
nyckelordet. Den här koden är olaglig:
Private WithEvents Foo As New Workbook 'illegal
Referensföremålet måste Set
explicit; i en klassmodul, ett bra ställe att göra det är ofta i Class_Initialize
hanteraren, för då hanterar klassen objektets händelser så länge som instansen existerar.
källor
Varje klassmodul (eller dokumentmodul eller användarform) kan vara en händelsekälla. Använd Event
att definiera signaturen för händelsen i avsnittet för deklarationer i modulen:
Public Event SomethingHappened(ByVal something As String)
Händelsens signatur avgör hur händelsen höjs och hur händelseshanterarna ser ut.
Händelser kan endast tas upp inom den klass de definieras i - klientkod kan bara hantera dem. Händelser RaiseEvent
nyckelordet RaiseEvent
; händelsens argument ges på den punkten:
Public Sub DoSomething()
RaiseEvent SomethingHappened("hello")
End Sub
Utan kod som hanterar händelsen SomethingHappened
kommer körning av DoSomething
proceduren fortfarande att höja händelsen, men ingenting kommer att hända. Förutsatt att händelsekällan är koden ovan i en klass som heter Something
, skulle den här koden i ThisWorkbook
visa en meddelanderuta som säger "hej" när test.DoSomething
kallas:
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
Vidarebefordra data till händelsekällan
Använda parametrar skickade genom referens
En händelse kan definiera en ByRef
parameter som är avsedd att returneras till den som ringer:
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
Om händelsen BeforeSomething
har en hanterare som sätter sin cancel
till True
, då exekvering kommer tillbaka från hanteraren, kommer cancel
att vara True
och AfterSomething
kommer aldrig att höjas.
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
Förutsatt att foo
objektreferensen tilldelas någonstans, när foo.DoSomething
körs, foo.DoSomething
en meddelanderuta att avbryta, och en andra meddelanderuta säger "avbröt inte" bara när Nej valts.
Använda muterbara objekt
Du kan också skicka en kopia av ett muterbart objekt ByVal
och låta hanterare ändra objektets egenskaper; den som ringer kan sedan läsa de modifierade egenskaperna och agera i enlighet därmed.
'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
Kombinerat med Variant
typen kan detta användas för att skapa ganska icke uppenbara sätt att returnera ett värde till den som ringer:
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
Hanteraren ser ut så här:
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