Beheersen wanneer een event wordt verwerkt of niet
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
Vragen, suggesties of opmerkingen