Automate PDF Creation from Excel Macros
This code example will show you how to automate PDF printing from a Microsoft Excel macro.
You will see how you can locate the correct printer name and use the COM interface to
automate the printer settings. It only shows you the basics, but you can build your own
functionality using this example as an inspiration.
Sub PrintSheetAsPDF()
Dim obj_printer_settings As Object
Dim save_path As String
Dim file_name As String
Dim current_printer As String
Dim xmldom As Object
Dim progid As String
Dim printername As String
Rem -- Read the info xml
Set xmldom = CreateObject("MSXML.DOMDocument")
If Not xmldom.Load(ActiveWorkbook.Path & "\info.xml") Then
MsgBox "Error loading info.xml from """ & ActiveWorkbook.Path & """.", vbCritical
Exit Sub
End If
Rem -- Get the program id of the automation object.
progid = xmldom.SelectSingleNode("/xml/progid").Text
Rem -- Create the object to control the printer settings
Set obj_printer_settings = CreateObject(progid)
Rem -- Get default printer name
printername = obj_printer_settings.GetPrinterName
Rem -- Get the full name of the printer
Dim full_printer_name As String
full_printer_name = FindPrinter(printername)
full_printer_name = GetFullNetworkPrinterName(full_printer_name)
Rem -- Prompt the user for a file name
save_path = Environ("USERPROFILE") & "\Desktop\"
file_name = InputBox("Save PDF to desktop as:", "Sheet '" & _
ActiveSheet.Name & "' to PDF...", ActiveSheet.Name)
Rem -- Abort the process if the user cancels the dialog
If file_name = "" Then Exit Sub
Rem -- Make sure that the file name ends with .pdf
If LCase(Right(file_name, 4)) <> ".pdf" Then
file_name = file_name & ".pdf"
End If
Rem -- Write the settings to the printer
Rem -- Settings are written to the runonce.ini
Rem -- This file is deleted immediately after being used.
With obj_printer_settings
.SetValue "output", save_path & file_name
.SetValue "showsettings", "never"
.WriteSettings True
End With
Rem -- Change to PDF printer
current_printer = ActivePrinter
ActivePrinter = full_printer_name
Rem -- Print the active work sheet
ActiveSheet.PrintOut
Rem -- Restore the printer selection
ActivePrinter = current_printer
End Sub
Function GetFullNetworkPrinterName(NetworkPrinterName As String) As String
Rem -- Returns the full network printer name
Rem -- Returns an empty string if the printer is not found
Rem -- E.g. GetFullNetworkPrinterName("HP LaserJet 8100 Series PCL")
Rem -- Might return "BIOPDF on Ne04:"
Dim current_printer_name As String
Dim temp_printer_name As String
Dim i As Long
current_printer_name = Application.ActivePrinter
i = 0
Do While i < 100
temp_printer_name = NetworkPrinterName & " on Ne" & _
Format(i, "00") & ":"
On Error Resume Next
Rem -- Try to change to the network printer
Application.ActivePrinter = temp_printer_name
On Error GoTo 0
If Application.ActivePrinter = temp_printer_name Then
Rem -- The network printer was found
GetFullNetworkPrinterName = temp_printer_name
Exit Do
End If
i = i + 1
Loop
Application.ActivePrinter = current_printer_name
End Function
Function FindPrinter(PrinterNameFragment As String) As String
Rem -- Find the full printer name base on a fragment of the name
Rem -- Use the GetFullNetworkPrinterName function to get the NeXX
Rem -- part of the name.
Dim wsh As Object
Dim printer
Dim printercoll
Dim i As Integer
Set wsh = CreateObject("WScript.Network.1")
Set printercoll = wsh.EnumPrinterConnections
For i = 1 To printercoll.Count - 1 Step 2
If InStr(1, LCase(printercoll(i)), LCase(PrinterNameFragment)) _
> 0 Then
FindPrinter = printercoll(i)
Exit Function
End If
Next
End Function
Download Example Files
You can download and run the example yourself. The files needed are available here.
Example files (zip archive)
|