Excel VBA code to work on Mac, Create PDF Function - excel

I have coded the following function. However, I cannot get it to work on office Mac. I am not sure of the procedure to find the EXP_PDF.DLL mac equivalent
Function Create_PDF(Myvar As Object, FixedFilePathName As String, _
OverwriteIfFileExist As Boolean, OpenPDFAfterPublish As Boolean) As String
Dim FileFormatstr As String
Dim FName As Variant
'Test If the Microsoft Add-in is installed
If Dir(Environ("commonprogramfiles") & "\Microsoft Shared\OFFICE" _& Format(Val(Application.Version), "00") & "\EXP_PDF.DLL") <> "" Then
If FixedFilePathName = "" Then
'Open the GetSaveAsFilename dialog to enter a file name for the pdf
FileFormatstr = "PDF Files (*.pdf), *.pdf"
FName = Application.GetSaveAsFilename("", filefilter:=FileFormatstr, _ Title:="Create PDF")
'If you cancel this dialog Exit the function
If FName = False Then Exit Function
Else
FName = FixedFilePathName
End If
'If OverwriteIfFileExist = False we test if the PDF
'already exist in the folder and Exit the function if that is True
If OverwriteIfFileExist = False Then
If Dir(FName) <> "" Then Exit Function
End If
'Now the file name is correct we Publish to PDF
On Error Resume Next
Myvar.ExportAsFixedFormat _
Type:=xlTypePDF, _
FileName:=FName, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=OpenPDFAfterPublish
On Error GoTo 0
'If Publish is Ok the function will return the file name
If Dir(FName) <> "" Then Create_PDF = FName
End If
End Function

There is no need to check for the existence of that specific DLL, because under MacOS, PDF export support is native. Your code simply works if you remove the Add-in check and remove the FileFilter string:
Function Create_PDF(Myvar As Object, FixedFilePathName As String, _
OverwriteIfFileExist As Boolean, OpenPDFAfterPublish As Boolean) As String
Dim FileFormatstr As String
Dim FName As Variant
If FixedFilePathName = "" Then
'Open the GetSaveAsFilename dialog to enter a file name for the pdf
FName = Application.GetSaveAsFilename("", Title:="Create PDF")
'If you cancel this dialog Exit the function
If FName = False Then Exit Function
Else
FName = FixedFilePathName
End If
'If OverwriteIfFileExist = False we test if the PDF
'already exist in the folder and Exit the function if that is True
If OverwriteIfFileExist = False Then
If Dir(FName) <> "" Then Exit Function
End If
'Now the file name is correct we Publish to PDF
On Error Resume Next
Myvar.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=FName, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=OpenPDFAfterPublish
On Error GoTo 0
'If Publish is Ok the function will return the file name
If Dir(FName) <> "" Then Create_PDF = FName
End Function
But GetSaveAsFilename is crippled on MacOS and does not allow filtering files by filetype. If you need to restrict users to a certain filetype, you can resort to AppleScript and do the following:
Function Create_PDF_Mac(Myvar As Object, FixedFilePathName As String, _
OverwriteIfFileExist As Boolean, OpenPDFAfterPublish As Boolean) As String
Dim FileFormatstr As String
Dim FName As Variant
If FixedFilePathName = "" Then
'Open the GetSaveAsFilename dialog to enter a file name for the pdf
'FName = Application.GetSaveAsFilename("", ".PDF", Title:="Create PDF")
On Error Resume Next
ThePath = MacScript("return (path to documents folder) as String")
TheScript = _
"set applescript's text item delimiters to "","" " & vbNewLine & _
"set theFile to (choose file name with prompt ""Save As File"" " & _
"default name ""untitled.pdf"" default location alias """ & _
ThePath & """ ) as string" & vbNewLine & _
"if theFile does not end with "".pdf"" then set theFile to theFile & "".pdf"" " & vbNewLine & _
"set applescript's text item delimiters to """" " & vbNewLine & _
"return theFile"
FName = MacScript(TheScript)
On Error GoTo 0
'If you cancel this dialog Exit the function
If FName = False Then Exit Function
Else
FName = FixedFilePathName
End If
'If OverwriteIfFileExist = False we test if the PDF
'already exist in the folder and Exit the function if that is True
If OverwriteIfFileExist = False Then
If Dir(FName) <> "" Then Exit Function
End If
'Now the file name is correct we Publish to PDF
On Error Resume Next
Myvar.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=FName, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=OpenPDFAfterPublish
On Error GoTo 0
'If Publish is Ok the function will return the file name
If Dir(FName) <> "" Then Create_PDF = FName
End Function
The you can use an OS selector switch to run the appropriate function for each OS:
#If Mac Then
savedFileName = Create_PDF_Mac(...)
#Else
savedFileName = Create_PDF_PC(...)
#End If
Given the limitations of default VB functions in MacOS, this is Microsof't suggested method as well.

