BeforePrint Event is Firing without Printing - vba

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.

Related

Generate separate PDF from Sheets in VBA

I am trying to create a macro that will generate separate PDF files for Selected Worksheets in a Workbook. I found this code on line, which works great, it puts all selected sheets in ONE PDF. I need to have each selected sheet as a separate PDF.
I am a beginner to VBA.
Sub PDFActiveSheet()
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
Separate sheets to separate PDF files
Sub ExportToPDFs()
' PDF Export Macro
' Change C:\Exports\ to your folder path where you need the diles saved
' Save Each Worksheet to a separate PDF file.
Dim ws As Worksheet
For Each ws In Worksheets
ws.Select
nm = ws.Name
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\Users\Excel\Desktop\test\" & nm & ".pdf", _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
Next ws
End Sub

Save each worksheet in workbook as an individual pdf

I want to loop over all worksheets in a workbook and save them as individual pdfs in the same path as the workbook. The files are named after the worksheet name.
This code below works up until the "wsA.ExportAsFixedFort" line. The error message i get is:
Run-time error '91': Object variable or With block variable not set
But i cant figure out what the issue is...
Any suggestions?
Option Explicit
Sub WorksheetLoop()
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
Dim WS_Count As Integer
Dim I As Integer
' Set WS_Count equal to the number of worksheets in the active workbook.
Set wbA = ActiveWorkbook
WS_Count = wbA.Worksheets.Count
strPath = wbA.Path
strTime = Format(Now(), "yyyymmdd\_hhmm")
'get active workbook folder, if saved
strPath = wbA.Path
If strPath = "" Then
strPath = Application.DefaultFilePath
End If
strPath = strPath & "\"
' Begin the loop.
For I = 1 To WS_Count
'replace spaces and periods in sheet name
strName = Replace(wbA.Worksheets(I).Name, " ", "")
strName = Replace(strName, ".", "_")
'create default name for savng file
strFile = strName & "_" & strTime & ".pdf"
myFile = strPath & strFile
Debug.Print myFile
'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
Next I
End Sub
Try to change like this:
If myFile <> "False" Then
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
FileName:=myFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Then try to find a way how to loop through the sheets, its a trivial VBA task.
In general, in your code wsA was not set. Thus, you got an error.

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

Creating folders and new *.xlsx file with macro from template like xlsm file

