¿Outlook dejó de imprimir automáticamente los adjuntos de un remitente concreto? Aquí tienes dos métodos 100% en cliente de escritorio para Windows 10, con código VBA listo para copiar: regla que ejecuta un script o macro por evento. Incluyen filtro por remitente, extensiones seguras y control básico de la cola.
Escenario y objetivos
En equipos con Windows 10 y Outlook Clásico (no “Nuevo Outlook”), la acción “Imprimir” estándar solo imprime el cuerpo del correo, no los adjuntos. Si antes te funcionaba una regla con macro y ahora no, o si la acción “ejecutar un script” desapareció por políticas o actualizaciones, este artículo te ofrece dos recorridos totalmente funcionales para volver a automatizar la impresión de adjuntos desde el cliente de escritorio.
Ruta rápida de decisión
Opción | Cómo funciona | Cuándo elegirla | Pros | Contras |
---|---|---|---|---|
A — Regla que ejecuta script (VBA) | La regla filtra (ej. “De: remitente X”) y llama a un procedimiento que guarda e imprime adjuntos. | Cuando tu Outlook muestra la acción “ejecutar un script” en las reglas. | Sencilla, acoplada a Reglas; fácil de entender. | La acción puede estar deshabilitada por TI o por actualizaciones de seguridad. |
B — Macro por evento (Application_NewMailEx ) | Un macro escucha cada correo entrante, filtra por condiciones y procesa adjuntos sin usar reglas. | Cuando no tienes la acción “ejecutar un script” o prefieres independencia de Reglas. | Robusta y flexible; evita depender de la acción “run a script”. | Ligeramente más técnica; conviene documentar el filtro y el módulo común. |
Requisitos previos (para ambas opciones)
- Outlook Clásico para Windows (no funciona en el “Nuevo Outlook”).
- Habilitar macros: Archivo → Opciones → Centro de confianza → Configuración de macros. Recomendado: “Habilitar todas con notificación” o “Deshabilitar todas excepto las firmadas digitalmente” si dispones de firma. Activa “Confiar en el acceso al modelo de objetos de proyecto de VBA”.
- Impresora predeterminada configurada y lista.
- Permisos de escritura en la carpeta temporal del usuario.
Opción A — Regla de Outlook que ejecuta un script (VBA)
Paso a paso resumido
- Asegúrate de usar Outlook Clásico y de tener macros habilitadas (ver requisitos).
- Abre el editor de VBA con ALT+F11.
- En el proyecto de Outlook, ThisOutlookSession: pega el procedimiento
AttachmentAutoPrint
(más abajo). - Inserta un Módulo estándar (por ejemplo, modAutoPrint) y pega el módulo común con utilidades de guardado/impresión (más abajo). Este módulo sirve para A y B.
- Guarda, cierra el editor y reinicia Outlook.
- Crea la regla: Inicio → Reglas → Administrar reglas y alertas → Nueva regla → define condiciones (ej. “de remitente X”) → acción “ejecutar un script” → selecciona
AttachmentAutoPrint
. - Envía un correo de prueba con adjuntos válidos y verifica que se imprimen en la cola.
Importante: si no aparece la acción “ejecutar un script”, es probable que esté deshabilitada por políticas corporativas o por una actualización de seguridad. En ese caso, pasa a la Opción B o consulta con TI para reactivarla.
Código para ThisOutlookSession (Opción A)
Copia y pega este procedimiento. Ajusta el correo a filtrar en el módulo común (ver más abajo) o aquí si lo prefieres.
Option Explicit
' Opcional: define una impresora específica o deja vacío para usar la predeterminada.
Public Const PRINTER\_NAME As String = "" ' Ej.: "HP LaserJet en SALA"
' Regla → "ejecutar un script" → AttachmentAutoPrint
Public Sub AttachmentAutoPrint(ByVal Item As Outlook.MailItem)
On Error GoTo EH
If ShouldProcess(Item) Then
Dim n As Long
n = SaveAndPrintAttachments(Item, PRINTER\_NAME)
If n = 0 Then LogMessage "Sin adjuntos válidos en: " & Item.Subject
End If
Exit Sub
EH:
LogMessage "Error en AttachmentAutoPrint: " & Err.Description
End Sub
Opción B — Macro por evento (sin regla “ejecutar un script”)
Paso a paso resumido
- Habilita macros (ver requisitos) y abre el editor con ALT+F11.
- En ThisOutlookSession, pega el controlador de evento
Application_NewMailEx
(más abajo). - Inserta o reutiliza el Módulo estándar (mismo módulo común que en la Opción A) con las funciones de guardado/impresión.
- Guarda, cierra el editor y reinicia Outlook.
- Prueba enviando un correo de ejemplo desde el remitente filtrado.
Código para ThisOutlookSession (Opción B)
Option Explicit
Public Const PRINTER\_NAME As String = "" ' Deja vacío para la impresora predeterminada
Private Sub Application\_NewMailEx(ByVal EntryIDCollection As String)
On Error GoTo EH
Dim ids() As String
Dim i As Long
ids = Split(EntryIDCollection, ",")
For i = LBound(ids) To UBound(ids)
Dim obj As Object
Set obj = Session.GetItemFromID(ids(i))
If Not obj Is Nothing Then
If TypeOf obj Is Outlook.MailItem Then
Dim mi As Outlook.MailItem
Set mi = obj
If ShouldProcess(mi) Then
Dim n As Long
n = SaveAndPrintAttachments(mi, PRINTER\_NAME)
If n = 0 Then LogMessage "Sin adjuntos válidos en: " & mi.Subject
End If
End If
End If
Set obj = Nothing
Next i
Exit Sub
EH:
LogMessage "Error en NewMailEx: " & Err.Description
End Sub
Módulo común (ambas opciones): guardar + imprimir adjuntos de forma segura
Inserta un Módulo estándar (menú Insertar → Módulo), por ejemplo llamado modAutoPrint, y pega el siguiente código. Ajusta la dirección del remitente en la función ShouldProcess
y las extensiones permitidas en ALLOWED_EXT
.
Option Explicit
' Carpeta temporal y extensiones permitidas (ajusta a tu necesidad)
Public Const TEMP_SUBFOLDER As String = "OutlookAutoPrint"
Public Const ALLOWED_EXT As String = ".pdf;.docx;.xlsx;.csv;.txt;.rtf;.pptx"
' Tiempo de espera (ms) antes de intentar borrar el archivo temporal
Public Const MINMSBEFORE_DELETE As Long = 3000
' ¿Registrar un log en %TEMP%\OutlookAutoPrint\autoprint.log?
Public Const LOGTOFILE As Boolean = True
#If VBA7 Then
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
' Guarda e imprime adjuntos permitidos. Devuelve cuántos se imprimieron.
Public Function SaveAndPrintAttachments(ByVal Item As Outlook.MailItem, _
Optional ByVal PrinterName As String = "") As Long
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim tempPath As String: tempPath = Environ$("TEMP") & "\" & TEMP_SUBFOLDER & "\"
If Not fso.FolderExists(tempPath) Then
On Error Resume Next
fso.CreateFolder tempPath
On Error GoTo 0
End If
Dim att As Outlook.Attachment
Dim printed As Long, saved As Long, skipped As Long
For Each att In Item.Attachments
Dim fn As String: fn = CleanFileName(att.FileName)
Dim ext As String: ext = LCase$(fso.GetExtensionName(fn))
If IsAllowedExt(ext) Then
Dim fullPath As String: fullPath = UniquePath(tempPath, fn)
On Error Resume Next
att.SaveAsFile fullPath
If Err.Number = 0 Then
saved = saved + 1
If PrintFile(fullPath, PrinterName) Then
printed = printed + 1
Else
LogMessage "Fallo de impresión: " & fullPath
End If
Sleep MINMSBEFORE_DELETE
On Error Resume Next
Kill fullPath
On Error GoTo 0
Else
LogMessage "Error al guardar '" & fn & "': " & Err.Description
Err.Clear
End If
On Error GoTo 0
Else
skipped = skipped + 1
End If
Next att
If saved = 0 And Item.Attachments.Count > 0 Then
LogMessage "Adjuntos presentes pero ningún tipo permitido: " & Item.Subject
End If
SaveAndPrintAttachments = printed
End Function
' Imprime usando la aplicación predeterminada. Si se especifica impresora, usa el verbo "printto".
Private Function PrintFile(ByVal filePath As String, Optional ByVal PrinterName As String = "") As Boolean
Dim r As Long
If Len(PrinterName) > 0 Then
r = ShellExecute(0, "printto", filePath, """" & PrinterName & """", vbNullString, 0)
Else
r = ShellExecute(0, "print", filePath, vbNullString, vbNullString, 0)
End If
PrintFile = (r > 32)
End Function
' Filtro de seguridad: admite solo extensiones de la lista ALLOWED_EXT
Private Function IsAllowedExt(ByVal ext As String) As Boolean
ext = LCase$(ext)
If Left$(ext, 1) <> "." Then ext = "." & ext
Dim allowed As Variant: allowed = Split(LCase$(ALLOWED_EXT), ";")
Dim i As Long
For i = LBound(allowed) To UBound(allowed)
If Trim$(allowed(i)) = ext Then
IsAllowedExt = True
Exit Function
End If
Next i
End Function
' Evita sobrescrituras creando "nombre (1).ext" si es necesario
Private Function UniquePath(ByVal folder As String, ByVal fileName As String) As String
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim p As String: p = folder & fileName
If Not fso.FileExists(p) Then
UniquePath = p
Exit Function
End If
Dim ext As String: ext = fso.GetExtensionName(p)
If ext <> "" Then ext = "." & ext
Dim base As String: base = Left$(fileName, Len(fileName) - Len(ext))
Dim i As Long: i = 1
Do
p = folder & base & " (" & i & ")" & ext
i = i + 1
Loop While fso.FileExists(p)
UniquePath = p
End Function
' Limpia caracteres no válidos para el sistema de archivos
Private Function CleanFileName(ByVal s As String) As String
Dim bad As Variant: bad = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
Dim i As Long
For i = LBound(bad) To UBound(bad)
s = Replace$(s, bad(i), "_")
Next i
CleanFileName = s
End Function
' Decide si procesar el correo (ajusta la dirección)
Public Function ShouldProcess(ByVal Item As Outlook.MailItem) As Boolean
Const FILTER_EMAIL As String = "remitente@dominio.com" ' <-- AJUSTA AQUÍ
If LCase$(GetSmtpAddress(Item)) = LCase$(FILTER_EMAIL) Then
ShouldProcess = True
Else
' Ejemplo alternativo por asunto:
' If InStr(1, Item.Subject, "FACTURA", vbTextCompare) > 0 Then ShouldProcess = True
End If
End Function
' Obtiene la dirección SMTP del remitente, compatible con Exchange
Public Function GetSmtpAddress(ByVal Item As Outlook.MailItem) As String
On Error Resume Next
Dim addr As String
If Item.SenderEmailType = "EX" Then
Dim ex As Outlook.ExchangeUser
Set ex = Item.Sender.GetExchangeUser
If Not ex Is Nothing Then addr = ex.PrimarySmtpAddress
End If
If addr = "" Then
Dim pa As Outlook.PropertyAccessor
Set pa = Item.PropertyAccessor
addr = pa.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x39FE001E")
If addr = "" Then addr = Item.SenderEmailAddress
End If
GetSmtpAddress = addr
End Function
' Log opcional a archivo
Public Sub LogMessage(ByVal text As String)
If Not LOGTOFILE Then Exit Sub
On Error Resume Next
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim logPath As String: logPath = Environ$("TEMP") & "\" & TEMP_SUBFOLDER & "\autoprint.log"
Dim ts: Set ts = fso.OpenTextFile(logPath, 8, True)
ts.WriteLine Format$(Now, "yyyy-mm-dd hh:nn:ss") & " - " & text
ts.Close
End Sub
Cómo personalizar el filtro
- En
ShouldProcess
cambiaFILTER_EMAIL
por la cuenta exacta del remitente autorizado. - Si prefieres filtrar por asunto o carpeta, descomenta y adapta los ejemplos indicados en el código.
- Ajusta la lista
ALLOWED_EXT
para incluir solo los tipos que quieras imprimir. - Para usar una impresora concreta, asigna su nombre a
PRINTER_NAME
(en ThisOutlookSession). Si lo dejas vacío, se usa la predeterminada.
Nota de impresión: usa la aplicación predeterminada
Para evitar problemas con ejecutables de impresoras o rutas específicas, este enfoque se apoya en Windows y en la aplicación predeterminada de cada extensión, llamando a ShellExecute
con el verbo “print” (o “printto” si indicas impresora). Recomendaciones:
- Usa “print” hacia la impresora predeterminada cuando sea posible (más compatible).
- “printto” depende de que la aplicación del archivo lo implemente. Funciona bien con muchas apps (ej. Adobe Reader), pero no todas lo soportan.
- Deja un pequeño retraso antes de borrar el archivo temporal (el código ya espera 3 segundos) para que la cola lo capture.
- Imprime solo tipos seguros. Evita ejecutar imprimibles raros o peligrosos.
Tipo | App típica | Comentarios |
---|---|---|
Adobe Reader / Edge | El más fiable. Si usas “printto”, Adobe Reader suele responder mejor que Edge. | |
.docx / .xlsx / .pptx | Microsoft Office | Requiere Office instalado. La primera impresión puede tardar por carga de Office. |
.csv / .txt / .rtf | Notepad / Wordpad / Word | Suele imprimir sin diálogo. Útiles para reportes simples. |
Consejos prácticos y resolución de problemas
- La regla “Imprimir” nativa no imprime adjuntos, solo el cuerpo del correo; por eso necesitas VBA o un complemento.
- Verifica lo básico: impresora predeterminada activa, cola sin errores, conexión a red (si la impresora es de red), permisos de escritura en
%TEMP%
. - Macros en 64 bits: el código ya declara
ShellExecute
ySleep
conPtrSafe
para evitar errores en Office de 64 bits. - Antivirus/antimalware: si Outlook muestra advertencias de “acceso programático”, comprueba que el antivirus esté actualizado y reconocido por Office.
- Desapareció “ejecutar un script”: es habitual por políticas/actualizaciones. Si no puedes reactivarlo con TI, usa la Opción B.
- Adjuntos protegidos: si un adjunto se abre en Vista protegida, algunas apps pueden no imprimir en silencio. Prueba con PDF primero.
- Registros: si activas
LOGTOFILE
, revisa%TEMP%\OutlookAutoPrint\autoprint.log
para ver qué pasó con cada adjunto. - Rendimiento: si llegan muchos correos simultáneamente, usa filtros más finos (remitente + asunto) para evitar saturar la cola.
Checklist de verificación rápida
- Outlook Clásico y macros habilitadas (con acceso a modelo de objetos).
- Copiaste el código en ThisOutlookSession y en un Módulo estándar.
- Reiniciaste Outlook tras guardar.
- Se imprime un PDF de prueba enviado desde el remitente autorizado.
- Los archivos temporales se crean y luego se eliminan (o quedan si hubo error).
Alternativas sin código
- Power Automate (Desktop o nube): crea un flujo “al llegar un correo” → “guardar adjuntos” → “imprimir documento” en un equipo designado. Es amigable y fácil de mantener, pero requiere licencias/configuración.
- Complementos de terceros especializados en imprimir adjuntos automáticamente. Son útiles si no quieres mantener macros ni políticas de seguridad.
Seguridad y buenas prácticas
- Principio de mínimo privilegio: limita por remitente y tipo de archivo. No imprimas ejecutables ni formatos desconocidos.
- Firmar macros: si es un entorno corporativo, firma el proyecto VBA y establece la directiva “solo macros firmadas”.
- Auditoría: conserva el log y realiza pruebas periódicas con correos de muestra controlados.
- Compatibilidad futura: el “Nuevo Outlook” no soporta VBA. Si migras, evalúa Power Automate o complementos.
Guía de pruebas recomendadas
- Prueba base: un correo desde el remitente filtrado con un solo PDF de 1 página. Debe imprimirse y borrarse el temporal.
- Varios adjuntos: PDF + DOCX + XLSX. Deben imprimirse todos los tipos permitidos.
- Adjunto no permitido: añade un .zip; el log debe indicar que fue omitido.
- Impresora específica: define
PRINTER_NAME
y verifica que la cola correcta recibe el trabajo. - Oleada de correos: envía 3–5 correos seguidos para observar la estabilidad y los tiempos en cola.
Resumen operativo
- Elige Opción A (Regla + script) si tienes disponible “ejecutar un script”.
- Elige Opción B (
NewMailEx
) si la acción de reglas no está disponible o prefieres independencia. - Habilita macros con notificación y activa “acceso al modelo de objetos”.
- Usa el módulo común para guardar + imprimir adjuntos con ShellExecute y extensiones seguras.
- Prueba con un correo de ejemplo y revisa la cola de impresión y el log.
Preguntas frecuentes
¿Por qué la regla nativa de Outlook no imprime adjuntos?
Porque solo imprime el cuerpo del mensaje. Para adjuntos, necesitas VBA o un complemento.
¿El código sirve en Office de 64 bits?
Sí. Las declaraciones usan PtrSafe
cuando procede.
¿Puedo usar una impresora de red concreta?
Sí. Indica su nombre exacto en PRINTER_NAME
. Si tu app predeterminada soporta printto, se enviará a esa cola; de lo contrario, usa la predeterminada.
¿Funciona en el “Nuevo Outlook”?
No. Ese cliente no ejecuta VBA. En ese caso, evalúa Power Automate o soluciones de terceros.
¿Puedo filtrar por varios remitentes?
Sí. Amplía ShouldProcess
con varias comparaciones o una lista.
Plantilla de mantenimiento
- Mensual: vacía la carpeta
%TEMP%\OutlookAutoPrint
si quedaran restos, revisa el log y limpia adjuntos atascados. - Trimestral: revalida los filtros (remitentes y extensiones) y el nombre de la impresora.
- Tras actualizaciones: comprueba que las aplicaciones predeterminadas de cada tipo siguen imprimiendo en silencio.
Con estas dos rutas (Regla + script o Evento NewMailEx
) y el módulo común, recuperarás una impresión automática de adjuntos sencilla, fiable y controlada para Outlook en Windows 10.