Here is a guide on how you can do it in newer versions of Mac Excel: https://www.rondebruin.nl/mac/mac034.htm
What's important is that you can't save your file to a location that is selected by you.
It has to be saved to the folder Library/Group Containers/UBF8T346G9.Office under the current user's home dir, so /Users/[current user]/Library/Group Containers/UBF8T346G9.Office in most of the cases. If the folder is not there, you have to create it. (See the code example on the page linked above)
Kudos to Ron!
Please vote for this to be fixed by MS here: https://excel.uservoice.com/forums/304933-excel-for-mac/suggestions/36531559-fix-exportasfixedformat-method

Related

Excel VBA printing to PDF

I am trying to set the default printer when printing to PDF but getting the error "Method ActivePrinter of object _application failed"
Application.ActivePrinter = "Microsoft Print to PDF"
With ActiveSheet.PageSetup
.PaperSize = xlPaperA4
End With
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, FileName:= _
"C:\Users\" & Environ$("UserName") & "\Downloads\" & Replace(Worksheets("test").Cells(1, 1), ".", "") & ".pdf", Quality:=xlQualityStandard, IncludeDocProperties:=False, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
How can I set the printer to Microsoft Print to PDF?
Please, copy the next function in a standard module:
Function FindPrinter(ByVal PrinterName As String) As String
Dim arrH, Pr, Printers, Printer As String
Dim RegObj As Object, RegValue As String
Const HKEY_CURRENT_USER = &H80000001
Set RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
RegObj.Enumvalues HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Printers, arrH
For Each Pr In Printers
RegObj.getstringvalue HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Pr, RegValue
Printer = Pr & " on " & Split(RegValue, ",")(1)
If InStr(1, Printer, PrinterName, vbTextCompare) > 0 Then
FindPrinter = Printer
Exit Function
End If
Next
End Function
And use it in this way:
Sub testFindPrinter()
Debug.Print FindPrinter("Microsoft Print to PDF")
End Sub
Or for your specific case:
Application.ActivePrinter = FindPrinter("Microsoft Print to PDF")
Please, test it and send some feedback

VBA Excel - Export PDF file from Excel with second page

