TL;DR —
Worksheet_Activatese dispara cuando una hoja pasa a ser la activa (aterrizas en ella);Worksheet_Deactivatese dispara justo cuando la abandonas (antes de que otra hoja tome el relevo). Son los eventos de llegada y salida de una hoja — usaActivatepara refrescar un panel al mirarlo,Deactivatepara comprobar cosas antes de que el usuario siga adelante. La pega que los define: ninguno tiene un argumentoCancel. A diferencia de BeforeClose y BeforeSave, puedes observar un cambio de hoja pero no puedes bloquearlo — lo máximo que puedes hacer es devolver al usuario de un rebote.
' En el módulo de la propia hoja (p. ej. "Dashboard"), NO en ThisWorkbook, NO en un Module.
Private Sub Worksheet_Activate()
Me.Range("A1").Select ' aterriza arriba del todo cada vez que llegas
ActiveWindow.ScrollRow = 1
Me.Calculate ' refresca las cifras de esta hoja al mirarla
End Sub
Private Sub Worksheet_Deactivate()
' Aquí no existe ningún parámetro Cancel — puedes avisar, pero no puedes impedir la salida.
If Me.Range("Signoff").Value = "" Then _
MsgBox "Heads up: you left the Dashboard without signing off.", vbInformation
End Sub
Cambiar de hoja es lo más corriente que hace un usuario, y estos dos eventos permiten que
una hoja reaccione a ello. Worksheet_Activate da vida a «refresca cuando miro esta
pestaña» — recalcular, volver a consultar, desplazarse arriba, proteger o desproteger.
Worksheet_Deactivate da vida a «comprueba antes de que me marche». El truco está en
entender lo que estos eventos no pueden hacer, porque eso es lo que los separa de los
eventos protectores.
Lo que aprenderás
- El modelo mental — eventos de llegada y salida, uno por hoja
- Por qué no hay
Cancel— y el truco del rebote cuando necesitas retener a un usuario - El patrón de refrescar al mirar (y la trampa del «no se ejecutó al abrir»)
Worksheet_Activatea nivel de hoja frente aWorkbook_SheetActivatea nivel de libro- Por qué las hojas de gráfico y la protección con
EnableEventsimportan aquí
El modelo mental: compuertas de llegada y salida
Piensa en cada hoja como en una puerta de embarque de un aeropuerto. Worksheet_Activate
se dispara en el instante en que entras por esta puerta — la hoja acaba de volverse
activa. Worksheet_Deactivate se dispara cuando sales — has hecho clic en otra
pestaña, y esta hoja está a punto de ceder el relevo. Tú no llamas a ninguno; Excel los
lanza al cambiar, en orden: primero el Deactivate de la hoja vieja, luego el Activate
de la nueva.
Ambos son sin parámetros, y ambos viven en el módulo de código de la hoja concreta
— ni ThisWorkbook, ni un Module estándar. Haz doble clic en la hoja (por ejemplo,
Dashboard) bajo «Objetos de Microsoft Excel» y escribe ahí
Private Sub Worksheet_Activate(). Dentro, Me se refiere a esa hoja, y por eso
Me.Calculate y Me.Range(...) se leen con claridad.
La regla que define estos eventos: no hay veto
Esta es la idea que ata todo el grupo. BeforeClose y BeforeSave te entregan cada uno
un indicador Cancel — tu manejador es un puesto de control que puede detener la acción.
Worksheet_Activate y Worksheet_Deactivate no tienen tal parámetro. Mira las
firmas: Worksheet_Deactivate() no recibe nada. No hay ningún Cancel que poner, así que
no hay forma de impedir que el usuario abandone una hoja. Para cuando se ejecuta
Deactivate, la decisión de cambiar ya está tomada.
No es un descuido — cambiar de hoja no es un acto arriesgado e irreversible como cerrar o guardar, así que Excel no ofrece un veto. Pero significa que «no les dejes salir de esta pestaña hasta que B2 esté rellena» no es directamente posible. El truco honesto es un rebote: detecta el problema y vuelve a activar la hoja, protegiéndote contra el nuevo disparo:
Private Sub Worksheet_Deactivate()
If Me.Range("B2").Value = "" Then
Application.EnableEvents = False ' nuestro Activate de abajo no debe encadenar más eventos
Me.Activate ' devuelve al usuario a esta hoja de un tirón
Application.EnableEvents = True
MsgBox "Fill in B2 before leaving this sheet.", vbExclamation
End If
End Sub
Entiende lo que es esto: no un cambio cancelado, sino un cambio completado seguido de
inmediato por un cambio de vuelta. Parpadea, es más pesado que un veto de verdad y vuelve
a disparar eventos — de ahí la protección con Application.EnableEvents, la misma
disciplina usada en Worksheet_Change. Si de verdad
necesitas retener a un usuario hasta que los datos sean válidos, un UserForm mostrado de
forma modal es una herramienta más limpia que pelearse con los eventos de hoja. Conoce el
límite y diseñarás a su alrededor en lugar de perseguir un Cancel que no existe.
El patrón que hace que Activate valga la pena: refrescar al mirar
El mejor uso de Worksheet_Activate es «haz que esta hoja sea correcta en el momento en
que alguien la mira». Una pestaña de resumen se recalcula, un informe vuelve a consultar su
origen, una hoja de entrada de datos se desplaza arriba del todo y desprotege las celdas de
entrada:
Private Sub Worksheet_Activate()
Me.Unprotect Password:="x"
Me.Range("Inputs").Locked = False
Me.Calculate
Application.Goto Me.Range("A1"), Scroll:=True ' coloca A1 arriba a la izquierda al llegar
End Sub
Hay una trampa que genera un goteo constante de preguntas del tipo «mi Activate no se
ejecutó»: la hoja que ya está activa cuando el libro se abre no dispara
Worksheet_Activate — nunca se cambió a ella, sencillamente era la hoja de inicio. Si
necesitas que el refresco ocurra en esa primera hoja al abrir, ejecútalo también desde
Workbook_Open, o llama a tu rutina de refresco desde ambos.
La distinción que hay que acertar: nivel de hoja frente a nivel de libro
Worksheet_Activate en un módulo de hoja se dispara solo para esa hoja. Si quieres
reaccionar cada vez que el usuario aterriza en cualquier hoja, no pegues el mismo
manejador en doce módulos de hoja — usa los eventos a nivel de libro en ThisWorkbook:
' En ThisWorkbook — se dispara para CADA hoja, y te dice cuál mediante 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 es la hoja que se está abandonando.
End Sub
Las versiones de libro te entregan Sh — la hoja implicada — así que un solo manejador
cubre todo el archivo. La regla: una hoja concreta → Worksheet_Activate en esa hoja;
cualquier hoja → Workbook_SheetActivate en ThisWorkbook. Elegir el nivel de hoja
cuando querías el de libro (o al revés) es el motivo más común de que «el evento se dispare
en las pestañas equivocadas».
Dos casos límite más que conviene conocer. Worksheet_Activate es solo para hojas de
cálculo — seleccionar una hoja de gráfico lanza Chart_Activate, no este evento, así
que un manejador que lo espere no se ejecutará nunca, en silencio. Y cualquier escritura o
selección que hagas dentro de estos manejadores puede encadenar más eventos; mantenlos
ligeros y recurre a Application.EnableEvents cuando cambien el libro.
Cómo ayuda ExcelMaster
Los eventos de cambio de hoja parecen sencillos pero esconden criterio de verdad: qué
evento (llegada frente a salida), qué nivel (hoja frente a libro), el hecho de que no
puedes cancelar una salida, la trampa de la primera hoja al abrir, y la protección con
EnableEvents en cualquier rebote.
ExcelMaster
te deja describir el resultado. Di «cada vez que abra la pestaña Dashboard, recalcúlala y
desplázate arriba del todo», y escribe un Worksheet_Activate en la hoja correcta — y si
pides «avísame si me marcho sin firmar», añade un Worksheet_Deactivate que avisa en lugar
de fingir que puede bloquear, porque no puede. Te quedas con el libro y el código; te
ahorras aprender los límites por las malas.
Preguntas frecuentes
¿Cuál es la diferencia entre Worksheet_Activate y Worksheet_Deactivate?
Worksheet_Activate se ejecuta cuando una hoja pasa a ser la activa — acabas de cambiar a
ella. Worksheet_Deactivate se ejecuta al abandonar esa hoja, justo antes de que otra se
vuelva activa. En un cambio, Excel dispara primero el Deactivate de la hoja vieja, luego
el Activate de la nueva. Ambos viven en el módulo de código de la hoja concreta y no
reciben parámetros.
¿Puedo impedir que un usuario abandone una hoja en VBA?
No directamente — Worksheet_Deactivate no tiene parámetro Cancel, así que no puedes
vetar el cambio como Workbook_BeforeClose veta un cierre. El truco es un rebote: en
Deactivate, llama a Me.Activate para devolver al usuario a la hoja (protégelo con
Application.EnableEvents = False … = True), luego muestra un mensaje. Para un bloqueo de
verdad, muestra en su lugar un UserForm modal.
¿Por qué no se ejecuta Worksheet_Activate cuando se abre el libro?
Porque nunca se cambió a la hoja de inicio — ya estaba activa cuando el archivo se abrió,
así que no se dispara ningún evento de activación para ella. Cambiar a otra y volver sí lo
disparará, pero para la hoja inicial en el momento de abrir, ejecuta tu refresco también
desde Workbook_Open.
¿Cómo ejecuto código cuando se selecciona cualquier hoja, no solo una?
Usa los eventos a nivel de libro en ThisWorkbook:
Private Sub Workbook_SheetActivate(ByVal Sh As Object) se dispara para cada hoja y pasa
Sh, la hoja que se activó. Eso es más limpio que copiar un Worksheet_Activate en cada
módulo de hoja.
¿Dónde va el código de Worksheet_Activate?
En el módulo de código de la hoja de cálculo concreta — haz doble clic en esa hoja (p. ej.
Sheet1 o Dashboard) bajo «Objetos de Microsoft Excel» en el Explorador de proyectos y
añade Private Sub Worksheet_Activate(). No se dispara desde un Module estándar; la
versión para todas las hojas, Workbook_SheetActivate, va en ThisWorkbook.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 05/08/2026.
Guías relacionadas: VBA Workbook_BeforeClose · VBA Workbook_BeforeSave · VBA Workbook_Open · VBA Worksheet_SelectionChange · VBA On Error
