Ricerca…
Sintassi
Modulo sorgente :
[Public] Event [identifier]([argument_list])
Modulo gestore :
Dim|Private|Public WithEvents [identifier] As [type]
Osservazioni
Un evento può essere solo
Public
. Il modificatore è facoltativo perché i membri del modulo di classe (inclusi gli eventi) sono implicitamentePublic
per impostazione predefinita.Una variabile
WithEvents
può esserePrivate
oPublic
, ma nonFriend
. Il modificatore è obbligatorio perchéWithEvents
non è una parola chiave che dichiara una variabile, ma una parte parola chiave modificatore della sintassi della dichiarazione di variabile. Quindi la parola chiaveDim
deve essere utilizzata se non è presente un modificatore di accesso.
Fonti e gestori
Quali sono gli eventi?
VBA è basato sugli eventi : il codice VBA viene eseguito in risposta agli eventi generati dall'applicazione host o dal documento host: la comprensione degli eventi è fondamentale per comprendere VBA.
Le API espongono spesso oggetti che generano un numero di eventi in risposta a vari stati. Ad esempio, un oggetto Excel.Application
genera un evento ogni volta che viene creata, aperta, attivata o chiusa una nuova cartella di lavoro. O ogni volta che viene calcolato un foglio di lavoro. O poco prima che un file venga salvato. O subito dopo. Un pulsante su un modulo solleva un evento Click
quando l'utente fa clic su di esso, lo stesso modulo utente solleva un evento subito dopo l'attivazione e un altro appena prima che venga chiuso.
Dal punto di vista dell'API, gli eventi sono punti di estensione : il codice client può scegliere di implementare il codice che gestisce questi eventi ed eseguire codice personalizzato ogni volta che questi eventi vengono generati: è così che è possibile eseguire automaticamente il codice personalizzato ogni volta che la selezione cambia su qualsiasi foglio di lavoro - gestendo l'evento che viene generato quando la selezione cambia in qualsiasi foglio di lavoro.
Un oggetto che espone eventi è una fonte di eventi . Un metodo che gestisce un evento è un gestore .
handlers
I moduli del documento VBA (ad es. ThisDocument
, ThisWorkbook
, Sheet1
, ecc.) ThisWorkbook
moduli UserForm
sono moduli di classe che implementano interfacce speciali che espongono un numero di eventi . Puoi sfogliare queste interfacce nel menu a discesa a sinistra nella parte superiore del riquadro del codice:
Il menu a discesa a destra elenca i membri dell'interfaccia selezionata nel menu a discesa a sinistra:
Il VBE genera automaticamente uno stub del gestore di eventi quando un elemento è selezionato nell'elenco di destra, oppure naviga lì se il gestore esiste.
È possibile definire una variabile WithEvents
ambito modulo in qualsiasi modulo:
Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet
Ogni dichiarazione WithEvents
diventa disponibile per la selezione dal menu a discesa sul lato sinistro. Quando un evento è selezionato nel menu a discesa a destra, il VBE genera uno stub del gestore di eventi chiamato dopo l'oggetto WithEvents
e il nome dell'evento, unito a un trattino basso:
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
Solo i tipi che espongono almeno un evento possono essere utilizzati con WithEvents
e alle dichiarazioni WithEvents
non può essere assegnato un riferimento sul posto con la parola chiave New
. Questo codice è illegale:
Private WithEvents Foo As New Workbook 'illegal
Il riferimento all'oggetto deve essere Set
esplicito; in un modulo di classe, un buon posto per farlo è spesso nel gestore Class_Initialize
, perché la classe gestisce gli eventi di quell'oggetto per tutto il tempo in cui esiste l'istanza.
fonti
Qualsiasi modulo di classe (o modulo documento o modulo utente) può essere una fonte di eventi. Utilizzare la parola chiave Event
per definire la firma per l'evento, nella sezione dichiarazioni del modulo:
Public Event SomethingHappened(ByVal something As String)
La firma dell'evento determina come viene generato l'evento e come saranno i gestori di eventi.
Gli eventi possono essere raccolti solo all'interno della classe in cui sono definiti: il codice client può gestirli solo. Gli eventi vengono RaiseEvent
con la parola chiave RaiseEvent
; gli argomenti dell'evento sono forniti in quel punto:
Public Sub DoSomething()
RaiseEvent SomethingHappened("hello")
End Sub
Senza il codice che gestisce l'evento SomethingHappened
, l'esecuzione della procedura DoSomething
aumenterà comunque l'evento, ma non accadrà nulla. Supponendo che la sorgente dell'evento sia il codice sopra riportato in una classe chiamata Something
, questo codice in ThisWorkbook
mostrerà una finestra di messaggio che dice "ciao" ogni volta test.DoSomething
viene chiamato il test.DoSomething
:
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
Trasmissione dei dati alla fonte dell'evento
Utilizzo dei parametri passati per riferimento
Un evento può definire un parametro ByRef
che deve essere restituito al chiamante:
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
Se l'evento BeforeSomething
ha un gestore che imposta il parametro cancel
su True
, quando l'esecuzione viene restituita dal gestore, l' cancel
sarà True
e AfterSomething
non verrà mai generato.
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
Supponendo che il riferimento all'oggetto foo
sia assegnato da qualche parte, quando foo.DoSomething
eseguito foo.DoSomething
, una finestra di messaggio richiede se annullare, e una seconda casella di messaggio dice "non annullato" solo quando No è stato selezionato.
Usando oggetti mutabili
È anche possibile passare una copia di un oggetto mutabile ByVal
e consentire ai gestori di modificare le proprietà di quell'oggetto; il chiamante può quindi leggere i valori delle proprietà modificate e agire di conseguenza.
'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
Combinato con il tipo Variant
, questo può essere usato per creare modi non ovvi per restituire un valore al chiamante:
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
Il gestore sarebbe simile a questo:
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