Outlook: imprimir adjuntos automáticamente en Windows 10 (VBA, reglas y eventos)

¿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.

Índice

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ónCómo funcionaCuándo elegirlaProsContras
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

  1. Asegúrate de usar Outlook Clásico y de tener macros habilitadas (ver requisitos).
  2. Abre el editor de VBA con ALT+F11.
  3. En el proyecto de Outlook, ThisOutlookSession: pega el procedimiento AttachmentAutoPrint (más abajo).
  4. 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.
  5. Guarda, cierra el editor y reinicia Outlook.
  6. Crea la regla: Inicio → Reglas → Administrar reglas y alertas → Nueva regla → define condiciones (ej. “de remitente X”) → acción “ejecutar un script” → selecciona AttachmentAutoPrint.
  7. 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

  1. Habilita macros (ver requisitos) y abre el editor con ALT+F11.
  2. En ThisOutlookSession, pega el controlador de evento Application_NewMailEx (más abajo).
  3. 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.
  4. Guarda, cierra el editor y reinicia Outlook.
  5. 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 cambia FILTER_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.
TipoApp típicaComentarios
.pdfAdobe Reader / EdgeEl más fiable. Si usas “printto”, Adobe Reader suele responder mejor que Edge.
.docx / .xlsx / .pptxMicrosoft OfficeRequiere Office instalado. La primera impresión puede tardar por carga de Office.
.csv / .txt / .rtfNotepad / Wordpad / WordSuele 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 y Sleep con PtrSafe 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

  1. Outlook Clásico y macros habilitadas (con acceso a modelo de objetos).
  2. Copiaste el código en ThisOutlookSession y en un Módulo estándar.
  3. Reiniciaste Outlook tras guardar.
  4. Se imprime un PDF de prueba enviado desde el remitente autorizado.
  5. 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

  1. Prueba base: un correo desde el remitente filtrado con un solo PDF de 1 página. Debe imprimirse y borrarse el temporal.
  2. Varios adjuntos: PDF + DOCX + XLSX. Deben imprimirse todos los tipos permitidos.
  3. Adjunto no permitido: añade un .zip; el log debe indicar que fue omitido.
  4. Impresora específica: define PRINTER_NAME y verifica que la cola correcta recibe el trabajo.
  5. 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.

Índice