Astuce VBA : désactiver les événements

Il peut être parfois utile de désactiver les événements ... Imaginez par exemple que l'événement Worksheet_Change (qui se déclenche après une modification dans la feuille) soit utilisé pour modifier la cellule A1 de cette même feuille.

Dans un tel cas, à la première modification d'une cellule de cette feuille, la cellule A1 sera modifiée ... Mais puisque la cellule A1 est modifiée, l'événement est déclenché de nouveau ... La cellule A1 sera donc modifiée une nouvelle fois et redéclenchera encore l'événement ... Et ainsi de suite ... Créant une boucle infinie et un beau plantage d'Excel.

Il faut donc éviter ici de déclencher l'événement lorsque A1 est modifié.


Désactiver tous les événements à l'aide de "Application.EnableEvents"

La solution la plus simple pour exécuter un bout de code sans déclencher d'événements est de placer le code entre ces 2 lignes en utilisant Application.EnableEvents :

Private Sub Worksheet_Change(ByVal Target As Range)

    'Désactivation de tous les événements
    Application.EnableEvents = False
    
    'Exemple d'action
    [A1] = [A1] + 1
    
    'Réactivation de tous les événements
    Application.EnableEvents = True
    
End Sub

Dans ce cas, la modification de A1 ne redéclenchera pas l'événement puisque les événements ont été désactivés avant d'effectuer l'action.

Cette solution est simple à mettre en place mais peut générer parfois des situations problématiques en cas de bug après la désactivation des événements (car ils ne sont pas réactivés automatiquement).

Désactiver un événement à l'aide d'une variable

Cette autre solution plus subtile utilise une variable pour "désactiver" l'événement en le quittant s'il est déjà en cours :

Dim stopEvent

Private Sub Worksheet_Change(ByVal Target As Range)
    
    'Si l'événement est déjà en cours : exit !
    If stopEvent = 1 Then Exit Sub

    'Désactivation de l'événement Worksheet_Change
    stopEvent = 1
    
    'Exemple d'action
    [A1] = [A1] + 1
    
    'Réactivation de l'événement Worksheet_Change
    stopEvent = 0
    
End Sub

Dans ce cas, lorsque l'événement est déclenché, la variable stopEvent ne vaut pas 1, la procédure n'est donc pas quittée prématurément (à la première ligne avec Exit Sub).

Lorsque la cellule A1 sera modifiée, l'événement sera redéclenché mais cette fois-ci, stopEvent vaudra 1 (la procédure s'arrêtera donc à la première ligne).

Notez que vous pouvez également utiliser une variable Static si la variable n'est utile que pour l'événement :

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Static stopEvent
    
    'Si l'événement est déjà en cours : exit !
    If stopEvent = 1 Then Exit Sub

    'Désactivation de l'événement Worksheet_Change
    stopEvent = 1
    
    'Exemple d'action
    [A1] = [A1] + 1
    
    'Réactivation de l'événement Worksheet_Change
    stopEvent = 0
    
End Sub