Inleiding
Events zijn een krachtig hulpmiddel bij het programmeren met Excel.
Events maken het mogelijk te reageren op acties van de gebruiker zoals
het bewerken van een cel of het klikken van de knop Afdrukken. Wanneer
een applicatie gebruik maakt van events, dan is het ook vaak nodig de
controle te hebben over het feit of de code in het event wel of niet
wordt uitgevoerd (bijvoorbeeld om te voorkomen dat de event code in een
oneindige lus geraakt of om programmacode de mogelijkheid te geven
acties uit te voeren die het event voorkomt).
Voorbeeld
Er zijn verschillende manieren om event code uit te schakelen. Eén
ervan is middels Application.EnableEvents=False. Daarmee worden helaas
alle application events uitgeschakeld, inclusief event handlers die
invoegtoepassingen mogelijk gebruiken. En als de code vastloopt, dan
blijven de events uitgeschakeld! Een ander nadeel is dat deze optie niet
werkt voor de event code van userforms en event code van controls op
werkbladen.
Een andere methode is middels gebruikmaking van een globale
variabele, wiens waarde wordt getest in elke relevante event subroutine.
Dit wordt echter niet gezien als een goede programmeer gewoonte (hoewel
ik deze regelmatig zelf ook toepas). Hieronder toon ik een meer algemene
benadering die gebruik maakt van een boolean variabele binnen de klasse
module die de event code bevat. Als voorbeeld gebruik ik de Thisworkbook
module, maar in principe kan deze methode in elke willekeurige klasse
module worden toegepast (de Thisworkbook module, de werkblad modules en
modules van userforms zijn in feite klasse modules).
Stel dat voorkomen moet worden dat de gebruiker de werkmap sluit.
Daartoe kan de volgende Workbook_BeforeClose routine worden geschreven
in de Thisworkbook module:
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "You are not allowed to close this file!",
vbInformation + vbOKOnly
Cancel = True
End Sub
Het is echter wel nodig, dat programmacode van de applicatie het
bestand kan sluiten. Hiertoe wordt een publieke variabele gedeclareerd
bovenaan in de Thisworkbook module:
Option Explicit
Public NoEvents As Boolean
En in de BeforeClose event, wordt de waarde van deze variabele
getest:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If NoEvents Then Exit Sub
MsgBox "You are not allowed to close this file!",
vbInformation + vbOKOnly
Cancel = True
End Sub
Deze code moet natuurlijk ook nog in gebruik genomen worden. In ieder
subroutine waarmee het bestand gesloten zou kunnen worden kan dit als
volgt:
Sub CloseMe()
ThisWorkbook.NoEvents = True
ThisWorkbook.Close
End Sub
Natuurlijk moet bNoEvents weer terug op False gezet worden als u deze
heeft gebruikt om bijvoorbeeld een ander event te voorkomen:
ThisWorkbook.NoEvents = False
Het grote voordeel van deze methode boven het gebruik van
Application.EnableEvents=False
is dat als de code wordt gereset, bijvoorbeeld als de gebruiker op End
klikt bij een runtime error, de variabele bNoEvents automatisch op False
gezet wordt en dus de events gewoon blijven werken. Deze methode geeft
ook meer controle over de events, daar één enkel event kan worden
uitgeschakeld, door toevoegen van meerdere variabelen:
Public NoCloseEvent As Boolean
Public NoPrintEvent As Boolean