🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Worksheet_Activate et Deactivate dans Excel — exécuter du code au changement de feuille (et pourquoi on ne peut pas annuler un départ)

|

VBA Worksheet_Activate et Deactivate dans Excel — exécuter du code au changement de feuille (et pourquoi on ne peut pas annuler un départ)

TL;DRWorksheet_Activate se déclenche quand une feuille devient la feuille active (vous y arrivez) ; Worksheet_Deactivate se déclenche à l'instant où vous la quittez (avant qu'une autre feuille ne prenne le relais). Ce sont les événements d'arrivée et de départ d'une feuille — utilisez Activate pour actualiser un tableau de bord à l'affichage, Deactivate pour vérifier des choses avant que l'utilisateur ne poursuive. Le hic qui les définit : aucun n'a d'argument Cancel. Contrairement à BeforeClose et BeforeSave, vous pouvez observer un changement de feuille mais vous ne pouvez pas le bloquer — le mieux que vous puissiez faire est de renvoyer l'utilisateur en arrière.

' Dans le module propre à la feuille (p. ex. « Dashboard ») — PAS ThisWorkbook, PAS un Module.
Private Sub Worksheet_Activate()
    Me.Range("A1").Select              ' arriver en haut à chaque fois qu'on entre
    ActiveWindow.ScrollRow = 1
    Me.Calculate                       ' actualiser les chiffres de cette feuille à l'affichage
End Sub

Private Sub Worksheet_Deactivate()
    ' Aucun paramètre Cancel ici — vous pouvez avertir, mais pas empêcher le départ.
    If Me.Range("Signoff").Value = "" Then _
        MsgBox "Heads up: you left the Dashboard without signing off.", vbInformation
End Sub

Changer de feuille est la chose la plus ordinaire qu'un utilisateur fasse, et ces deux événements permettent à une feuille d'y réagir. Worksheet_Activate alimente le « actualiser quand je regarde cet onglet » — recalculer, réinterroger, remonter en haut, protéger ou déprotéger. Worksheet_Deactivate alimente le « vérifier avant que je m'en aille ». L'astuce, c'est de comprendre ce que ces événements ne peuvent pas faire, car c'est ce qui les distingue des événements gardiens.

Ce que vous allez apprendre

  • Le modèle mental — des événements d'arrivée et de départ, un par feuille
  • Pourquoi il n'y a pas de Cancel — et le contournement par renvoi quand vous devez retenir un utilisateur
  • Le motif d'actualisation à l'affichage (et le piège du « ne s'est pas exécuté à l'ouverture »)
  • Worksheet_Activate au niveau feuille vs Workbook_SheetActivate au niveau classeur
  • Pourquoi les feuilles graphiques et la protection EnableEvents comptent toutes deux ici

Le modèle mental : des portes d'arrivée et de départ

Voyez chaque feuille comme une porte d'embarquement dans un aéroport. Worksheet_Activate se déclenche à l'instant où vous entrez par cette porte — la feuille vient de devenir active. Worksheet_Deactivate se déclenche quand vous sortez — vous avez cliqué sur un autre onglet, et cette feuille est sur le point de passer la main. Vous n'appelez jamais ni l'un ni l'autre ; Excel les lève lors du changement, dans l'ordre : d'abord le Deactivate de l'ancienne feuille, puis l'Activate de la nouvelle.

Tous deux sont sans paramètre, et tous deux résident dans le module de code de la feuille concernée — ni ThisWorkbook, ni un Module standard. Double-cliquez sur la feuille (disons Dashboard) sous « Microsoft Excel Objets » et écrivez-y Private Sub Worksheet_Activate(). À l'intérieur, Me désigne cette feuille, ce qui explique pourquoi Me.Calculate et Me.Range(...) se lisent naturellement.

La règle qui définit ces événements : il n'y a pas de veto

