Outlook: stampa automatica degli allegati con VBA (Windows) — guida completa e troubleshooting

Hai una regola di Outlook che stampava gli allegati in automatico e da qualche giorno non funziona più? In questa guida aggiornata vediamo come ripristinarla in modo sicuro su Windows, con esempi di codice VBA pronti all’uso, alternative no‑code e una checklist di diagnostica mirata.

Indice

Scenario e obiettivo

Un utente aveva creato tempo fa una regola che, tramite uno script VBA (Project1 : ThisOutlookSession), stampava automaticamente gli allegati provenienti da un mittente specifico. Da circa una settimana la stampa non parte più. L’obiettivo è ripristinare la stampa automatica degli allegati in Outlook per Windows (“Classic Outlook”) nel modo più solido possibile, senza componenti esterni obbligatori e con la massima trasparenza su sicurezza e manutenzione.

Perché la stampa automatica può smettere di funzionare

  • Macro disattivate: un aggiornamento di Office o un criterio aziendale può aver cambiato le impostazioni del Centro protezione, bloccando l’esecuzione di VBA.
  • Regola “Esegui uno script” non più attiva: la voce può essere nascosta o disabilitata da policy; la regola potrebbe essere stata importata/duplicata e non punta più alla macro corretta.
  • Passaggio a “New Outlook”: la nuova app (UWP) non supporta script VBA; serve usare “Classic Outlook”.
  • Percorsi e stampanti cambiati: la cartella di salvataggio non esiste più, il comando di stampa è cambiato o la stampante predefinita è stata rinominata.
  • File handler: il programma che gestisce i PDF (o altri formati) è diverso e il vecchio comando non è più valido.

Checklist rapida di ripristino

  1. Verifica di usare Classic Outlook (non “New Outlook”).
  2. Vai in File → Opzioni → Centro protezione → Impostazioni Centro protezione → Impostazioni macro e consenti macro firmate oppure abilita le macro solo se l’ambiente è controllato.
  3. Controlla la regola: Home → Rules → Manage Rules & Alerts e verifica se l’azione “Run a script / Esegui uno script” è disponibile e punta alla macro corretta.
  4. Controlla che la cartella di salvataggio esista e che tu abbia permessi di scrittura.
  5. Apri l’editor VBA (ALT+F11), ricrea lo script con le personalizzazioni (mittente, percorso, comando di stampa) e salva.
  6. Riavvia Outlook per forzare il reload di ThisOutlookSession.

Soluzione A — Evento globale: Application_NewMailEx (senza regola)

Questa strada intercetta tutti i nuovi messaggi in arrivo e, se il mittente corrisponde al filtro, salva e stampa gli allegati. Non richiede la regola “Esegui uno script”.

Passaggi

  1. Apri Outlook (Classic), premi ALT+F11 per aprire l’Editor VBA.
  2. Nel riquadro Project Explorer, fai doppio clic su ThisOutlookSession.
  3. Incolla il codice seguente, personalizzando i valori contrassegnati.
Option Explicit

' === CONFIGURAZIONE DA PERSONALIZZARE ===
Private Const SENDER_FILTER As String = "mittente@esempio.com"   ' ← mittente da filtrare
Private Const SAVE_FOLDER  As String = "C:\Percorso\Salvataggio\" ' ← cartella esistente
Private Const PDF_ONLY     As Boolean = False                     ' True stampa solo PDF
Private Const LOG_FILE     As String = "C:\Percorso\Logs\OutlookAutoPrint.log"

' Percorsi esempio per stampa diretta PDF con Acrobat Reader (facoltativo)
' Se vuoto, si usa la stampa generica di Windows (ShellExecute "print")
Private Const ACROBAT_PATH As String = ""  ' es. "C:\Program Files\Adobe\Acrobat Reader\AcroRd32.exe"
Private Const PRINTER_NAME As String = ""  ' es. "Nome Stampante Condivisa"

' === EVENTO DI ARRIVO POSTA ===
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    On Error GoTo EH

    Dim ids() As String, i As Long
    Dim itm As Object, mail As Outlook.MailItem

    ids = Split(EntryIDCollection, ",")
    For i = LBound(ids) To UBound(ids)
        Set itm = Application.Session.GetItemFromID(ids(i))
        If TypeName(itm) = "MailItem" Then
            Set mail = itm
            If LCase$(GetSenderSmtp(mail)) = LCase$(SENDER_FILTER) Then
                PrintAttachmentsFromMail mail
            End If
        End If
    Next

    Exit Sub
