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.
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
- Salva il file Excel almeno una volta nella cartella desiderata (serve un percorso reale).
- Apri l’Editor VBA con ALT + F11.
- Nel riquadro “Progetto”, fai clic destro sul tuo file → Inserisci > Modulo.
- Incolla la macro “SaveSheetAsPDF_Robusto” nel modulo.
- Torna al foglio Excel e scrivi in B1 il nome del PDF (opzionale: se lasci vuoto, userà nome foglio + data/ora).
- Avvia la macro con Strumenti > Macro oppure collegala a un pulsante o alla Barra di Accesso Rapido per un clic.
Spiegazione dettagliata di ExportAsFixedFormat
Parametro | Descrizione | Valori utili | Consiglio |
---|---|---|---|
Type | Formato di esportazione | xlTypePDF (PDF), xlTypeXPS | Usa PDF per compatibilità universale |
Filename | Percorso completo del file di output | Es. C:\Dati\Report.pdf | Componilo con Workbook.Path + nome + estensione |
Quality | Qualità/dimensione del PDF | xlQualityStandard , xlQualityMinimum | Standard per stampa/archivio, Minimum per invii email |
IncludeDocProperties | Esporta proprietà del documento (titolo, autore, ecc.) | True /False | Lascia True salvo esigenze privacy |
IgnorePrintAreas | Ignora o rispetta l’Area di stampa del foglio | True /False | False per rispettare l’impaginazione definita |
OpenAfterPublish | Apre o meno il PDF a fine esportazione | True /False | Imposta 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 & sep & "PDF"
If Dir(pdfFolder, vbDirectory) = "" Then MkDir pdfFolder
fn = CleanFileName(ActiveSheet.Range("B1").Value)
If Len(fn) = 0 Then fn = ActiveSheet.Name & "_" & Format(Now, "yyyymmdd_hhnnss")
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=pdfFolder & sep & fn & ".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") ' <-- 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_" & Format(Now, "yyyymmdd_hhnnss")
saveLocation = basePath & sep & baseName & ".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?
Oggetto | Cosa rappresenta | Quando usarlo |
---|---|---|
ThisWorkbook | Il file che contiene la macro | Componenti aggiuntivi, modelli condivisi, pulsanti “globali” |
ActiveWorkbook | Il file attivo in quel momento | Macro “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 <> 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) <> "" 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)
Sintomo | Causa probabile | Soluzione rapida |
---|---|---|
Errore 1004 su ExportAsFixedFormat | File mai salvato, nome file con caratteri non validi, foglio non è un Worksheet | Salva il file Excel; usa CleanFileName ; verifica che il foglio attivo non sia un grafico |
Il PDF finisce in “Documenti” | Filename senza percorso assoluto | Componi il percorso con Workbook.Path + nome + .pdf |
Impaginazione sballata | Nessuna Area di stampa o impostazioni pagina errate | Definisci Area di stampa; usa FitToPagesWide e margini coerenti |
Dimensione PDF troppo grande | Qualità standard, immagini ad alta risoluzione | xlQualityMinimum , valuta la riduzione delle immagini o la stampa in bianco/nero |
PDF sovrascritto senza avviso | Manca 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 & "" & 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 & sep & 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 & "_" & Format(Now, "yyyymmdd_hhnnss")
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=monthly & sep & fn & ".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.