C'est l'idée qui relie tout le groupe d'articles. BeforeClose et BeforeSave vous remettent chacun un indicateur Cancel — votre gestionnaire est un point de contrôle qui peut arrêter l'action. Worksheet_Activate et Worksheet_Deactivate n'ont aucun paramètre de ce type. Regardez les signatures : Worksheet_Deactivate() ne prend rien. Il n'y a pas de Cancel à définir, donc aucun moyen d'empêcher l'utilisateur de quitter une feuille. Au moment où Deactivate s'exécute, la décision de changer a déjà été prise.

Ce n'est pas un oubli — un changement de feuille n'est pas un acte risqué et irréversible comme fermer ou enregistrer, Excel n'offre donc pas de veto. Mais cela signifie que « ne pas les laisser quitter cet onglet tant que B2 n'est pas rempli » n'est pas directement possible. Le contournement honnête, c'est le renvoi : détecter le problème et réactiver la feuille, en se prémunissant contre le redéclenchement :

Private Sub Worksheet_Deactivate()
    If Me.Range("B2").Value = "" Then
        Application.EnableEvents = False    ' notre Activate ci-dessous ne doit pas provoquer de cascade
        Me.Activate                         ' ramener l'utilisateur de force sur cette feuille
        Application.EnableEvents = True
        MsgBox "Fill in B2 before leaving this sheet.", vbExclamation
    End If
End Sub

Comprenez bien ce dont il s'agit : non pas un changement annulé, mais un changement achevé aussitôt suivi d'un retour. Ça scintille, c'est plus lourd qu'un vrai veto, et ça redéclenche des événements — d'où la protection Application.EnableEvents, la même discipline qu'employée dans Worksheet_Change. Si vous devez vraiment retenir un utilisateur jusqu'à ce que les données soient valides, un UserForm affiché de façon modale est un outil plus propre que de lutter contre les événements de feuille. Connaissez la limite et vous concevrez en conséquence, au lieu de courir après un Cancel qui n'existe pas.

Le motif qui rend Activate utile : actualiser à l'affichage

Le meilleur usage de Worksheet_Activate, c'est « rendre cette feuille correcte à l'instant où quelqu'un la regarde ». Un onglet de synthèse recalcule, un rapport réinterroge sa source, une feuille de saisie remonte en haut et déprotège les cellules d'entrée :

Private Sub Worksheet_Activate()
    Me.Unprotect Password:="x"
    Me.Range("Inputs").Locked = False
    Me.Calculate
    Application.Goto Me.Range("A1"), Scroll:=True   ' placer A1 en haut à gauche à l'arrivée
End Sub

Il y a un piège qui génère un flot continu de questions du type « mon Activate ne s'est pas exécuté » : la feuille déjà active à l'ouverture du classeur ne déclenche pas Worksheet_Activate — on n'a jamais basculé vers elle, c'était simplement la feuille de départ. Si vous voulez que l'actualisation se produise sur cette première feuille au moment de l'ouverture, exécutez-la aussi depuis Workbook_Open, ou appelez votre routine d'actualisation depuis les deux.

La distinction à bien saisir : niveau feuille vs niveau classeur

Worksheet_Activate dans un module de feuille se déclenche uniquement pour cette feuille-là. Si vous voulez réagir chaque fois que l'utilisateur arrive sur n'importe quelle feuille, ne collez pas le même gestionnaire dans douze modules de feuille — utilisez les événements au niveau classeur, dans ThisWorkbook :

' Dans ThisWorkbook — se déclenche pour CHAQUE feuille, et vous indique laquelle via Sh.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    Application.StatusBar = "You are on: " & Sh.Name
End Sub

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    ' Sh est la feuille que l'on quitte.
End Sub

