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 är Public standard.

  • En WithEvents variabel kan vara Private eller Public , men inte Friend . Modifieraren är obligatorisk eftersom WithEvents inte är ett nyckelord som deklarerar en variabel, utan en modifieringsnyckeldel i variabeldeklarationssyntaxen. Därför måste nyckelordet Dim 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:

DennaWorkbook-modul implementerar arbetsbokshändelser

På rullgardinsmenyn till höger listas medlemmarna på gränssnittet som valts i rullgardinsmenyn till vänster:

Kalkylarkmoduler kan hantera kalkylbladshändelser

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow