Excel: salvare il foglio attivo in PDF nella stessa cartella (macro VBA completa)

Vuoi un tasto “Esporta in PDF” che salvi il foglio attuale nella stessa cartella della cartella di lavoro, senza dover cambiare percorso ogni volta? In questa guida trovi la macro VBA pronta all’uso, spiegata riga per riga, più varianti robuste per nomi file sicuri, conferma di sovrascrittura, stampa su un’unica pagina, sottocartelle “PDF”, uso con OneDrive/SharePoint e molto altro.

Indice

Panoramica del problema

Molte macro “base” per l’esportazione in PDF salvano per impostazione predefinita in Documenti. Questo diventa rapidamente scomodo in ambienti condivisi o su PC diversi, perché il percorso cambia da utente a utente. L’obiettivo è semplice: scrivere una macro che salvi il PDF nello stesso percorso del file Excel aperto, senza dover toccare percorsi assoluti.

Soluzione minima: esportare il foglio attivo in PDF nella stessa cartella

Questa è la macro essenziale che risolve il problema nella forma più semplice. Usa la cella B1 come nome file.

Sub SaveAsPDF()
    Dim saveLocation As String
    saveLocation = ActiveWorkbook.Path & "\" & Range("B1").Value & ".pdf"
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=saveLocation
End Sub
  • ActiveWorkbook.Path restituisce la cartella in cui è salvata la cartella di lavoro.
  • Range("B1").Value fornisce il nome del PDF.
  • ExportAsFixedFormat crea il PDF senza finestre di dialogo.

Funziona, ma è “nuda e cruda”: non gestisce file non ancora salvati, caratteri non validi nel nome, né la sovrascrittura. Per un utilizzo in ufficio è meglio una macro più robusta.

Versione robusta consigliata (pronta per l’uso quotidiano)

Questa macro include: controllo se il file è stato salvato, nomi file sicuri, conferma di sovrascrittura, messaggi chiari e compatibilità Windows/Mac grazie al separatore di percorso automatico.

Option Explicit

Public Sub SaveSheetAsPDF_Robusto(Optional ByVal UsaThisWorkbook As Boolean = False)
Dim wb As Workbook, ws As Object
Dim basePath As String, sep As String
Dim baseName As String, saveLocation As String
Dim reply As VbMsgBoxResult
```
On Error GoTo CleanFail

Set wb = IIf(UsaThisWorkbook, ThisWorkbook, ActiveWorkbook)
Set ws = ActiveSheet

' Verifica che l'oggetto attivo sia un foglio di lavoro
If TypeName(ws) <> "Worksheet" Then
    MsgBox "La macro funziona solo su fogli di lavoro. Seleziona un foglio e riprova.", vbExclamation
    Exit Sub
End If

sep = Application.PathSeparator
basePath = wb.Path

' Il file Excel deve essere già stato salvato almeno una volta
If Len(basePath) = 0 Then
    MsgBox "Salva prima la cartella di lavoro (File > Salva) e ripeti l'operazione.", vbExclamation
    Exit Sub
End If

' Nome base dal contenuto di B1, altrimenti usa nome foglio + timestamp
baseName = Trim$(CStr(ws.Range("B1").Value))
If Len(baseName) = 0 Then
    baseName = ws.Name & "_" & Format(Now, "yyyymmdd_hhnnss")
End If
baseName = CleanFileName(baseName)

saveLocation = basePath & sep & baseName & ".pdf"

' Conferma di sovrascrittura se il file esiste
If Dir(saveLocation) <> "" Then
    reply = MsgBox("Il file esiste già:" & vbCrLf & saveLocation & vbCrLf & _
                   "Vuoi sovrascriverlo?", vbYesNo + vbQuestion, "Conferma sovrascrittura")
    If reply = vbNo Then Exit Sub
End If

' Esporta in PDF rispettando l'Area di stampa eventualmente impostata
ws.ExportAsFixedFormat Type:=xlTypePDF, _
                       Filename:=saveLocation, _
                       Quality:=xlQualityStandard, _
                       IncludeDocProperties:=True, _
                       IgnorePrintAreas:=False, _
                       OpenAfterPublish:=False

MsgBox "PDF creato con successo:" & vbCrLf & saveLocation, vbInformation, "Completato"
Exit Sub
```
CleanFail:
MsgBox "Impossibile creare il PDF." & vbCrLf & _
"Errore " & Err.Number & ": " & Err.Description, vbCritical
End Sub

' --- Funzione di supporto: pulisce i caratteri non validi per i nomi file ---
Private Function CleanFileName(ByVal s As String) As String
Dim badChars As Variant, i As Long
badChars = Array("", "/", ":", "*", "?", """", "<", ">", "|")
For i = LBound(badChars) To UBound(badChars)
s = Replace$(s, badChars(i), "*")
Next
s = Trim$(s)
If Len(s) = 0 Then s = "PDF*" & Format(Now, "yyyymmdd_hhnnss")
CleanFileName = s
End Function 

Cosa fa in più questa versione

  • UsaThisWorkbook: se imposto a True, la macro salva nella cartella del file che contiene la macro (utile se lavori con più file aperti). Altrimenti usa l’ActiveWorkbook (default).
  • Separatore di percorso automatico: Application.PathSeparator gestisce correttamente \ (Windows) e / (macOS).
  • Nomi sicuri: CleanFileName elimina i caratteri non validi (< > : ” / \ | ? *).
  • Conferma di sovrascrittura: avvisa prima di rimpiazzare un PDF esistente.
  • Messaggi chiari: spiega se la cartella di lavoro non è stata salvata o se si verifica un errore.

Guida passo-passo: come inserire e usare la macro

  1. Salva il file Excel almeno una volta nella cartella desiderata (serve un percorso reale).
  2. Apri l’Editor VBA con ALT + F11.
  3. Nel riquadro “Progetto”, fai clic destro sul tuo file → Inserisci > Modulo.
  4. Incolla la macro “SaveSheetAsPDF_Robusto” nel modulo.
  5. Torna al foglio Excel e scrivi in B1 il nome del PDF (opzionale: se lasci vuoto, userà nome foglio + data/ora).
  6. Avvia la macro con Strumenti > Macro oppure collegala a un pulsante o alla Barra di Accesso Rapido per un clic.

Spiegazione dettagliata di ExportAsFixedFormat

ParametroDescrizioneValori utiliConsiglio
TypeFormato di esportazionexlTypePDF (PDF), xlTypeXPSUsa PDF per compatibilità universale
FilenamePercorso completo del file di outputEs. C:\Dati\Report.pdfComponilo con Workbook.Path + nome + estensione
QualityQualità/dimensione del PDFxlQualityStandard, xlQualityMinimumStandard per stampa/archivio, Minimum per invii email
IncludeDocPropertiesEsporta proprietà del documento (titolo, autore, ecc.)True/FalseLascia True salvo esigenze privacy
IgnorePrintAreasIgnora o rispetta l’Area di stampa del foglioTrue/FalseFalse per rispettare l’impaginazione definita
OpenAfterPublishApre o meno il PDF a fine esportazioneTrue/FalseImposta True se vuoi verificare subito il risultato

Personalizzazioni utili (copi&incolla)

Usare sempre la cartella del file che contiene la macro

Se vuoi che il PDF vada sempre accanto al file che contiene il codice (ad esempio in un componente aggiuntivo o un modello condiviso), richiama la procedura così:

Call SaveSheetAsPDF_Robusto(True) ' Usa ThisWorkbook.Path

Impostare stampa su una pagina (adatta in larghezza)

Per report più leggibili, forza la stampa su una pagina in larghezza e quante servono in altezza:

With ActiveSheet.PageSetup
    .Orientation = xlLandscape       ' Or xlPortrait
    .Zoom = False                    ' Disattiva lo zoom percentuale
    .FitToPagesWide = 1              ' Una pagina in larghezza
    .FitToPagesTall = False          ' Altezza libera (più pagine)
End With

Call SaveSheetAsPDF_Robusto 

Salvare in una sottocartella “PDF” accanto al file

Utile per tenere ordine. Il codice crea la cartella se non esiste.

Sub SaveToPDFSubfolder()
    Dim sep As String, basePath As String, pdfFolder As String
    Dim fn As String
```
sep = Application.PathSeparator
basePath = ActiveWorkbook.Path
If Len(basePath) = 0 Then
    MsgBox "Salva prima la cartella di lavoro.", vbExclamation
    Exit Sub
End If

pdfFolder = basePath &amp; sep &amp; "PDF"
If Dir(pdfFolder, vbDirectory) = "" Then MkDir pdfFolder

fn = CleanFileName(ActiveSheet.Range("B1").Value)
If Len(fn) = 0 Then fn = ActiveSheet.Name &amp; "_" &amp; Format(Now, "yyyymmdd_hhnnss")

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
    Filename:=pdfFolder &amp; sep &amp; fn &amp; ".pdf", _
    Quality:=xlQualityStandard, IncludeDocProperties:=True, _
    IgnorePrintAreas:=False, OpenAfterPublish:=False
```
End Sub 

Esportare solo un intervallo specifico

Imposta temporaneamente l’Area di stampa, esporta e ripristina.

Sub ExportRangeAsPDF(ByVal rngAddress As String)
    Dim ws As Worksheet, oldArea As String
    Set ws = ActiveSheet
```
oldArea = ws.PageSetup.PrintArea
ws.PageSetup.PrintArea = rngAddress

On Error GoTo SafeExit
Call SaveSheetAsPDF_Robusto
```
SafeExit:
ws.PageSetup.PrintArea = oldArea
End Sub

' Esempio d'uso:
' Call ExportRangeAsPDF("A1:G40") 

Esportare più fogli in un unico PDF

Quando selezioni più fogli, Excel crea un singolo PDF con tutti i fogli selezionati. Attenzione: la selezione dell’utente verrà momentaneamente modificata.

Sub ExportSelectedSheetsAsOnePDF()
    Dim arr, basePath As String, sep As String, baseName As String, saveLocation As String
```
arr = Array("Report", "Dati", "Cruscotto") ' &lt;-- modifica l'elenco

basePath = ActiveWorkbook.Path
If Len(basePath) = 0 Then
    MsgBox "Salva prima la cartella di lavoro.", vbExclamation
    Exit Sub
End If

sep = Application.PathSeparator
baseName = "Pacchetto_" &amp; Format(Now, "yyyymmdd_hhnnss")
saveLocation = basePath &amp; sep &amp; baseName &amp; ".pdf"

ThisWorkbook.Worksheets(arr).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=saveLocation, _
    Quality:=xlQualityStandard, IncludeDocProperties:=True, _
    IgnorePrintAreas:=False, OpenAfterPublish:=False

ThisWorkbook.Worksheets(1).Select ' ripristino una selezione singola
```
End Sub 

Ridurre il peso del file PDF

Per email o portali con limiti di dimensione, passa alla qualità minima:

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=saveLocation, _
    Quality:=xlQualityMinimum, IncludeDocProperties:=True, _
    IgnorePrintAreas:=False, OpenAfterPublish:=False

Aprire il PDF automaticamente dopo l’esportazione

OpenAfterPublish:=True

ThisWorkbook vs ActiveWorkbook: quale scegliere?

OggettoCosa rappresentaQuando usarlo
ThisWorkbookIl file che contiene la macroComponenti aggiuntivi, modelli condivisi, pulsanti “globali”
ActiveWorkbookIl file attivo in quel momentoMacro “locali” legate al file su cui stai lavorando

Riconoscere e gestire nomi file non validi

Windows e macOS vietano caratteri come < > : " / \ | ? * nei nomi. Se l’utente digita un nome non valido in B1, la macro “robusta” lo corregge automaticamente. Vuoi un comportamento ancora più esplicito? Aggiungi un avviso:

Dim rawName As String
rawName = CStr(ActiveSheet.Range("B1").Value)
If rawName &lt;&gt; CleanFileName(rawName) Then
    MsgBox "Alcuni caratteri non sono consentiti nel nome file. Verranno sostituiti con _", vbInformation
End If

Conferma di sovrascrittura: variante compatta

If Dir(saveLocation) &lt;&gt; "" Then
    If MsgBox("Il file esiste già. Sovrascrivere?", vbYesNo) = vbNo Then Exit Sub
End If

Compatibilità, percorsi e lavoro in cloud (Windows/macOS, OneDrive, SharePoint)

  • Separatore di percorso: usa sempre Application.PathSeparator. Evita di scrivere manualmente \ o /.
  • Cartella non salvata: se Workbook.Path è vuoto, è perché il file non è mai stato salvato. La macro si ferma e te lo segnala.
  • OneDrive/SharePoint: con i file sincronizzati in locale, Workbook.Path punta alla cartella sincronizzata e l’esportazione funziona regolarmente. Se invece lavori su un file aperto direttamente da URL (senza sync), alcune configurazioni possono restituire percorsi non file-system. In questi casi:
    • Sincronizza la libreria con l’app OneDrive/SharePoint, oppure
    • usa un fallback locale (es. “Download” o “Temp”) se rilevi un URL.

Fallback di esempio (salva in “Download” se il percorso contiene http):

Dim basePath As String, sep As String
sep = Application.PathSeparator
basePath = ActiveWorkbook.Path

If InStr(1, basePath, "http", vbTextCompare) > 0 Then
basePath = Environ$("USERPROFILE") & sep & "Downloads"
End If 

Perché il PDF finiva in “Documenti” (e come evitarlo sempre)

Se non specifichi un percorso completo nel parametro Filename, Excel usa la cartella predefinita (spesso Documenti). Costruendo il percorso come Workbook.Path & sep & NomeFile & ".pdf" forzi il salvataggio accanto al file Excel, indipendentemente dal PC o dall’utente.

Checklist di affidabilità

  • ✅ La cartella di lavoro è già stata salvata almeno una volta?
  • ✅ La cella B1 contiene un nome “pulito” (o usi un fallback)?
  • IgnorePrintAreas è impostato come desideri (rispettare l’impaginazione o ignorarla)?
  • ✅ Hai previsto la conferma di sovrascrittura in ambienti condivisi?
  • ✅ Usi Application.PathSeparator per evitare problemi Windows/macOS?

Troubleshooting (problemi comuni)

SintomoCausa probabileSoluzione rapida
Errore 1004 su ExportAsFixedFormatFile mai salvato, nome file con caratteri non validi, foglio non è un WorksheetSalva il file Excel; usa CleanFileName; verifica che il foglio attivo non sia un grafico
Il PDF finisce in “Documenti”Filename senza percorso assolutoComponi il percorso con Workbook.Path + nome + .pdf
Impaginazione sballataNessuna Area di stampa o impostazioni pagina errateDefinisci Area di stampa; usa FitToPagesWide e margini coerenti
Dimensione PDF troppo grandeQualità standard, immagini ad alta risoluzionexlQualityMinimum, valuta la riduzione delle immagini o la stampa in bianco/nero
PDF sovrascritto senza avvisoManca il controllo Dir()Aggiungi il check di esistenza con conferma utente

FAQ rapide

Posso usare un nome file dinamico con data/utente?
Sì. Esempio: baseName = ActiveSheet.Name & "" & Format(Date, "yyyymmdd") & "" & Environ$("Username").

Posso esportare l’intera cartella di lavoro in un unico PDF?
Sì: ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:=... esporta tutti i fogli (rispettando l’ordine).

La macro funziona anche su Mac?
Sì, evitando separatori “hardcoded”. Usa Application.PathSeparator come in questa guida.

Come collego la macro a un pulsante nel foglio?
Inserisci una Forma (Inserisci > Illustrazioni > Forme), clic destro > Assegna macro > scegli la macro.

Posso far scegliere all’utente il nome o la cartella?
Sì, con un InputBox o con Application.GetSaveAsFilename (mostra la finestra Salva con nome). Per questa guida ci concentriamo sul salvataggio automatico nella stessa cartella.

Esempi completi da copiare

Esempio A — Macro “pronto ufficio” + impaginazione

Sub PDF_OneClick()
    With ActiveSheet.PageSetup
        .Orientation = xlLandscape
        .Zoom = False
        .FitToPagesWide = 1
        .FitToPagesTall = False
        .LeftMargin = Application.CentimetersToPoints(1)
        .RightMargin = Application.CentimetersToPoints(1)
        .TopMargin = Application.CentimetersToPoints(1)
        .BottomMargin = Application.CentimetersToPoints(1)
    End With
    Call SaveSheetAsPDF_Robusto
End Sub

Esempio B — Nome file da B1 con fallback intelligente

Sub PDFFromB1WithFallback()
    Dim nm As String
    nm = Trim$(CStr(ActiveSheet.Range("B1").Value))
    If Len(nm) = 0 Then nm = ActiveSheet.Name &amp; "" &amp; Format(Now, "yyyymmddhhnnss")
    ActiveSheet.Range("B1").Value = nm ' scrivo il nome così resta visibile all'utente
    Call SaveSheetAsPDF_Robusto
End Sub

Esempio C — Creare (se serve) una sottocartella per mese

Per archiviare i PDF in YYYY-MM (es. 2025-10):

Sub SavePDF_ToMonthlyFolder()
    Dim sep As String, basePath As String, monthly As String
    Dim fn As String
```
sep = Application.PathSeparator
basePath = ActiveWorkbook.Path
If Len(basePath) = 0 Then
    MsgBox "Salva prima la cartella di lavoro.", vbExclamation
    Exit Sub
End If

monthly = basePath &amp; sep &amp; Format(Date, "yyyy-mm")
If Dir(monthly, vbDirectory) = "" Then MkDir monthly

fn = CleanFileName(ActiveSheet.Range("B1").Value)
If Len(fn) = 0 Then fn = ActiveSheet.Name &amp; "_" &amp; Format(Now, "yyyymmdd_hhnnss")

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
    Filename:=monthly &amp; sep &amp; fn &amp; ".pdf", _
    Quality:=xlQualityStandard, IncludeDocProperties:=True, _
    IgnorePrintAreas:=False, OpenAfterPublish:=False
```
End Sub 

Buone pratiche per team e ambienti condivisi

  • Evita percorsi hardcoded (es. C:\Utenti\Mario\Documenti). Usa il percorso del file aperto.
  • Uniforma la stampa: definisci margini e ripeti righe d’intestazione (Imposta pagina > Riga di intestazione da ripetere).
  • Documenta le convenzioni (es. nome da B1, sottocartella “PDF”). Meno ambiguità = meno errori.
  • Gestisci la privacy: con IncludeDocProperties:=False se non vuoi allegare metadati.
  • Controlla i caratteri dei nomi provenienti da formule o da input utente.

Conclusioni

Con poche righe di VBA puoi standardizzare l’export dei report in modo che ogni PDF venga salvato accanto al file Excel, senza sorprese. Parti dalla macro minima se ti serve solo il necessario, oppure adotta la versione “robusta” per un ambiente di lavoro affidabile, con nomi sicuri, conferma di sovrascrittura, impaginazione coerente e compatibilità Windows/macOS e cloud. In questo modo elimini la dipendenza da percorsi fissi e rendi la procedura portabile su qualsiasi postazione.


Codice “base” dall’articolo in un colpo d’occhio

' Soluzione minimale
Sub SaveAsPDF()
    Dim saveLocation As String
    saveLocation = ActiveWorkbook.Path & "\" & Range("B1").Value & ".pdf"
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=saveLocation
End Sub

' Suggerimenti extra:
' 1) Usa ThisWorkbook.Path se vuoi riferirti al file che contiene la macro
' 2) Controllo se non salvato:
'    If ActiveWorkbook.Path = "" Then MsgBox "Salva prima la cartella di lavoro.": Exit Sub
' 3) Nome file sicuro: sostituisci caratteri non ammessi (< > : " / \ | ? *)
' 4) Conferma sovrascrittura:
'    If Dir(saveLocation) <> "" Then
'        If MsgBox("Il file esiste già. Sovrascrivere?", vbYesNo) = vbNo Then Exit Sub
'    End If 

Con questi accorgimenti la macro diventa davvero solida e portabile, pronta per l’uso quotidiano in team.

Indice