Les versions au niveau classeur vous remettent Sh — la feuille concernée — si bien qu'un seul gestionnaire couvre tout le fichier. La règle : une feuille précise → Worksheet_Activate dans cette feuille ; n'importe quelle feuille → Workbook_SheetActivate dans ThisWorkbook. Choisir le niveau feuille alors que vous vouliez le niveau classeur (ou l'inverse) est la raison la plus fréquente pour laquelle « l'événement se déclenche sur les mauvais onglets ».

Deux autres cas limites à connaître. Worksheet_Activate ne concerne que les feuilles de calcul — sélectionner une feuille graphique lève Chart_Activate, pas cet événement, si bien qu'un gestionnaire qui l'attend ne s'exécutera jamais, en silence. Et toute écriture ou sélection que vous faites dans ces gestionnaires peut se propager en cascade vers d'autres événements ; gardez-les légers et recourez à Application.EnableEvents quand ils modifient le classeur.

Comment ExcelMaster aide

Les événements de changement de feuille paraissent simples mais cachent un vrai discernement : quel événement (arrivée ou départ), quel niveau (feuille ou classeur), le fait que vous ne pouvez pas annuler un départ, le piège de la première feuille à l'ouverture, et la protection EnableEvents sur tout renvoi.

ExcelMaster vous laisse décrire le résultat. Dites « chaque fois que j'ouvre l'onglet Dashboard, recalcule-le et remonte tout en haut », et il écrit un Worksheet_Activate dans la bonne feuille — et si vous demandez « préviens-moi si je pars sans avoir validé », il ajoute un Worksheet_Deactivate qui avertit au lieu de prétendre pouvoir bloquer, parce qu'il ne le peut pas. Vous gardez le classeur et le code ; vous vous épargnez d'apprendre les limites à la dure.

Questions fréquentes

Quelle est la différence entre Worksheet_Activate et Worksheet_Deactivate ?

Worksheet_Activate s'exécute quand une feuille devient la feuille active — vous venez de basculer dessus. Worksheet_Deactivate s'exécute quand vous quittez cette feuille, juste avant qu'une autre ne devienne active. Lors d'un changement, Excel déclenche d'abord le Deactivate de l'ancienne feuille, puis l'Activate de la nouvelle. Tous deux résident dans le module de code de la feuille concernée et ne prennent aucun paramètre.

Puis-je empêcher un utilisateur de quitter une feuille en VBA ?

Pas directement — Worksheet_Deactivate n'a pas de paramètre Cancel, vous ne pouvez donc pas mettre le changement en veto comme Workbook_BeforeClose met une fermeture en veto. Le contournement, c'est le renvoi : dans Deactivate, appelez Me.Activate pour ramener l'utilisateur sur la feuille (protégez-le avec Application.EnableEvents = False … = True), puis affichez un message. Pour un vrai blocage, affichez plutôt un UserForm modal.

Pourquoi Worksheet_Activate ne s'exécute-t-il pas à l'ouverture du classeur ?

Parce qu'on n'a jamais basculé vers la feuille de départ — elle était déjà active à l'ouverture du fichier, aucun événement d'activation ne se déclenche donc pour elle. En sortir puis y revenir le déclenchera, mais pour la feuille initiale au moment de l'ouverture, exécutez votre actualisation aussi depuis Workbook_Open.

Comment exécuter du code quand n'importe quelle feuille est sélectionnée, pas seulement une ?

Utilisez les événements au niveau classeur, dans ThisWorkbook : Private Sub Workbook_SheetActivate(ByVal Sh As Object) se déclenche pour chaque feuille et passe Sh, la feuille qui a été activée. C'est plus propre que de copier un Worksheet_Activate dans chaque module de feuille.

Où placer le code Worksheet_Activate ?

Dans le module de code de la feuille de calcul concernée — double-cliquez sur cette feuille (p. ex. Sheet1 ou Dashboard) sous « Microsoft Excel Objets » dans l'Explorateur de projets et ajoutez Private Sub Worksheet_Activate(). Il ne se déclenche pas depuis un Module standard ; la version pour toutes les feuilles, Workbook_SheetActivate, se place dans ThisWorkbook.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 05/08/2026.

Guides associés : VBA Workbook_BeforeClose · VBA Workbook_BeforeSave · VBA Workbook_Open · VBA Worksheet_SelectionChange · VBA On Error