EH:
    LogMessage "Errore in Application_NewMailEx: " & Err.Number & " - " & Err.Description
End Sub

' === FUNZIONE PER NORMALIZZARE L'EMAIL DEL MITTENTE ===
Private Function GetSenderSmtp(ByVal m As Outlook.MailItem) As String
    On Error Resume Next
    Dim s As String
    If m.SenderEmailType = "EX" Then
        s = m.Sender.GetExchangeUser().PrimarySmtpAddress
    Else
        s = m.SenderEmailAddress
    End If
    GetSenderSmtp = s
End Function

' === LOGICA DI STAMPA ===
Private Sub PrintAttachmentsFromMail(ByVal m As Outlook.MailItem)
    On Error GoTo EH

    Dim att As Outlook.Attachment
    Dim target As String

    EnsureFolder SAVE_FOLDER
    For Each att In m.Attachments
        If (Not PDF_ONLY) Or LCase$(Right$(att.FileName, 4)) = ".pdf" Then
            target = SAVE_FOLDER & TimeStampPrefix() & SanitizeFileName(att.FileName)
            att.SaveAsFile target

            If ACROBAT_PATH <> "" And LCase$(Right$(target, 4)) = ".pdf" Then
                PrintPdfWithAcrobat target, PRINTER_NAME
            Else
                If Not PrintGeneric(target) Then
                    LogMessage "Stampa generica fallita per: " & target
                End If
            End If

            LogMessage "Stampato: " & target & " da: " & GetSenderSmtp(m)
        End If
    Next

    Exit Sub
EH:
    LogMessage "Errore in PrintAttachmentsFromMail: " & Err.Number & " - " & Err.Description
End Sub

' === SUPPORTO: STAMPA GENERICA WINDOWS (usa il verbo "print") ===
#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 LongPtr
#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
#End If

Private Function PrintGeneric(ByVal filePath As String) As Boolean
    On Error Resume Next
    Dim r As LongPtr
    r = ShellExecute(0, "print", filePath, vbNullString, vbNullString, 0)
    PrintGeneric = (r > 32)
End Function

' === SUPPORTO: STAMPA PDF CON ACROBAT READER ===
Private Sub PrintPdfWithAcrobat(ByVal filePath As String, Optional ByVal printer As String = "")
    On Error Resume Next
    Dim cmd As String
    If Len(printer) > 0 Then
        cmd = """" & ACROBAT_PATH & """ /t """ & filePath & """ """ & printer & """"
    Else
        cmd = """" & ACROBAT_PATH & """ /t """ & filePath & """"
    End If
    Shell cmd, vbHide
End Sub

' === UTIL: SANITIZZAZIONE, TIMESTAMP, LOG, CARTELLA ===
Private Function TimeStampPrefix() As String
    TimeStampPrefix = Format(Now, "yyyymmddhhnnss")
End Function

Private Function SanitizeFileName(ByVal fn As String) As String
    Dim badChars As Variant, c As Variant
    badChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
    For Each c In badChars
        fn = Replace(fn, c, "_")
    Next
    SanitizeFileName = fn
End Function

Private Sub EnsureFolder(ByVal path As String)
    If Len(Dir$(path, vbDirectory)) = 0 Then MkDir path
End Sub

