TL;DR —
Worksheet_Activatese déclenche quand une feuille devient la feuille active (vous y arrivez) ;Worksheet_Deactivatese 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 — utilisezActivatepour actualiser un tableau de bord à l'affichage,Deactivatepour vérifier des choses avant que l'utilisateur ne poursuive. Le hic qui les définit : aucun n'a d'argumentCancel. 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_Activateau niveau feuille vsWorkbook_SheetActivateau niveau classeur- Pourquoi les feuilles graphiques et la protection
EnableEventscomptent 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