I have this code that creates a folder and a saves the actual file in it, but i want that it only saves a copy with only one sheet in it. So that the file with the code works like a template...
You write your stuff and press the button and it saves an .xlsx file with one sheet (the sheet with the form) in the new created folder... so you could do this with hundreds of files an folders.
So in the end it should work like this:
You open the .xlsm file where the code below is in.
You got to sheets one FORM (what should be "exported" later on) and
a list where you copy stuff in the form.
When you filled the form and press the button and it saves the Form
sheet in the new folder as .xlsx and you can continue in the .xlsm
file.
If it's unclear for you please ask.
The code i have now
Sub Macro1()
Dim strFilename, strDirname, strPathname, strDefpath As String
On Error Resume Next ' If directory exist goto next line
strDirname = Range("D81").Value ' New directory name
strFilename = Range("D8").Value 'New file name
strDefpath = Application.ActiveWorkbook.Path 'Default path name
If IsEmpty(strDirname) Then Exit Sub
If IsEmpty(strFilename) Then Exit Sub
MkDir strDefpath & "\" & strDirname
strPathname = strDefpath & "\" & strDirname & "\" & strFilename 'create total string
ActiveWorkbook.SaveAs Filename:=strPathname & ".xlsm", _
FileFormat:=xlOpenXMLWorkbookMacroEnabled, Password:="", WriteResPassword:="", _
ReadOnlyRecommended:=False, CreateBackup:=False
End Sub
Problem here is i have Names for the forms that are like 1102,1103 an going on like that. the next step is that there are files with the name 1102_1 and 1102_2 and they both should go in the folder 1102 ...
It's a bit out of my knownledge please help me guys :) greets
Now i am using this code below
Problem is that it always closes the xlsm file what really annoyes and when i reopen it it wants to update the file i need to remove that but i don't know how :/... and it only should export/save one special sheet
Private Sub CommandButton1_Click()
Dim strFilename As String, _
strDirname As String, _
strPathname As String, _
strDefpath As String, _
SheetToExport As String, _
WbMaster As Workbook, _
WbCopy As Workbook
On Error Resume Next ' If directory exist goto next line
strDirname = Range("W12").Value ' New directory name
strFilename = Range("D8").Value 'New file name
Set WbMaster = Application.ActiveWorkbook
SheetToExport = Range("A1").Value 'Or specify UserForm output
strDefpath = WbMaster.Path 'Default path name
If IsEmpty(strDirname) Then Exit Sub
If IsEmpty(strFilename) Then Exit Sub
MkDir strDefpath & "\" & strDirname
strPathname = strDefpath & "\" & strDirname & "\" & strFilename 'create total string
WbMaster.Sheets(SheetToExport).Copy
Set WbCopy = Application.ActiveWorkbook
WbCopy.SaveAs Filename:=strPathname & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", _
ReadOnlyRecommended:=False, CreateBackup:=False
WbCopy.Close
End Sub
Be careful on your variable declaration!
The way you did it in your OP (original post) :
strFilename, strDirname and strPathname are declared as Variant and not as String.
You can still use them BUT it'll take much more memory and can be issue if you use them as arguments.
See the code :
Dim strFilename As String, _
strDirname As String, _
strPathname As String, _
strDefpath As String, _
SheetToExport As String, _
WbMaster As Workbook, _
WbCopy As Workbook
On Error Resume Next ' If directory exist goto next line
strDirname = Range("D81").Value ' New directory name
strFilename = Range("D8").Value 'New file name
Set WbMaster = Application.ActiveWorkbook
SheetToExport = Range("A1").Value 'Or specify UserForm output
strDefpath = WbMaster.Path 'Default path name
If IsEmpty(strDirname) Then Exit Sub
If IsEmpty(strFilename) Then Exit Sub
MkDir strDefpath & "\" & strDirname
strPathname = strDefpath & "\" & strDirname & "\" & strFilename 'create total string
WbMaster.Sheets(SheetToExport).Copy
Set WbCopy = Application.ActiveWorkbook
WbCopy.SaveAs Filename:=strPathname & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", _
ReadOnlyRecommended:=False, CreateBackup:=False
ClosingWb = MsgBox("Do you wish to close the exported file?",vbYesNo,"Close exported file")
If ClosingWb <> vbNo Then WbCopy.Close

VBScript to export selected portion of Excel sheet to a PDF, on one page

I currently have a VBScript that exports an entire excel worksheet to a PDF. I was wondering if it would be possible to set the script to only export the selected areas. I know this can be done manually, but I've been tasked with automating this process. If achieved, it would make the whole reporting proccess a lot easier. The VBScript that I'm currently using is:
Sub PDFActiveSheet()
Dim ws As Worksheet
Dim strPath As String
Dim myFile As Variant
Dim strFile As String
On Error GoTo errHandler
Set ws = ActiveSheet
'enter name and select folder for file
' start in current workbook folder
strFile = Replace(Replace(ws.Name, " ", ""), ".", "_") _
& "_" _
& Format(Now(), "yyyymmdd\_hhmm") _
& ".pdf"
strFile = ThisWorkbook.Path & "\" & strFile
myFile = Application.GetSaveAsFilename _
(InitialFileName:=strFile, _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Select Folder and FileName to save")
If myFile <> "False" Then
ws.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=myFile, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
MsgBox "PDF version of report has been created."
End If
exitHandler:
Exit Sub
errHandler:
MsgBox "Could not create PDF file"
Resume exitHandler
End Sub
I've already tried replacing the "Set ws = ActiveSheet" to "Selection", and that has yielded no results. Also, as a side note, when selections are sent to a PDF, they appear on separate sheets.Is it possible to put them both on one sheet?
Thanks in advance for any help that you can offer me.
Try setting the Print Area that you want to output to PDF.