Private Sub LogMessage(ByVal msg As String)
    On Error Resume Next
    Dim f As Integer: f = FreeFile
    EnsureFolder Left$(LOGFILE, InStrRev(LOGFILE, "\"))
    Open LOG_FILE For Append As #f
    Print #f, Format(Now, "yyyy-mm-dd hh:nn:ss"); " | "; msg
    Close #f
End Sub

Note importanti:

  • Personalizza SENDERFILTER, SAVEFOLDER, PDFONLY e, se vuoi usare Acrobat per i PDF, ACROBATPATH e PRINTER_NAME.
  • La stampa generica (PrintGeneric) dipende dall’associazione file predefinita in Windows: assicurati che i PDF (o altri formati) si aprano con un programma che supporta il verbo Print.
  • Il log su file (LOG_FILE) è utilissimo per diagnosi e audit.

Soluzione B — Regola “Esegui uno script” + macro dedicata

Se preferisci vincolare la stampa al trigger di una regola (es. solo per un determinato mittente o solo con una parola in oggetto), usa una macro con firma compatibile con le regole di Outlook.

Passaggi

  1. VBA: in ThisOutlookSession incolla questa macro (e le funzioni di supporto già viste sopra: GetSenderSmtp, PrintAttachmentsFromMail, ecc.).
Option Explicit

' Macro compatibile con "Esegui uno script"
Public Sub Regola_StampaAllegati(ByVal Item As Outlook.MailItem)
    On Error GoTo EH
    ' Filtro aggiuntivo a livello di codice (opzionale)
    If LCase$(GetSenderSmtp(Item)) = LCase$("mittente@esempio.com") Then
        PrintAttachmentsFromMail Item
    End If
    Exit Sub
EH:
    LogMessage "Errore in Regola_StampaAllegati: " & Err.Number & " - " & Err.Description
End Sub
  1. Regola: vai in Home → Rules → Manage Rules & Alerts → New Rule…, scegli “applica regola ai messaggi in arrivo”, imposta la condizione “da persone o gruppo pubblico” con l’indirizzo desiderato e, nelle azioni, scegli “Run a script / Esegui uno script”Project1.Regola_StampaAllegati.
  2. Salva e riavvia Outlook.

Attenzione: la voce “Esegui uno script” può essere disabilitata da criteri di sicurezza aziendali o impostazioni locali. Se non compare, consulta il tuo amministratore o verifica le policy client di Outlook. In ambienti privi di domain policy, alcuni amministratori abilitano l’azione tramite impostazioni di sicurezza client; valuta sempre l’impatto sulla postura di sicurezza prima di procedere.

Quale soluzione scegliere?

MetodoProControQuando usarlo
Evento NewMailExNon richiede regola; intercetta tutto; codice centralizzato.Meno granulare senza logica extra; stampa anche su inoltri automatici se non filtrati.Quando vuoi semplicità e controllo da codice.
Regola + Regola_StampaAllegatiCondizioni della regola chiare; facile attivare/disattivare.Dipende dalla disponibilità di “Esegui uno script”.Quando esistono già regole di inoltro/filtraggio consolidate.

Diagnostica e debug: cosa controllare in 5 minuti

  1. Il codice scatta? Aggiungi temporaneamente MsgBox o Debug.Print nell’evento; apri la Finestra Immediata (CTRL+G in VBE) per vedere le tracce.
  2. Il file si salva? Guarda nella cartella SAVE_FOLDER. Se vuota, problema di permessi o percorso inesistente.
  3. La stampa parte? Se il file si salva ma non stampa, prova ad aprirlo manualmente e usa “Stampa” dall’app predefinita; se funziona, aggiorna il metodo di stampa nel codice (Acrobat /t per PDF o ShellExecute "print").
  4. Log: ispeziona LOG_FILE per errori e timestamp delle stampe.
  5. Stampante: verifica il nome esatto e che sia online/impostata correttamente; se usi PRINTER_NAME, controlla che coincida con il nome di sistema.

Filtri più evoluti sugli allegati

Vuoi stampare solo certi tipi di allegato o escludere file troppo grandi? Ecco una variante del ciclo sugli allegati:

' Stampa solo PDF e immagini < 10 MB
If LCase$(att.FileName) Like ".pdf" Or LCase$(att.FileName) Like ".jpg" Or LCase$(att.FileName) Like "*.png" Then
    If att.Size < 10  1024  1024 Then
        ' salva e stampa...
    Else
        LogMessage "Allegato troppo grande, salto: " & att.FileName
    End If
End If

Automazione affidabile della stampa: strategie

  • PDF: è il formato più prevedibile. Con Acrobat/Reader puoi usare /t per inviare il file direttamente alla stampante senza UI.
  • Verbo Print di Windows: funziona per molti formati (docx, txt, immagini) ma dipende dall’app registrata come predefinita e può mostrare finestre.
  • Accodamento: se arrivano molti messaggi, introduci un delay tra una stampa e l’altra o un semplice controllo di file lock.
  • Pulizia: pianifica la pulizia della cartella di salvataggio (es. file più vecchi di 7 o 30 giorni) per evitare accumuli.

Sicurezza delle macro: cosa sapere

  • In File → Opzioni → Centro protezione consenti l’esecuzione solo di macro affidabili. L’ideale è firmare il progetto VBA con un certificato (anche auto‑firmato con lo strumento incluso in Office) e impostare “Consenti solo macro firmate”.
  • Evita di stampare automaticamente allegati di tipo eseguibile o potenzialmente pericolosi. Limita i formati con un whitelist e, se possibile, stampa solo PDF.
  • In ambienti aziendali, valuta l’uso di criteri di gruppo per gestire macro e la disponibilità dell’azione “Esegui uno script”.

Classic Outlook vs New Outlook

Lo script VBA funziona nel Classic Outlook (Win32). La nuova app “New Outlook” per Windows non supporta VBA: se hai migrato, la stampa automatica non potrà funzionare con questo metodo. In tal caso puoi:

  • Restare su Classic Outlook per gli scenari che richiedono VBA.
  • Adottare Power Automate (cloud) con connettori Outlook/SharePoint/OneDrive e un’azione di stampa su un PC tramite Power Automate Desktop.

Alternative no‑code

  • Power Automate Desktop (integrato in Windows 10/11): crea un flusso che salva gli allegati in una cartella e lancia il comando di stampa del lettore PDF.
  • Strumenti di terze parti: esistono add‑in dedicati alla gestione stampa allegati; valuta sempre costi, affidabilità e policy di sicurezza.

Template completo “chiavi in mano”

Se preferisci un file VBA unico e riutilizzabile, unisci le due sezioni (evento + macro di regola) e tieni in alto solo i parametri da toccare. Ecco un estratto essenziale con i punti di personalizzazione in evidenza:

' ====== PARAMETRI ======
' - Cambia solo questi valori e lascia il resto invariato
Private Const SENDER_FILTER As String = "mittente@esempio.com"
Private Const SAVE_FOLDER  As String = "C:\Percorso\Salvataggio\"
Private Const ACROBAT_PATH As String = ""
Private Const PRINTER_NAME As String = ""
Private Const PDF_ONLY     As Boolean = True
Private Const LOG_FILE     As String = "C:\Percorso\Logs\OutlookAutoPrint.log"

' ====== TRIGGER 1: EVENTO ======
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    ' ... (come sopra)
End Sub

' ====== TRIGGER 2: REGOLA ======
Public Sub Regola_StampaAllegati(ByVal Item As Outlook.MailItem)
    ' ... (come sopra)
End Sub

' ====== SUPPORTO (GetSenderSmtp, PrintAttachmentsFromMail, PrintGeneric, PrintPdfWithAcrobat, ecc.) ======
' ... (come sopra)

Risoluzione problemi: domande frequenti

La voce “Esegui uno script” non appare tra le azioni della regola

È comune in ambienti dove sono state irrigidite le impostazioni di sicurezza di Outlook. Chiedi al tuo amministratore se la funzionalità è stata disabilitata tramite policy. In alternativa utilizza l’evento NewMailEx (Soluzione A), che non richiede la regola.

Il mittente rilevato non coincide con quello visibile nel messaggio

Su caselle Exchange/Entra ID, SenderEmailAddress può essere in formato Exchange (“EX”). La funzione GetSenderSmtp risolve l’SMTP primario in modo affidabile.

La macro si disattiva ad ogni riavvio

Assicurati di salvare il progetto VBA e di non avere criteri che impongano la disattivazione. Firma il progetto e imposta in Centro protezione “Consenti solo macro firmate”.

Le finestre di stampa si aprono a video

Accade con ShellExecute “print” su certe app. Per i PDF valuta l’uso del parametro /t di Acrobat Reader o di un lettore PDF che supporti stampa silenziosa.

La stampante giusta non viene usata

Se non specifichi PRINTER_NAME, molte app usano la stampante predefinita di Windows. Imposta la stampante specifica se il tuo flusso richiede device dedicati (es. una stampante di reparto).

Considerazioni operative (riepilogo)

AspettoDettagli operativi
Sicurezza macroIn Outlook le macro sono spesso disattivate. In File → Opzioni → Centro protezione → Impostazioni Centro protezione → Impostazioni macro consenti le macro firmate o abilita l’esecuzione solo in ambienti sicuri.
Driver/utility di stampaPrinter.exe è un segnaposto. Usa il comando del driver o un’utility che accetti il percorso file come argomento (es. AcroRd32.exe /t per PDF, print o il verbo Print via ShellExecute).
Percorso di salvataggioLa cartella deve esistere e avere permessi di scrittura. In alternativa usa una cartella temporanea e pianifica una pulizia periodica.
Versioni di OutlookLo script è destinato a Classic Outlook. In New Outlook il supporto VBA non è disponibile.
Alternative no‑codePower Automate Desktop (Windows 10/11) può salvare e aprire allegati con un flusso low‑code. Esistono anche add‑in di terze parti che gestiscono la stampa automatica; valutarne costi e sicurezza.

Best practice di manutenzione

  • Whitelisting estensioni: limita ai soli formati necessari (tipicamente PDF). Riduce il rischio di contenuti non sicuri.
  • Log e auditing: conserva un log delle stampe con mittente, nome file e timestamp; aiuta in caso di contestazioni.
  • Backup impostazioni: esporta le regole di Outlook e salva il tuo progetto VBA per un ripristino rapido.
  • Aggiornamenti: dopo update di Office/Windows, fai un test di stampa con un’e‑mail di prova.
  • Separa i ruoli: usa un account di servizio su PC “di stampa” quando possibile, così eventuali problemi non impattano l’utente principale.

Esempi di comandi utili per la stampa silenziosa

Questi esempi mostrano come potresti sostituire il placeholder citato in vecchi script (Printer.exe) con comandi reali. Adattali al tuo ambiente:

  • Acrobat Reader (PDF): "C:\Program Files\Adobe\Acrobat Reader\AcroRd32.exe" /t "C:\Percorso\Salvataggio\file.pdf" "NomeStampante"
  • Stampa generica Windows (verb Print): gestita nel codice tramite ShellExecute – non richiede una utility esterna.
  • PowerShell (approccio generico): Start-Process -FilePath "C:\...\file.pdf" -Verb Print (richiamabile da VBA con Shell).

Procedura completa: dalla A alla Z

  1. Conferma versione: apri Classic Outlook.
  2. Abilita macro (in modo sicuro): imposta “Disattiva tutte le macro con notifica” o “Consenti solo macro firmate”.
  3. Apri VBA (ALT+F11): incolla il codice della Soluzione A o Soluzione B.
  4. Personalizza: mittente, cartella, stampante, estensioni consentite, percorso Acrobat (se usato).
  5. Compila e salva il progetto (menu Debug → Compila progetto VBA).
  6. Riavvia Outlook e invia un’email di prova dal mittente autorizzato con un PDF allegato.
  7. Verifica cartella e log, controlla la stampante; se tutto ok rimuovi eventuali MsgBox di debug.

Conclusioni

Con i due approcci proposti (evento globale o regola + macro) puoi ripristinare in modo rapido e controllato la stampa automatica degli allegati in Outlook per Windows. I parametri in testa al codice rendono facile l’adattamento al tuo contesto (mittenti, formati, stampante). Mantieni un focus costante su sicurezza (macro firmate, whitelist delle estensioni) e manutenzione (log, backup del codice). Se il tuo ambiente ha già adottato “New Outlook” o policy restrittive, considera l’alternativa con Power Automate Desktop per ottenere lo stesso risultato senza VBA.


Appendice: snippet minimale (solo PDF, sender fisso)

Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    Dim arr() As String, i As Long
    Dim m As Outlook.MailItem, o As Object
    arr = Split(EntryIDCollection, ",")
    For i = LBound(arr) To UBound(arr)
        Set o = Application.Session.GetItemFromID(arr(i))
        If TypeName(o) = "MailItem" Then
            Set m = o
            If LCase$(m.SenderEmailAddress) = "mittente@esempio.com" Then
                Dim a As Outlook.Attachment, p As String
                For Each a In m.Attachments
                    If LCase$(Right$(a.FileName, 4)) = ".pdf" Then
                        p = "C:\Percorso\Salvataggio\" & a.FileName
                        a.SaveAsFile p
                        Shell "C:\Percorso\Printer.exe " & """" & p & """", vbHide  ' ← sostituisci con comando reale
                    End If
                Next
            End If
        End If
    Next
End Sub

Riepilogo chiave

  • Script funzionante sia con evento NewMailEx sia con regola “Esegui uno script”.
  • Filtro mittente robusto tramite GetSenderSmtp.
  • Stampa flessibile: verbo Windows Print o Acrobat /t.
  • Log e sanificazione nomi file per gestione affidabile.
  • Compatibilità: solo Classic Outlook; per New Outlook usa Power Automate Desktop.

Con questi passaggi, la stampa automatica degli allegati torna operativa senza ricorrere a componenti esterni e con tutta la flessibilità dello scripting VBA.

Indice