7. Eventos de Hoja y Libro
En esta lección aprenderás a:
- Entender qué es un evento en VBA y para qué sirve.
- Usar
Worksheet_Changepara reaccionar cuando el usuario edita una celda. - Usar
Workbook_Openpara ejecutar código al abrir el archivo. - Prevenir la recursividad con
Application.EnableEvents.
¿Qué es un evento?
Un evento es una acción del usuario o del sistema (editar una celda, abrir el libro, hacer clic) que Excel detecta y a la que VBA puede responder automáticamente, sin necesidad de llamar el procedimiento manualmente.
Vista tipo Excel: la primera fila muestra las letras de columna; la primera columna muestra los números de fila. En las celdas con fórmula (=...), cada referencia lleva un color distinto. Clic en la referencia: resalta solo esa celda. Clic en el resto de la celda (por ejemplo el = o los operadores): resalta todas las celdas citadas. Repetir el mismo gesto sobre lo ya resaltado lo oculta.
Eventos más usadosResumen
Para abrir el módulo de una hoja, haz doble clic en su nombre en el Explorador de proyectos del editor VBA.
| A | B | C | |
|---|---|---|---|
| 1 | Evento | Cuándo se dispara | Dónde se escribe |
| 2 | Worksheet_Change | Al cambiar el valor de cualquier celda de la hoja | Módulo de la hoja (ej. Hoja1) |
| 3 | Worksheet_Activate | Al activar (hacer clic en) esa hoja | Módulo de la hoja |
| 4 | Workbook_Open | Al abrir el libro de Excel | ThisWorkbook |
| 5 | Workbook_BeforeSave | Antes de guardar el libro | ThisWorkbook |
| 6 | Workbook_BeforeClose | Antes de cerrar el libro | ThisWorkbook |
Worksheet_Change — reaccionar al editar celdas
Este evento recibe el parámetro Target que representa la celda modificada. Se escribe en el módulo de la hoja (doble clic en Hoja1 en el explorador):
Target.Column devuelve el número de columna (1=A, 2=B…). Target.Address devuelve la dirección como texto (ej. "$B$5").
Prevenir recursividad con EnableEvents
Si el evento modifica una celda, eso puede disparar de nuevo el mismo evento, creando un bucle infinito. La solución: desactivar los eventos mientras se ejecuta el código:
Siempre restaura Application.EnableEvents = True al final. De lo contrario ningún evento funcionará durante el resto de la sesión.
Workbook_Open — código al abrir el archivo
Se escribe en el módulo de ThisWorkbook (doble clic en ThisWorkbook en el explorador):
Environ("USERNAME") lee el nombre del usuario de Windows.
Practica en Excel
Abre Excel (o copia los datos con el botón de la tabla), sigue los pasos y comprueba el resultado en tu hoja.
- Abre el editor VBA, haz doble clic en "Hoja1" en el Explorador de proyectos.
- Elige "Worksheet" y "Change" en los desplegables superiores del módulo.
- Escribe el código de Worksheet_Change para colorear negativos en columna B.
- Vuelve a Excel, escribe un número negativo en B3 y verifica el color rojo.
- Haz doble clic en "ThisWorkbook" y escribe el evento Workbook_Open con un mensaje de bienvenida.
- Guarda el archivo como .xlsm (habilitado para macros) y ciérralo. Al reabrirlo, el mensaje debe aparecer.
Ejercicios prácticos
15 ejercicios organizados por dificultad para consolidar el manejo de eventos VBA.
Básico
1. Saludo al abrir
Escribe en ThisWorkbook un evento Workbook_Open que muestre el mensaje "¡Bienvenido! Hoy es: " seguido de la fecha actual (Date).
Ver solución
2. Detectar cambio en celda A1
En el módulo de Hoja1, escribe un Worksheet_Change que muestre un MsgBox solo cuando se edite la celda A1.
Ver solución
3. Activar hoja con mensaje
Escribe un evento Worksheet_Activate que muestre el nombre de la hoja activa cuando el usuario haga clic en ella.
Ver solución
4. Timestamp automático
Cuando se edite cualquier celda de la columna B, escribe en la columna C de la misma fila la hora actual (Now).
Ver solución
5. Aviso antes de guardar
En ThisWorkbook, escribe un evento Workbook_BeforeSave que muestre "¿Seguro que quieres guardar?" antes de proceder.
Ver solución
Intermedio
6. Colorear celda editada
Cuando se edite cualquier celda de la columna A, colorea el fondo de esa celda en amarillo (RGB(255, 255, 0)). Usa EnableEvents para evitar recursividad.
Ver solución
7. Validar celda no vacía
Si el usuario deja vacía la celda B2, cancela el cambio restaurando el valor anterior y muestra un aviso. (Pista: guarda el valor anterior en una variable de módulo antes del cambio.)
Ver solución
8. Convertir a mayúsculas automáticamente
Cada vez que el usuario edite una celda de la columna C, convierte automáticamente el texto a mayúsculas usando UCase.
Ver solución
9. Redirigir al usuario al abrir
En Workbook_Open, activa la hoja llamada "Panel" y selecciona la celda A1. Si la hoja no existe, muestra un aviso y no hagas nada.
Ver solución
10. Contador de cambios
Declara una variable de módulo contadorCambios. Con cada edición de cualquier celda, incrementa el contador y muestra en la celda F1 cuántas veces se ha editado la hoja.
Ver solución
Avanzado
11. Rango de intersección
Usa Application.Intersect para detectar si el usuario editó alguna celda dentro del rango B2:D10. Solo en ese caso, muestra en una MsgBox la dirección y el nuevo valor.
Ver solución
12. Bloquear cierre sin contraseña
En Workbook_BeforeClose, pide al usuario una contraseña con InputBox. Si no escribe "admin123", cancela el cierre poniendo Cancel = True.
Ver solución
13. Evento en múltiples hojas
Desde ThisWorkbook, usa el evento Workbook_SheetChange (que se dispara en cualquier hoja) para registrar en la hoja "Log" (créala) cada cambio: fila, columna, hoja y valor nuevo.
Ver solución
14. Semáforo de stock
La columna D tiene cantidades de stock. Cuando el usuario edite un valor en D, colorea la celda: rojo si es menor a 5, amarillo si está entre 5 y 10, verde si es mayor a 10.
Ver solución
15. Desactivar eventos temporalmente desde otro módulo
Crea una macro CargarDatos en un módulo estándar que escriba 50 valores en la columna A desactivando los eventos antes de empezar y reactivándolos al terminar, evitando que el evento Worksheet_Change se dispare 50 veces.