TL;DR —
Workbook_BeforePrintes un evento que Excel dispara antes de que se imprima nada del libro. Te entrega un único argumento,Cancel. PonCancel = Truey la impresión se cancela — así puedes validar primero (bloquear una impresión con campos obligatorios vacíos), sellar la fecha de impresión o registrar quién imprimió. Dos cosas sorprenden a todo el mundo: se dispara también con la Vista preliminar — no solo con una impresión de verdad — así que cualquier trabajo pesado aquí se ejecuta cada vez que alguien hace una vista previa; y se dispara una sola vez para todo el libro, no una vez por hoja. El código vive enThisWorkbook.
' Vive en ThisWorkbook - NO en un Module, NO en una hoja.
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If ThisWorkbook.Sheets("Invoice").Range("Total").Value = "" Then
MsgBox "Enter a Total before printing this invoice.", vbExclamation
Cancel = True ' <-- bloquea la impresión; nada llega a la impresora
End If
End Sub
La mayoría de las macros se ejecutan cuando el usuario lo pide — un botón, un atajo.
Workbook_BeforePrint se ejecuta cuando el usuario intenta imprimir, y lo hace antes de
que el trabajo llegue a la impresora. Ese momento es justo lo que quieres para comprobaciones
y sellos de último segundo: confirmar que la hoja está lista para imprimir, escribir la fecha
de hoy en un encabezado, registrar quién imprimió y cuándo — o detener la impresión por
completo. Es también un evento con dos comportamientos que pillan a la gente por sorpresa, y
ambos cambian cómo deberías escribir el manejador.
Lo que aprenderás
- El modelo mental — un puesto de control sobre la impresión, con un
Cancelcon el que puedes vetarla - La regla que más importa —
Cancel = Truebloquea la impresión, y un bloqueo silencioso es un bug - La pega de la Vista preliminar — el evento se dispara también en la vista previa, así que mantenlo ligero
- Por qué se ejecuta una sola vez para todo el libro, no por hoja — y qué hacer con los encabezados
- Dónde tiene que vivir el código, y en qué se diferencia de los eventos de gesto
El modelo mental: un puesto de control sobre la impresión, no un botón de imprimir
Workbook_BeforePrint se dispara en el momento en que se solicita una impresión — Archivo ▸
Imprimir, Ctrl+P, una macro que llama a .PrintOut, o abrir la vista de impresión — y se
dispara antes de que Excel envíe nada a la impresora. Pasa un único Boolean por
referencia, Cancel. Tú nunca llamas a este Sub; Excel te llama a ti, espera y luego mira
Cancel. Déjalo en paz y la impresión continúa. Pon Cancel = True y Excel abandona la
impresión.
Así que el manejador es un puesto de control camino de la impresora, no un botón de
imprimir que pulsas. Tiene la misma forma que sus primos de eventos-guardián
Workbook_BeforeClose y
Workbook_BeforeSave: cada uno te entrega un Cancel que
puedes poner para vetar la acción que Excel está a punto de realizar. Lee BeforePrint como
«avísame cuando alguien imprima» y te perderás el veto que hace que valga la pena conectarlo.
Y como esos dos, su código vive en el módulo ThisWorkbook — haz doble clic en
ThisWorkbook bajo «Objetos de Microsoft Excel» en el Explorador de proyectos. En un Module
estándar no se dispara nunca.
La regla que más importa: Cancel = True la bloquea — pero di por qué
Bloquear una impresión es la razón entera por la que mucha gente recurre a este evento —
validar antes de imprimir, o impedir que salga un borrador. El mecanismo es una línea,
Cancel = True. El error es hacerlo en silencio:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Sheets("Invoice").Range("Approved").Value <> "Yes" Then Cancel = True ' bloquea... en silencio
End Sub
El usuario pulsa Ctrl+P, no se imprime nada y no hay ninguna explicación. Da por hecho que
la impresora está estropeada, o que Excel lo está, y te abre un informe de error. Un
Cancel silencioso es un bug, no una función. Cuando bloquees una impresión, dile al
usuario por qué, para que el no-suceso sea obviamente tu decisión:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Sheets("Invoice").Range("Approved").Value <> "Yes" Then
MsgBox "This invoice isn't approved yet - printing is blocked.", vbExclamation
Cancel = True
End If
End Sub
Ahora el bloqueo es legible: el usuario sabe exactamente qué corregir. La misma cortesía se aplica a Workbook_BeforeSave — cualquier veto que el usuario no esperaba necesita una frase que lo explique.
La pega que arruina el rendimiento: la Vista preliminar también lo dispara
Este es el comportamiento que convierte un manejador útil en uno lento. Workbook_BeforePrint
se dispara no solo en una impresión de verdad, sino también cuando el usuario abre la Vista
preliminar (la vista de impresión en Backstage). Así que si tu manejador hace algo costoso —
actualizar una conexión de datos, ejecutar una consulta web, recalcular un modelo enorme,
reconstruir una hoja — ese trabajo se ejecuta cada vez que alguien hace una vista previa, y
la vista previa es algo que la gente hace a la ligera y a menudo. La hoja se arrastra, y nadie
relaciona la lentitud con un evento de impresión.
La regla: mantén BeforePrint ligero. Validación, un sello de fecha, una línea de
registro — bien. Las actualizaciones pesadas pertenecen a una acción explícita (un botón
«Actualizar») o a una tarea programada, no a un evento que se dispara con cada vistazo a la
vista previa de impresión. Si de verdad tienes que hacer trabajo pesado solo para una
impresión real, no hay forma limpia y universal de distinguir la vista previa de la impresión
dentro del evento clásico — lo cual es en sí mismo el argumento más fuerte para no poner aquí
trabajo pesado en absoluto.
La regla sobre el alcance: se ejecuta una sola vez para todo el libro
Workbook_BeforePrint se dispara una vez por solicitud de impresión para todo el libro —
no una vez por hoja, y no te dice qué hoja se está imprimiendo. No existe
Worksheet_BeforePrint. Así que cualquier lógica de «prepara esto antes de imprimir» tiene
que tratar el libro como la unidad. Si quieres un sello de impresión en cada hoja, recorre las
hojas tú mismo, o — mejor — usa un encabezado de PageSetup que Excel mantiene por ti:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.PageSetup.LeftFooter = "Printed " & Format(Date, "yyyy-mm-dd")
Next ws
End Sub
Prefiere los encabezados y pies de página de PageSetup — &D para la fecha, &P para el
número de página, &F para el nombre de archivo — antes que escribir el sello en una celda.
Un pie de página es solo para impresión y se limpia solo; una celda que modificas para
imprimir hay que restaurarla después, y como no existe un evento compañero «AfterPrint» fiable
y la vista previa también dispara este manejador, esa restauración es peliaguda de hacer bien.
Deja que Excel se ocupe del papel; guarda tus celdas para los datos.
La distinción que enmarca el grupo: sin Target, solo a nivel de libro
Los dos eventos de gesto de esta familia —
Worksheet_BeforeDoubleClick y
Worksheet_BeforeRightClick — son por hoja y te
entregan una celda Target, porque un clic ocurre en un sitio concreto.
Workbook_BeforePrint es lo contrario: a nivel de libro, sin Target, porque una impresión
es una acción de todo el documento, no un punto en una hoja. Lo que los tres comparten es el
indicador Cancel — el único argumento que convierte un evento de una notificación en un
veto. Esa es la columna vertebral de toda la familia de interceptación: doble clic, clic
derecho, impresión — en cada uno, Excel le pregunta a tu código «¿sigo adelante?» y tu
Cancel es la respuesta.
Cómo ayuda ExcelMaster
Una protección de impresión son unas cuantas pequeñas decisiones fáciles de equivocar por
poco: el Cancel = True que bloquea el trabajo, el MsgBox que evita que el bloqueo sea un
misterio, la disciplina de mantener el manejador ligero para que la vista previa siga siendo
rápida, y usar PageSetup en lugar de modificar celdas.
ExcelMaster
te deja describir el comportamiento en su lugar. Di «antes de imprimir, si la factura no está
aprobada, bloquea la impresión y avisa al usuario, y sella la fecha de impresión en el pie de
página de cada hoja», y escribe un Workbook_BeforePrint en ThisWorkbook que pone Cancel,
explica el bloqueo y usa PageSetup para el sello. Te quedas con el libro y el código; te
ahorras aprender la pega de la vista previa por las malas.
Preguntas frecuentes
¿Cómo ejecuto una macro antes de imprimir en Excel?
Pon un procedimiento Workbook_BeforePrint en el módulo ThisWorkbook:
Private Sub Workbook_BeforePrint(Cancel As Boolean). Excel lo llama antes de cualquier
impresión del libro. Añade ahí tu preparación o tus comprobaciones. No se dispara desde un
Module estándar.
¿Cómo impido que un libro se imprima en VBA?
Pon Cancel = True dentro de Workbook_BeforePrint. Excel comprueba Cancel después de que
se ejecute tu manejador, y True bloquea la impresión. Muestra siempre un MsgBox que
explique por qué — un bloqueo silencioso le parece una impresora estropeada al usuario.
¿Se dispara Workbook_BeforePrint con la Vista preliminar?
Sí. Abrir la vista de Impresión/Vista preliminar lo dispara, no solo una impresión de verdad. Por eso deberías mantener el manejador ligero — cualquier actualización o recálculo pesado se ejecutaría cada vez que alguien hace una vista previa.
¿Existe un evento Worksheet_BeforePrint para una sola hoja?
No. BeforePrint es solo a nivel de libro y se dispara una vez para todo el libro, sin decirte
qué hoja se imprime. Para actuar por hoja, recorre ThisWorkbook.Worksheets dentro del
manejador, o configura el encabezado/pie de página de PageSetup de cada hoja.
¿Cómo añado la fecha de impresión a cada página?
Usa un pie de página de PageSetup con la fecha, ya sea el código integrado &D o
Format(Date, "yyyy-mm-dd"), aplicado a cada hoja en Workbook_BeforePrint. Un pie de página
es solo para impresión y no necesita limpieza, a diferencia de un valor escrito en una celda.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 06/08/2026.
Guías relacionadas: VBA Worksheet_BeforeDoubleClick · VBA Worksheet_BeforeRightClick · VBA Workbook_BeforeSave · VBA Workbook_BeforeClose · VBA Workbook_Open
