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

VBA Worksheet_Activate y Deactivate en Excel — ejecuta código al cambiar de hoja (y por qué no puedes cancelar una salida)

|

VBA Worksheet_Activate y Deactivate en Excel — ejecuta código al cambiar de hoja (y por qué no puedes cancelar una salida)

TL;DRWorksheet_Activate se dispara cuando una hoja pasa a ser la activa (aterrizas en ella); Worksheet_Deactivate se dispara justo cuando la abandonas (antes de que otra hoja tome el relevo). Son los eventos de llegada y salida de una hoja — usa Activate para refrescar un panel al mirarlo, Deactivate para comprobar cosas antes de que el usuario siga adelante. La pega que los define: ninguno tiene un argumento Cancel. 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_Activate a nivel de hoja frente a Workbook_SheetActivate a nivel de libro
  • Por qué las hojas de gráfico y la protección con EnableEvents importan 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