VBA - printing individual sheets as individual and combined pdf - vba

Dim s As String
Dim i As Long
Dim rng As Range
Dim ws() As Variant 'dynamic array
If LCase(Sheet76.Range("H7")) = "x" Then
ReDim ws(1 To 7) 'declare size
'Select file save location
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
If .SelectedItems.Count > 0 Then
strPath = .SelectedItems(1)
End If
End With
'to print individually
For i = 1 To 7
s = Sheet76.Cells(8 + i, 7).Value
ws(i) = s
Sheets(s).Select
strPath = strPath & "\"
strFileName = strPath & s & ".pdf"
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strFileName, _
IgnorePrintAreas:=False
Next
end if
I have two questions. The above code is for printing out individual pdfs per worksheet. I'm able to print out 4 of the 7, then it has an error runtime message. What am I doing wrong?
Also, why doesn't this work for printing out multiple worksheets as a single pdf?
sheets(ws).select
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strFileName, _
IgnorePrintAreas:=False`
EDIT: I fixed the runtime error; the string value for i=5 didn't tie up with the sheet name. I'm still stuck on how to print the selected worksheets as one combined pdf.

dim ws() as string
For i = 1 To 7
s = Sheet76.Cells(8 + i, 7).Value
ws(i) = s
Next
Sheets(ws).Select
strFileName = strPath & "Combined.pdf"
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strFileNamering variable., _
IgnorePrintAreas:=False
Solution to printing worksheets as a single combined pdf above. I got it to work by declaring ws() array as st

Related

VBA Excel Ignores PrintArea Pdf

I have 250 excel documents where I try to print a sheet for pdf. If I do it manually, it will be 4 pages, but if I use my code, it will be 7 pages long.
It's like it ignores the print area, and makes several blank pages.
Can any of you figure out the mistake?
Dim wb As Workbook
Dim xExtension As String: xExtension = "*.xls*"
Dim xFolder As String: xFolder = [MailFolder]
Dim xFile As String: xFile = Dir(xFolder & xExtension) 'DIR gets the first file of the folder
Dim Rng As Range: Set Rng = Range("A1")
Dim s As String
Do While xFile <> "" 'Loop through all files in a folder until DIR cannot find anymore
Set wb = Workbooks.Open(xFolder & xFile): wb.Activate
Call WorksheetsToPDF(wb, "F:\VBA\PDF\Udlejning\" & CleanFileName("Police - " & "2021 -" & [KompletPoliceNr] & " - " & [Forsikringstager]) & ".pdf", "Certifikat")
'Call WorksheetsToPDF(wb, "F:\VBA\KF Begæringer\" & CleanFileName("KF Begæring-2021-" & [KompletPoliceNr] & "-" & [Forsikringstager]) & ".pdf", "Police")
wb.Close savechanges:=False
xFile = Dir()
Loop
End Sub
Private Sub WorksheetsToPDF(wb As Workbook, DistinationPath As String, ParamArray Arr() As Variant)
wb.Sheets(Arr()).Select
Debug.Print EFDK.GetNextavailablefilename(DistinationPath)
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, FileName:=EFDK.GetNextavailablefilename(DistinationPath), Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False
End Sub
Private Function GetNextAvailableFilename(ByVal xPath As String) As String
With CreateObject("Scripting.FileSystemObject")
Dim strFolder As String, strBaseName As String, strExt As String, i As Long
strFolder = .GetParentFolderName(xPath)
strBaseName = .GetBaseName(xPath)
strExt = .GetExtensionName(xPath)
Do While .FileExists(xPath)
i = i + 1
xPath = .BuildPath(strFolder, strBaseName & " - " & i & "." & strExt)
Loop
End With
GetNextAvailableFilename = xPath
End Function
You did not answer my clarification questions...
Just for the sake of testing, please try the next adapted function:
Private Sub WorksheetsToPDF(wb As Workbook, DistinationPath As String, ParamArray arr() As Variant)
Dim El
wb.Sheets(arr()).Select
For Each El In arr()
wb.Sheets(El).PageSetup.FitToPagesWide = 1
wb.Sheets(El).PageSetup.PaperSize = xlPaperA4 ' xlPaperLetter
wb.Sheets(El).PageSetup.Orientation = xlLandscape
Next
'Debug.Print EFDK.GetNextavailablefilename(DistinationPath)
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, FileName:=EFDK.GetNextavailablefilename(DistinationPath), Quality:=xlQualityStandard, IncludeDocProperties:=True
End Sub

BeforePrint Event is Firing without Printing

I have the code below. It makes me wonder why the BeforePrint event in the workbook codes is fired even though I am not printing anything. The workbook definitely is not blank. The error is in the creation of the PDF file.
The file does a simple job of saving the worksheet in a PDF format with the name of the sheet, the file path of the workbook, and some details inside the worksheet.
Anything that I am missing? I am not new to VBA but this bugs me a lot today. I am using MS Excel 2016 on Windows 7 ultimate.
Edit: I tried removing the following codes below but the problem still persists:
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
The code is as follows:
Option Explicit
Public Sub createpdffile()
Dim wsA As Worksheet
Dim wbA As Workbook
Dim strPath As String
Dim strFile As String
Dim strPathFile As String
Dim myFile As Variant
Dim sheetname As String, sheetcode As String
Dim iRow As Long
Dim openPos As Integer
Dim closePos As Integer
'temporarily disable error handler so that I can see where the bug is.
'On Error GoTo errHandler
Set wbA = ActiveWorkbook
Set wsA = ActiveSheet
wbA.Save
'get last row of sheet and set print area to last row with L column
iRow = wsA.Cells(Rows.Count, 1).End(xlUp).Row
wsA.PageSetup.PrintArea = wsA.Range("A1:L" & iRow).Address
'just checking name in sheet and removing needed characters
sheetname = wsA.Name
openPos = InStr(sheetname, "(")
closePos = InStr(sheetname, ")")
sheetcode = Mid(sheetname, openPos + 1, closePos - openPos - 1)
'get active workbook folder, if saved
strPath = wbA.Path
If strPath = "" Then
strPath = Application.DefaultFilePath
End If
strPath = strPath & "\"
'create default name for saving file
strFile = sheetcode & " No. " & wsA.Cells(11, 9) & " - " & wsA.Cells(8, 3) & ".pdf"
strPathFile = strPath & strFile
'use 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
'THIS IS WHERE THE ERROR IS LOCATED
If myFile <> "False" Then
wsA.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=myFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
'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" & vbNewLine & _
"Please complete the details needed!", vbOKOnly + vbExclamation, "Error Saving as PDF"
Resume exitHandler
End Sub
Solution from Foxfire and Burns and Burns' idea:
I added a public declaration before the main sub.
Option Explicit
'added line
Public myboolean as Boolean
Public Sub createpdffile()
myboolean = True
....
Then I added a line in the BeforePrint Event that says:
If myboolean = True Then Exit Sub
This now bypasses the BeforePrint event when the virtual PDF printer is called.
wsA.ExportAsFixedFormat
That line activates the BeforePrint Event. Actually, you are printing a PDF file. It works as a virtual PDF Printer.

How to merge 3 VBA commands in to one? Set print range without absolute reference

I'm trying to solve a situation where I have a range of text that can vary considerably depending on the results returned by an array formula. Sometimes there may be 5 rows of data, other times there may be 2000.
I think I've found the chunks of individual VBA codes required for each stage of the task I want to complete, but I am a complete novice with VBA and I have no idea how to piece these together.
The following selects all the actual data on the page, and excludes any rows that contain a hidden formula:
Sub PickedActualUsedRange()
Range("A1").Resize(Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row, _
Cells.Find(What:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Column).Select
End Sub
So far so good. This is the exact range I want to print.
I also want the row height to be adjusted automatically, as each cell may contain a string of text of varying lengths that may be wrapped. So again the following command needs to go in:
Selection.Rows.AutoFit
Not too much trouble so far.
However, for the next bit I would like the VBA to use the selection made above, and to set this as the new print range. However, the code I have found seems to require me to set an absolute range (as per below), whereas I need this to adjust in accordance to the first selection
Selection.PageSetup.PrintArea = "$A$1:$B$12"
Once this is in place, the next step I would like to incorporate is this code I found via from the contextures website for printing the current worksheet:
Sub PDFActiveSheet()
'www.contextures.com
'for Excel 2010 and later
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
'use 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
Is anybody able to help me incorporate all of the above in to a single string of code please?
FURTHER EDIT
Still not sure what I'm doing with different chunks of code. What would be the exact text I would need to enter in Module1? I don't understand how to structure it:
'Function to give the actual data range from a given worksheet
Function PickedActualUsedRange(ws As Worksheet) As Range
Set PickedActualUsedRange = ws.Range("A1").Resize(Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row, _
Cells.Find(What:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Column)
End Function
Sub PDFSheet(wsA As Worksheet) '<-- the sheet in question will be given as parameter
' Drop or change the following lines...
' Dim wsA As Worksheet '<-- drop
' Dim wbA As Workbook '<-- drop
...
strPath = wsA.Parent.Path ' <-- change
...
End Sub
Sub mySyb()
Sub PDFActiveSheet()
'www.contextures.com
'for Excel 2010 and later
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
'use 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
End Sub
Sub mySyb()
Dim ws As Worksheet: Set ws = Worksheets("report")
Dim r As Range: Set r = PickedActualUsedRange(ws)
r.Rows.AutoFit
ws.PageSetup.PrintArea = r.Address
PDFSheet (ws)
End Sub
To fit it the easiest way with your current code, here's how you would setup the print area:
ActiveSheet.PageSetup.PrintArea = Selection.address
And you can call your routines in order
PickedActualUsedRange
Selection.Rows.AutoFit
ActiveSheet.PageSetup.PrintArea = Selection.address
PDFActiveSheet
On a final note, your code uses unqualified ranges and counts a lot on Select, Selection, ActivateSheet etc... which is usually considered bad practice (code will be difficult to maintain). You'd better change it to get rid of these and use explicit sheet names and qualified ranges.
EDIT
' Function to give the actual data range from a given worksheet
Function PickedActualUsedRange(ws as Worksheet) as Range
Set PickedActualUsedRange = ws.Range("A1").Resize(ws.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row, _
ws.Cells.Find(What:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Column)
End Function
Sub PDFSheet(wsA As Worksheet)
'www.contextures.com
'for Excel 2010 and later
Dim strTime As String, strName As String, strPath As String, strFile As String, strPathFile As String
Dim myFile As Variant
On Error GoTo errHandler
strTime = Format(Now(), "yyyymmdd\_hhmm")
'get active workbook folder, if saved
strPath = wsA.Parent.Path & "\"
'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
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
Sub myMacro
Dim ws as worksheet: Set ws = Worksheets("report")
Dim r as range: Set r = PickedActualUsedRange(ws)
r.Rows.AutoFit
ws.PageSetup.PrintArea = r.address
PDFSheet ws
End Sub
Put all this in a code module (i.e. Module1) and call the myMacro through ALT
+ F8

exporting a certain worksheet from a workbook to pdf

i am an amateur programmer learning how to program using vba
without further a due, my question is :
i have created a listbox (listbox1) where i've listed all my sheets(ws) name in a specific workbook.
i've also created another listbox(listbox2) where when i select some sheets name on the listbox1, they will be transfer to listbox2.
my main objective is that by choosing one or more sheets listed in the listbox2, and by clicking a button, i'll manage to save all the selected sheets in one pdf file.
here is the code for the button used to export the file in pdf that i've written but i've only managed to export them not in one pdf file but in numerous amount of pdf file.
Dim NomTableau() As String
For Each WkbkName In application.Workbooks()
If WkbkName.Name = choix_poteau.Value & "_" & section & "_" & projet & ".xlsx" Then
WkbkName.Activate
GoTo lois
End If
Next
Set wbk = Workbooks.Open(add1 & "\" & Me.projet.Value & "\" & Me.section.Value & "\poteaux\" & Me.choix_poteau.Value & "_" & Me.section & "_" & Me.projet & ".xlsx")
lois:
For i = 0 To ListBox2.ListCount - 1
While ListBox2.List(i) <> ""
Dim ws As Worksheet
For Each ws In Worksheets
If ws.Name = ListBox2.List(i) Then
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Export\Resultats__" & ListBox2.List(i - counter) & ".pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True
End If
Next
Wend
Next i
End Sub
thanks alot, really appreciate your help
Instead of exporting each sheet individually, select them all first and then call the ExportAsFixedFormat method.
Here is my test code, which worked as expected:
Option Explicit
Private Sub TestPDF()
Dim i As Integer
Dim arrSheets() As String
Dim strSheets As String
'Get our sheet names
For i = 1 To 3
strSheets = Worksheets(i).Name & "," & strSheets
Next
'Trim the trailing comma
strSheets = Left(strSheets, Len(strSheets) - 1)
arrSheets = Split(strSheets, ",")
ThisWorkbook.Sheets(arrSheets).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\qzbcjs\Documents\Useful Workbooks\test.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True
End Sub
I declared an array of strings, populated a string variable with the comma-delimited names of the worksheets (in my case I just wanted the first through third sheets), split that comma-delimited string into an array and used the array to select all of the desired sheets and only called the ExportAsFixedFormat method once.
Adapting this method to your code, beginning as the lois part would look something like this:
lois:
Dim ws As Worksheet
Dim arrSheets() As String
Dim strWs As String
For i = 0 To ListBox2.ListCount - 1
While ListBox2.List(i) <> ""
For Each ws In Worksheets
If ws.Name = ListBox2.List(i) Then
strWs = ws.Name & "," & strWs
End If
Next
Wend
Next i
strWs = Left(strWs, Len(strWs) - 1)
arrSheets = Split(strWs, ",")
ThisWorkbook.Sheets(arrSheets).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Export\Resultats__" & ListBox2.List(i - counter) & ".pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True

Selecting Where PDF Files Save

I'm so relieved that I finally got the code below to work with the help of this community.
I have one more option on my wishlist that I'm struggling with. Currently, the code below will save worksheet 3 all the way to worksheet titled "post" as separate PDF files into a folder I select. This is triggered by a shape.
I'm trying to make the below code prompt a folder select so users can select where their PDF files are saved, does anyone have any ideas how to do this?
Also, the Call Shell at the bottom would preferably open the folder where the files are saved, but that's not really necessary as long as users know where the files are being saved :)
Sub SaveAllPDF()
Dim i As Integer
Dim Fname As String
Dim TabCount As Long
TabCount = Sheets("Post").Index
'Set the TabCount to the last cell you want to PDF
' Begin the loop.
For i = 3 To TabCount
'Set i = the number of the first sheet you want to PDF in order from left to right To TabCount
If Sheets(i).Visible <> xlSheetVisible Then
Else
With Sheets(i)
Fname = .Range("C15") & " " & .Range("E13") & "-" & .Range("B1")
'The Fname above is equaling the cells that the PDF's filename will be
'The folder directory below is where the PDF files will be saved
.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\Brandon\Desktop\operation automated\RLtemp\" & Fname, Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End With
End If
Next i
Call Shell("explorer.exe" & " " & "C:\Users\Brandon\Desktop\operation automated\RLtemp\", vbNormalFocus)
'This opens the folder where the PDFs are saved
End Sub
You can just use the Excel's FileDialog object:
Sub SaveAllPDF()
Dim i As Integer
Dim Fname As String
Dim TabCount As Long
TabCount = Sheets("Post").index
'Set the TabCount to the last cell you want to PDF
Dim dialog As FileDialog
Dim path As String
Set dialog = Application.FileDialog(msoFileDialogFolderPicker)
dialog.AllowMultiSelect = False
If dialog.Show = -1 Then
path = dialog.SelectedItems(1)
' Begin the loop.
For i = 3 To TabCount
'Set i = the number of the first sheet you want to PDF in order from left to right To TabCount
If Sheets(i).Visible <> xlSheetVisible Then
Else
With Sheets(i)
Fname = .Range("C15") & " " & .Range("E13") & "-" & .Range("B1")
'The Fname above is equaling the cells that the PDF's filename will be
'The folder directory below is where the PDF files will be saved
.ExportAsFixedFormat Type:=xlTypePDF, filename:=path & "\" & Fname, Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End With
End If
Next i
Call Shell("explorer.exe" & " " & path & "\", vbNormalFocus)
'This opens the folder where the PDFs are saved
End If
End Sub