Just want to ask if how can I export a PDF file with vba? The thing is I do have a 10-F and 10-B sheet. The code below is working in the 10-F sheet. My problem is how can I export the data in the 10-B sheet together with the 10-F? The first page is the data in 10-F while the data in 10-B will be on the second page.
The range for the 10-B sheet is "B10:AD92".
Sub Ver_PDF()
'Create and assign variables
Dim saveLocation As String
Dim rng As Range
lname = ThisWorkbook.Sheets("HOME").Range("K12")
fname = ThisWorkbook.Sheets("HOME").Range("K13")
Name = fname & " " & lname
pdfile = "V-" & Name & ".pdf"
saveLocation = ThisWorkbook.Path & "\V-PDF\" & pdfile
Set rng = Sheets("10-F").Range("B9:AD89")
Dim strFileExists As String
strFileExists = Dir(saveLocation)
If strFileExists <> "" Then
Dim Ret
'~~> Change this to the relevant file path and name
Ret = IsFileOpen(saveLocation)
If Ret = True Then
MsgBox "Please close the PDF file before proceeding...", vbCritical + vbOKOnly, "Error"
Exit Sub
End If
End If
rng.ExportAsFixedFormat Type:=xlTypePDF, _
FileName:=saveLocation, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Any help is highly appreciated! Thanks!
This code will do what you want. Change the worksheet names in the array as well as the destination path and file name.
Sub ExportAsPDF()
Dim FolderPath As String
Dim FileName As String
FolderPath = "D:\Test PDFs\" ' change to suit: end on back-slash
FileName = "Test" ' change to suit
On Error Resume Next
MkDir FolderPath
On Error GoTo 0
Worksheets(Array("10-F", "10-B")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
FileName:=FolderPath & FileName & ".PDF", _
OpenAfterPublish:=True, _
IgnorePrintAreas:=False
MsgBox "PDF was successfully created."
Worksheets(1).Select
End Sub
Change OpenAfterPublish to False if you don't want to see the result right away.

Convert Sheet to PDF missing images

I am using this code to convert sheet to pdf file.I must mention that my Excel Sheet also contains images in each cells on a Column.
Sub SheetToPDF()
Dim wsA As Worksheet
Dim wbA As Workbook
Dim strName As String
Dim strPath As String
Dim strFile As String
Dim strPathFile As String
Dim myFile As Variant
Dim lOver As Long
On Error GoTo errHandler
Set wbA = ActiveWorkbook
Set wsA = ActiveSheet
'get active workbook folder, if saved
strPath = wbA.Path
If strPath = "" Then
strPath = Application.DefaultFilePath
End If
strPath = strPath & "\"
strName = "test"
'create default name for savng file
strFile = strName & ".pdf"
strPathFile = strPath & strFile
If bFileExists(strPathFile) Then
lOver = MsgBox("Overwrite existing file?", _
vbQuestion + vbYesNo, "File Exists")
If lOver <> vbYes Then
'user can enter name and
' select folder for file
myFile = Application.GetSaveAsFilename _
(InitialFileName:=strPathFile, _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Select Folder and FileName to save")
If myFile <> "False" Then
strPathFile = myFile
Else
GoTo exitHandler
End If
End If
End If
'export to PDF in current folder
wsA.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strPathFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
'confirmation message with file info
MsgBox "Successfully created PDF file: " _
& vbCrLf _
& strPathFile
exitHandler:
Exit Sub
errHandler:
MsgBox "Could not create PDF file :("
Resume exitHandler
End Sub
'=============================
Function bFileExists(rsFullPath As String) As Boolean
bFileExists = CBool(Len(Dir$(rsFullPath)) > 0)
End Function
The problem is that the PDF file is missing images (only last 2 pages copied the images successfully)
Is there any code to help me copy all images from the excel sheet to PDF file?
Thank you very much!

Problem with VBA print to pdf error code in windows 10 environment

I have code which works fine in windows 7 and other windows version environments, but when some of the users have been upgraded to Windows 10 (myself included)
This is a macro enabled sheet which has worked fine for 3 years, and as far as I can tell the only change is the 'upgrade' to windows 10!
this is the bit of code which seems to fail:
'saveas function for pdf
ws.range("A1:K69").ExportAsFixedFormat Type:=xlTypePDf, _
filename:=path & fname, _
Quality:-xlqualityStandard, _
IncludeDocProperties:=True' _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
I get a Run-Time error Method 'ExportAsFixedFormat' of Object 'Range' failed. But when someone in an earlier windows environment runs the code it works perfectly and I get the pdf created, saved and opened for the user to insert other documents into.
Driving me mental, and I cannot work out why this would fail - and also sporadically as well.
I use the below to auto save an excel sheet as PDF, should try and save it to the excel file location and name it after the tab name.
If you set a print area on the sheet for the range you want to view in the PDF first, it should work :)
Hope it helps
Sub Export_Summary()
'
Dim wsA As Worksheet
Dim wbA As Workbook
Dim strTime As String
Dim strName As String
Dim strPath As String
Dim strFile As String
Dim strPathFile As String
Dim myFile As Variant
On Error GoTo errHandler
Set wbA = ActiveWorkbook
Set wsA = ActiveSheet
strTime = Format(Now(), "yyyymmdd\_hhmm")
'get active workbook folder, if saved
strPath = wbA.Path
If strPath = "" Then
strPath = Application.DefaultFilePath
End If
strPath = strPath & "\"
'replace spaces and periods in sheet name
strName = Replace(wsA.Name, " ", "")
strName = Replace(strName, ".", "_")
'create default name for savng file
strFile = strName & "_" & strTime & ".pdf"
strPathFile = strPath & strFile
'user can enter name and
' select folder for file
myFile = Application.GetSaveAsFilename _
(InitialFileName:=strPathFile, _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Select Folder and FileName to save")
'export to PDF if a folder was selected
If myFile <> "False" Then
wsA.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=myFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
'confirmation message with file info
MsgBox "PDF file has been created: " _
& vbCrLf _
& myFile
End If
exitHandler:
Exit Sub
errHandler:
MsgBox "Could not create PDF file"
Resume exitHandler
End Sub

Define file name via macro

I have the following piece of code to save a pdf file from an existing excel file.
Dim FSO As Object
Dim s(1) As String
Dim sNewFilePath As String
Set FSO = CreateObject("Scripting.FileSystemObject")
s(0) = ThisWorkbook.FullName
If FSO.FileExists(s(0)) Then
'//Change Excel Extension to PDF extension in FilePath
s(1) = FSO.GetExtensionName(s(0))
If s(1) <> "" Then
s(1) = "." & s(1)
sNewFilePath = Replace(s(0), s(1), ".pdf")
'//Export to PDF with new File Path
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF,_
_ Filename:=sNewFilePath, Quality:=xlQualityStandard,_
_ IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End If
Else
'//Error: file path not found
MsgBox "Error: this workbook may be unsaved. Please save and try again."
End If
Set FSO = Nothing
Since the code has to be run recursively, I'd would like add to the file name the week number, contained in a given cell (B2) in the sheet.
I tried replacing
s(0) = ThisWorkbook.FullName & Cells(2,2)
but it is not working. Where is the error?
FullName property returns the full path & filename & extension. Appending Cells(2,2) to that will give you a value like "c:\path\to\filename.xlsx" & Cells(2,2).Value.
You need to insert the week number (Cells(2,2)) before the file extension part.
You can probably do that like so:
sNewFilePath = Replace(s(0), s(1), Cells(2,2).Value & ".pdf")
Or, without using FileSystemObject:
Dim fullName As String, weekNum As String
Dim sNewFilePath As String
weekNum = Cells(2,2).Value
fullName = ThisWorkbook.FullName
'If the file exists, the `Dir` function will return the filename, len != 0
If Len(Dir(fullName)) <> 0 Then
'remove the extension using Mid/InstrRev functions, _
build the new filename with weeknumber & pdf extension
sNewFilePath = Mid(fullName, 1, InstrRev(fullName,".")-1) & weekNum & ".pdf"
'Export to PDF with new File Path
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF,_
_ Filename:=sNewFilePath, Quality:=xlQualityStandard,_
_ IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End If
Else
'//Error: file path not found
MsgBox "Error: this workbook may be unsaved. Please save and try again."
End If
FullName includes the file extension. Perhaps this (you would be better off adding a sheet reference to B2 also).
s(0)=split(ThisWorkbook.FullName, ".")(0) & Cells(2, 2) & ".pdf"
Something like this would do it (I cleaned it up a little bit):
Dim FSO As Object
Dim s(1) As String
Dim sNewFilePath As String
Sub SavePDF()
Set FSO = CreateObject("Scripting.FileSystemObject")
s(0) = ThisWorkbook.FullName
If FSO.FileExists(s(0)) Then
'//Change Excel Extension to PDF extension in FilePath
s(1) = FSO.GetExtensionName(s(0))
If s(1) <> "" Then
s(1) = "." & s(1)
sNewFilePath = Left(s(0), InStrRev(s(0), "\")) & ".pdf"
'//Export to PDF with new File Path
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
sNewFilePath & Sheets("wsTakeOff").Range("AY2").Value & " - " & Sheets("wsTakeOff").Range("D1") & ".pdf", Quality:= _
xlQualityStandard, includedocproperties:=False, ignoreprintareas:=False, _
openafterpublish:=False
End If
Else
'//Error: file path not found
MsgBox "Error: this workbook may be unsaved. Please save and try again."
End If
Set FSO = Nothing
End Sub

Resources