One of the most common word-processing related task for academics is to generate PDF versions of documents — for sharing with colleagues, for submission to a journal, for uploading to a publication page, et cetera. In LaTex, creating PDFs is a question of one simple command (plus a bit of fiddling with settings). In recent versions of Word, it is also pretty simple: just Save as… and select PDF. But that option is buried in the ribbon interface and involves quite a number of clicks. I generate PDFs practically everyday, so I wanted something easier. Enter Word macros.
The macros below do only one thing: they save the currently open file as PDF, by default in the same folder, with the same file name. The first will provide you with the option to change file name and location, the second is a straight export, no questions asked. Pick whichever one you like and add it to Word. Some steps for adding it as a button to a toolbar follow below.
Hang on, where do I put this code?, you ask. You can find out how to add a macro to Word here. Basically you create a new macro and paste the below code into it, then save. I could provide you with a downloadable .dot(x) file but that would only get you into trouble with all sorts of security restrictions in your browser or in Word, so doing it this way is easier.
Macro 1: Using the ‘Save as…’ window
This macro essentially just calls up the ‘Save as…’ window and pre-selects the PDF format. It will suggest a filename, which you can change; and it will warn you when you’re about to overwrite an existing file.
Sub Save_to_PDF()
'
' Save_to_PDF Macro
'
'
With Dialogs(wdDialogFileSaveAs)
.Format = wdFormatPDF
.Show
End With
End Sub
Macro 2: No questions asked
This macro (from here, with helpful amendments by readers) goes straight for exporting. It won’t ask you anything and won’t warn you if a file is overwritten (which to me is precisely the point — I want the PDF always to correspond to the most recent version of the document).
Sub Silent_save_to_PDF()
'
' Silent Save_to_PDF Macro
'
ActiveDocument.ExportAsFixedFormat OutputFileName:= _
Replace(ActiveDocument.FullName, ".docx", ".pdf") , _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, Item:= _
wdExportDocumentContent, IncludeDocProps:=False, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
End Sub
Advanced users will note that they can customize the output somewhat by changing the export settings. For instance, if you use it mainly for journal submissions, you might want to set IncludeDocProps
to False
.
Adding your macro to the Quick Access Toolbar
Now we want to pick one of the macros and add it to a menu for true one-click access. I like the ‘quick access toolbar’ best for this purpose — this is where my Zotero buttons are as well. Here’s how:
- Right-click the quick access toolbar, choose ‘Customize Quick Access Toolbar’
- In the menu that appears, under “Choose commands from”, pick “Macros”. You’ll see your macro appear in the list.
- Select your macro (either version 1 or version 2) and click the Add >> button. With the up and down buttons on the right you can position it further; I like mine just next to the normal Save button.
- It’ll already work this way. If you’re a perfectionist like me, select your macro in the right column, click ‘Modify…’ and select an icon you like.
Voilá! You have your one-click “Save to PDF” button in Word.
38 responses to “One-click Save as PDF from Word: two useful macros”
Really helpful, thanks :)
Thanks!! Save a lot of time!!
Thank you. Thank you. Great tool. It reduces the frustration level of using Office’s brain-dead File, Save screens.
Your second macro fails if the path has a period. Change to:
.ExportAsFixedFormat OutputFileName:=Mid(ActiveDocument.FullName, 1, InStrRev(ActiveDocument.FullName, “.”)) & “.pdf”, _
@Tom, fixed, thanks!
Your version of the macro would be as follows:
Sub Silent_save_to_PDF()
'
' Silent Save_to_PDF Macro
'
With ActiveDocument
.ExportAsFixedFormat OutputFileName:=Mid(ActiveDocument.FullName, 1, InStrRev(ActiveDocument.FullName, “.”)) & “.pdf”, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, _
OptimizeFor:=wdExportOptimizeForPrint, Range:=wdExportAllDocument, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
End With
End Sub
Hi. I have been looking for EXACTLY this! But when I run the second macro i get this error message “Application-defined of object-defined error”. I use 2011 for mac, if that has any relevance.
Hi Erik, does Tom’s version (above) work?
For me the second version fails.
I’ve solved it like this:
Sub Print_to_PDF()
ActiveDocument.ExportAsFixedFormat OutputFileName:= _
Replace(ActiveDocument.FullName, ".docx", ".pdf") , _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, Item:= _
wdExportDocumentContent, IncludeDocProps:=False, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
End Sub
Hi,
This is really excellent, but how could I add a certain location the .pdf will be saved to? The thing is that a part of my job is to open external files and save them to .pdf format in order to process them further. So, I’d like to skip the step of saving the .doc/.docx format by adding a location string to the macro, so it would be saved there as .pdf. But I don’t know how, yet.
Try the “Silent_save_to_PDF()” macro also mentioned in the post. This will save a PDF file in the same folder as where your .docx is. Then Google for how to set file location — I don’t know it from the top of my head but it can’t be hard.
Dear Mark,
Thank you for your excellent post !
I get this error, and do not understand why:
Run-time error ‘-2147467259 (80004005)’ :
The export failed because this feature is not installed.
Do you have any idea ?
Regards,
Hi André — sorry, no idea. Sounds like you may not have the right support for creating Adobe PDF on your system.
Thanks a lot,
please i would also that the file is opened automatically in the default pdf reader .How can i do this ?
simply i have to change the options: OpenAfterExport:=True
really nice, clean macro
Hi,
Thanks! It helped a lot.
Need further help how exported Pdf could be password protected.
here’s one I pieced together from several that I found and added a little myself, it will save to network location as PDF, add the date to the file name, and email it automatically.
strPath = “Enter network location to save to”
StrDate = Trim(Format(Now(), “ddmmyyyy”))
strName = Left(ActiveDocument.FullName, Len(ActiveDocument.FullName) – 4)
strName = strName & StrDate & “.PDF”
docName = “Enter Document name ” & StrDate
strAtta = strPath & docName
Dim outl As Object
Dim Mail As Object
ActiveDocument.SaveAs
ActiveDocument.ExportAsFixedFormat OutputFileName:=strPath & docName, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:=wdExportOptimizeForPrint, _
Range:=wdExportAllDocument, Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=True
Set outl = CreateObject(“Outlook.Application”)
Set Mail = outl.CreateItem(0)
Mail.Subject = “Enter Subject” & StrDate
Mail.Body = “Enter text” & StrDate
Mail.To = “Enter Recipient”
Mail.CC = “Enter Recipient”
Mail.Attachments.Add strAtta & “.PDF”
Mail.Display *can be set to send*
I wanted the second macro exactly, works great for me !
Thanks a lot Mark :)
I created a macro to save the document in PDF so that each page is stored separately, the file name given is the same as the name of the Word + the page number.
Sub SaveOneToPDF()
‘ Save one page to one document
Dim NumPages As Long
Dim i As Long
‘ How many pages in the document
i = 1
NumPages = ActiveDocument.ComputeStatistics(wdStatisticPages)
Dim pathName As String
Dim o As Document
Set o = ActiveDocument
If InStrRev(o.Name, “.”) 0 Then
pathName = Left(o.Name, InStrRev(o.Name, “.”) – 1)
Else
pathName = o.Name
End If
‘ Each page is saved as a PDF
While NumPages >= i ‘ “i” use as pagenumber
‘ OpenAfterExport:=False OR true
ActiveDocument.ExportAsFixedFormat OutputFileName:= _
ActiveDocument.Path & “\” & pathName & “.p” & i & “.pdf”, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportFromTo, From:=i, To:=i, Item:= _
wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
i = i + 1
Wend
End Sub
Thank you so much! I wish MS Word didn’t make simple, useful tasks take so many clicks in Word! Your macro is a real time saver! Thanks!
Thks for this sample code.
I liked (and used!) Alex’s work above (THANKS!), but there were some typo and font issues. Here’s a cleaned up version to save each page to a separate PDF–helpful with MailMerges of invoices, or similar:
Sub SaveEachPgToPDF()
‘ Save each page of the current DOC to a PDF document
Dim NumPages, i As Long
Dim pathName As String
Dim o As Document
NumPages = ActiveDocument.ComputeStatistics(wdStatisticPages)
Set o = ActiveDocument
If InStrRev(o.Name, “.”) > 0 Then
pathName = Left(o.Name, InStrRev(o.Name, “.”) – 1)
Else
pathName = o.Name
End If
‘ PDF files will use existing doc name, with .p1, .p2, etc appended
For i = 1 To NumPages
OutFileName = o.Path & “\” & pathName & “.p” & i & “.pdf”
o.ExportAsFixedFormat _
OutputFileName:=OutFileName, _
ExportFormat:=wdExportFormatPDF, _
OpenAfterExport:=False, _
OptimizeFor:=wdExportOptimizeForPrint, _
Range:=wdExportFromTo, From:=i, To:=i, _
Item:=wdExportDocumentContent, _
IncludeDocProps:=True, _
KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, _
DocStructureTags:=True, _
BitmapMissingFonts:=True, _
UseISO19005_1:=False
Next i
End Sub
Thank you for the scripts. Also for the suggestion to change the icon of the added macros.
I found another easy method at microsoft tutorials website at http://www.microsofttut.com/2017/03/how-to-convert-docx-file-to-pdf-and.html. am sure it will also help you!
works for me, thanks
Hi,
Is there anyone who can make example 2 with these changes for me?
1. Save to chosen path
2. Save only current page
3. Name of PDF – DateandTime+CustomerName (taken form a mergefield)
Thanks a lot
Would there be a way to set the options for creating the PDF? I regularly create estimates in word and page one is my worksheet while pages 2/3 are what I want to save as a PDF. Your macro works great but this step would save a lot of extra steps deleting the page from the PDF. I could use the one with the save as dialogue but that would be more steps again.
Great work I must say. Thanks for this even as it is now.
HI
I have a word document that has 2 pages,
currently the 1st page; will save to convert to pdf, save to sharepoint, email group email and single email. I just need a hand identifing where i need to insert, the code for a single page and then the document.
1st page is to be pdf’d separately and saved to sharepoint folder and emailed to a group
the 1st and second pages are to be emailed as a word document to a email address.
how do i go about identifying the separate pages.
see below for the code for the 1st page as it is at the moment.
the change is the addition of the 2nd page and sending via email as a word. the 2nd page can not go on the first email out.
Option Explicit
Dim strFilename As String
Sub SaveAndSend()
Dim strDate As String
Dim strNoti As String
Dim strTitle As String
strDate = ActiveDocument.SelectContentControlsByTag(“EventDate”).Item(1).Range.Text
If IsDate(strDate) Then
strDate = Format(strDate, “yyyy-mm-dd”)
Else
MsgBox “Please select an event date.”, vbExclamation, “Date Error”
Exit Sub
End If
strNoti = ActiveDocument.SelectContentControlsByTag(“NotificationNumber”).Item(1).Range.Text
strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text
If Not IsNumeric(strNoti) Or Len(strNoti) 9 Then
MsgBox “Please enter a valid notification number.”, vbExclamation, “Notification Error”
Exit Sub
End If
If Left(strTitle, 5) = “Enter” Then
MsgBox “Please enter short text.”, vbExclamation, “Title Not Entered”
Exit Sub
End If
strFilename = strDate & ” ” & strNoti & ” ” & strTitle & “.pdf”
ActiveDocument.SaveAs FileName:= _
“https://spo.bhpb.com/sites/COLMTAmacdata/Event%20Notifications/” & strFilename, FileFormat:=wdFormatPDF
ActiveDocument.SaveAs FileName:= _
“\\necmacfil01\bcc_data\Transfer\Events\” & strFilename, FileFormat:=wdFormatPDF
Call SendDocumentAsAttachment
End Sub
Sub SendDocumentInMail()
Dim oOutlookApp As Outlook.Application
Dim oItem As Outlook.MailItem
On Error Resume Next
‘Start Outlook if it isn’t running
Set oOutlookApp = GetObject(, “Outlook.Application”)
If Err 0 Then
Set oOutlookApp = CreateObject(“Outlook.Application”)
End If
‘Create a new message
Set oItem = oOutlookApp.CreateItem(olMailItem)
‘Copy the open document
Selection.WholeStory
Selection.Copy
Selection.End = True
‘Set the WordEditor
Dim objInsp As Outlook.Inspector
Dim wdEditor As Word.Document
Set objInsp = oItem.GetInspector
Set wdEditor = objInsp.WordEditor
‘Count Characters in Signature
Dim lngCharCount As Long
lngCharCount = wdEditor.Characters.Count
‘Paste Doc at start of email
wdEditor.Characters(1).PasteAndFormat (wdFormatOriginalFormatting)
‘Insert a page break prior to signature
wdEditor.Characters(wdEditor.Characters.Count – lngCharCount + 1).InsertBreak Type:=wdPageBreak
‘Set Subject and recipients
oItem.Subject = strFilename
oItem.To = “DL-COL-NEC-MACEventNotification@bhpb.com”
‘oItem.To = “daniel.h.smith@bhpb.com”
‘Display the message
oItem.Display
‘Clean up
Set oItem = Nothing
Set oOutlookApp = Nothing
Set objInsp = Nothing
Set wdEditor = Nothing
End Sub
Sub SendDocumentAsAttachment()
Dim strDate As String
Dim strNoti As String
Dim strTitle As String
strDate = ActiveDocument.SelectContentControlsByTag(“EventDate”).Item(1).Range.Text
If IsDate(strDate) Then
strDate = Format(strDate, “yyyy-mm-dd”)
Else
MsgBox “Please select an event date.”, vbExclamation, “Date Error”
Exit Sub
End If
strNoti = ActiveDocument.SelectContentControlsByTag(“NotificationNumber”).Item(1).Range.Text
strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text
If Not IsNumeric(strNoti) Or Len(strNoti) 9 Then
MsgBox “Please enter a valid notification number.”, vbExclamation, “Notification Error”
Exit Sub
End If
If Left(strTitle, 5) = “Enter” Then
MsgBox “Please enter short text.”, vbExclamation, “Title Not Entered”
Exit Sub
End If
strFilename = strDate & ” ” & strNoti & ” ” & strTitle & “.pdf”
Dim bStarted As Boolean
Dim oOutlookApp As Outlook.Application
‘You’ll need to add the Outlook Object Library to VBA Tools References
Dim oItem As Outlook.MailItem
strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text
On Error Resume Next
If Len(ActiveDocument.Path) = 0 Then ‘Document has not been saved
‘so save it
‘ ActiveDocument.Save
End If
‘see if Outlook is running and if so turn your attention there
Set oOutlookApp = GetObject(, “Outlook.Application”)
If Err 0 Then ‘Outlook isn’t running
‘So fire it up
Set oOutlookApp = CreateObject(“Outlook.Application”)
bStarted = True
End If
‘Open a new e-mail message
Set oItem = oOutlookApp.CreateItem(olMailItem)
With oItem ‘and add the detail to it
.To = “DL-COL-NEC-MACEventNotification@bhpb.com” ‘send to this address
.CC = “”
‘.BCC = “”
.Subject = strDate & ” ” & strNoti & ” ” & strTitle ‘This is the message subject
.Attachments.Add Source:=”\\necmacfil01\bcc_data\Transfer\Events\” & strFilename
.Display
End With
‘If bStarted Then ‘If the macro started Outlook, stop it again.
‘ oOutlookApp.Quit
‘End If
‘Clean up
Set oItem = Nothing
Set oOutlookApp = Nothing
End Sub
Thank you so much for these codes. I tried using the “record Macro” function and could not get this to work at all. The code for Macro 1 worked well. The Macro 2 needed a little tweaking since it was a little off from the reference page.
With ActiveDocument
.ExportAsFixedFormat OutputFileName:=Split(.FullName, “.”)(0) & “.pdf”, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, _
OptimizeFor:=wdExportOptimizeForPrint, Range:=wdExportAllDocument, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
End With
merci beaucoup ! helpful.
luc
Thank you.
Hi!
One person on stackoverflow helped to modify your macros so it automatically exports word as PDF to the same folder (no questions asked). But I was wondering whether it is possible to also export it as secure / locked for editing PDF. Any suggestions?
Here is the modified version (works in Word 2011 and 2016 on Mac):
Sub SaveActiveDocAsPDF()
On Error Resume Next
Dim saveName As String
saveName = ActiveDocument.FullName
saveName = Left(saveName, Len(saveName) – 5) & “.pdf”
ActiveDocument.SaveAs FileName:=saveName, _
FileFormat:=wdFormatPDF
End Sub
Thanks for sharing.
Brilliant – exactly what I needed. Now I’m just regretting that I’ve been clicking a million buttons for so many years.
Thank you Mark, these macros are gold. I can’t live without them anymore.
A little tip I would give is to assign a shortcut to it by:
– Under “Developer” tab, click “Record Macro”
– Give the name you want, then click “Keyboard” option below
– On the “Customize Keyboard” window, select the key sequence you want
– Click on “Macros” under the “Developer” tab to run the Macro created by Mark while recording
– Run it
– Then just stop recording the Macro
Voila, you have a shortcut key to save your document to PDF.
HI All,
I’m looking to save the PDF and Word doc as new filenames at once.
So far, I can only get the PDF to save-as, but docx just saves as the existing filename.
Any help. Method 1
Thank you!
Thank you for the silent one macro!
I am using doc not docx so I changed the relevant line to doc to make it work
Replace(ActiveDocument.FullName, “.doc”, “.pdf”), _
but it would be nice if it worked with both doc and docx.