Pivot Slicer Items to PDF - via file dialog folder picker - excel

Hi all and thank you for taking the time to read.
In relation to the code below (code provided by M--) from this post VBA to select each slicer item AND then save each selected slicer item as a pdf?
Rather than a predetermined save / export location i would like the user to select a folder of their choice.
I have been politely informed in stack chat by #QHarr that i need a filedialog object to introduce this function. Would this be at the beginning of the module? Is export better than save.as in this scenario? Would the latter effect the way the slicer items are transferred?
Much appreciated and kind regards
wAnd
Public Sub myMacro()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")
'This reminds the user to only select the first slicer item
If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
MsgBox "Please Only Select Store-Number 1"
Exit Sub
End If
For i = 1 To sC.SlicerItems.Count
'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)
sC.SlicerItems(i).Selected = True
If i <> 1 Then sC.SlicerItems(i - 1).Selected = False
'Debug.Print sI.Name
'add export to PDF code here
With Sheet18.PageSetup
.PrintArea = Sheet18.Range("A1:N34" & lastRow).Address
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Sheet18.Range("M1") = sC.SlicerItems(i).Name
'This prints to C directory, change the path as you wish
Sheet18.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\" & Range("M1").Text & ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End Sub

After looking around i have managed to solve it. In a nutshell i didnt use the back slash for Filename:=path & \ & Range("G2").Text
Final code below
Private Sub CommandButton1_Click()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Site_Product")
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)
'This reminds the user to only select the first slicer item
If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
MsgBox "Please select the top most item"
Exit Sub
End If
For i = 1 To sC.SlicerItems.Count
'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)
sC.SlicerItems(i).Selected = True
If i <> 1 Then sC.SlicerItems(i - 1).Selected = False
'Debug.Print sI.Name
'add export to PDF code here
With Sheet5.PageSetup
.PrintArea = Sheet5.Range("B2:M76" & lastRow).Address
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Sheet5.Range("G2") = sC.SlicerItems(i).Name
For Each CL In Sheet5.Range("M11:M67")
If CL.WrapText Then CL.Rows.AutoFit
Sheet5.Range("A1:A74").AutoFilter Field:=1, Criteria1:=Sheet5.Range("A2")
Next
'This prints to C directory, change the path as you wish
Sheet5.ExportAsFixedFormat Type:=xlTypePDF, Filename:=path & "\" & Range("G2").Text, Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End If
End Sub

Related

Excel VBA: Delete sheet after exporting to PDF

I have written the following code tied to a command button to prompt the user to define a save path, export the active sheet to PDF and open it, then delete the sheet after it's been exported and activate a different sheet. The code works to completion but right at the end, I get a the following error:
Run-time error '-2147221080 (800401a8)':
Automation error
Below is my code. Any help would be immensely appreciated.
Private Sub ExceptionPrint_Click()
Sheet_Name = ActiveSheet.Name
PDF_Name = "Exception - " & ActiveSheet.Name & ".pdf"
Set File_Dialog = Application.FileDialog(msoFileDialogFolderPicker)
File_Dialog.AllowMultiSelect = False
File_Dialog.Title = "Select the Desired Location"
If File_Dialog.Show <> -1 Then
Exit Sub
End If
PDF_Name = File_Dialog.SelectedItems(1) & "\" & PDF_Name
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=PDF_Name, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
If Sheets("Data").Range("H12").Value = "W1" Then
Sheets("Week 1").Activate
Sheets("Data").Range("H12").Value = ""
Else
Sheets("Week 1").Activate
Sheets("Data").Range("H12").Value = ""
End If
Application.DisplayAlerts = False
Sheets(Sheet_Name).Delete
Application.DisplayAlerts = True
End Sub
I've tried everything I could think of, but I'm not that great with VBA to begin with.
Assign the active sheet to a reference at the start and use that reference throughout the program. Also try to catch early any errors that the user might make.
Option Explicit
Private Sub ExceptionPrint_Click()
Dim wb As Workbook, wsPDF As Worksheet, PDF_Name As String
' validation
Set wb = ThisWorkbook
Set wsPDF = wb.ActiveSheet
With wsPDF
If .Name = "Week 1" Or .Name = "Data" Then
MsgBox "Sheet " & wsPDF.Name & " must not be selected", vbCritical
Exit Sub
ElseIf WorksheetFunction.CountA(.UsedRange) = 0 Then
MsgBox .Name & " is blank", vbCritical
Exit Sub
End If
End With
' select folder
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Title = "Select the Desired Location"
If .Show <> -1 Then Exit Sub
PDF_Name = .SelectedItems(1) & "\Exception - " & wsPDF.Name & ".pdf"
End With
' print and delete
wsPDF.ExportAsFixedFormat Filename:=PDF_Name, Type:=xlTypePDF, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=True
Application.DisplayAlerts = False
wsPDF.Delete
Application.DisplayAlerts = True
' finish
With wb
.Sheets("Week 1").Activate
.Sheets("Data").Range("H12").Value = ""
End With
End Sub
I ended up just leaving a "Delete Sheet" button on the sheet in question rather than having it automatically delete. Thank you everyone.

VBA print line number and column letter in pdf document

So I am trying to print an Excel sheet. So far I got most of the stuff set up, but I can't get the line number nor the column letter working.
I tried a bunch of stuff like LineNumbering, PrintTitleColumns, but I think that's not what I am actually looking for.
Here's my code:
Sub PrintToPDF()
' Saves active sheet as PDF file.
Dim Name As String
Dim wkPrint As Worksheet
FileNameArray = Split(ThisWorkbook.Name, ".")
Name = ThisWorkbook.Path & "\" & Format(Now(), "yyyy-mm-dd") & "_" & FileNameArray(0) & ".pdf"
Set wkPrint = ThisWorkbook.Worksheets("Dokumentation")
'On Error GoTo err
'wkPrint.PrintCommunication = True
With wkPrint.PageSetup
.PaperSize = xlPaperA3
.RightHeader = "&D &T"
.PrintGridlines = True
'.LineNumbering.Active = True
'.PrintTitleColumns = "A:AA"
End With
'Application.PrintCommunication = True
wkPrint.ExportAsFixedFormat Type:=xlTypePDF, Filename:=Name, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
Exit Sub
'err:
'MsgBox err.Description
End Sub
Thanks in advance!
You are looking for wkPrint.PageSetup.PrintHeadings = True

Excel VBA to look for PrintArea headings and auto PageBreak

I have "Filling form" worksheet where user is filling information and then I have "Print version" worksheet that is actually printing. I am making "CV tool" so user is filling his personal information and then my current VBA is saving end file from "Print version" to xls. and .pdf to the same folder with certain name both files where my "CV tool" is. Some people have experience of 10 years in 10 different work places and others have been only in 2 different companies previously. So before saving to .pdf and .xls my VBA hides rows that are empty to make end result look good.
The problem is that estetically it is not so good looking because some heading of work positions are at the end of the page and work description is continuing on the next page. Is there any way to make some kind of VBA to look for each page in "PrintArea" and if certain block is not fitting to this page VBA will insert "Page Break" before it to move it to the next page?
My current macro below (Sub doitallplease() is main command):
Sub Color()
Dim myRange As Range
Dim cell As Range
Set myRange = ThisWorkbook.Sheets("Print version").Range("Print_Area")
For Each cell In myRange
myRange.Interior.ColorIndex = 0
If cell.HasFormula = True And cell.value = "" And cell.EntireRow.Hidden = False Then Rows(cell.Row).EntireRow.Hidden = True
Next
End Sub
Sub MagicButton()
Dim iFileName$, iRow&, iCol&, iCell As Range, iArr
iFileName = ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".xls"
iArr = Array(1, 3, 4): iCol = UBound(iArr) + 1
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
ThisWorkbook.Sheets("Print version").Copy
With ActiveWorkbook.ActiveSheet
.Buttons.Delete '.Shapes("Button 1").Delete
.UsedRange.value = .UsedRange.value
.SaveAs iFileName, xlExcel8: .Parent.Close
End With
Application.Calculation = xlAutomatic
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Sub exportpdfthisfile()
ActiveWorkbook.Sheets("Print version").Select
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Sub doitallplease()
Application.ScreenUpdating = False
ActiveWorkbook.Sheets("Print version").Visible = True
Call Color
Call MagicButton
Call exportpdfthisfile
ActiveWorkbook.Sheets("Filling form").Activate
ActiveWorkbook.Sheets("Print version").Visible = False
Application.ScreenUpdating = True
End Sub

VBA to select each slicer item AND then save each selected slicer item as a pdf?

I've designed a dashboard consisting of a number of different pivot tables and pivot charts.
All of these pivot tables/charts are controlled by 1 slicer called "Slicer_Store".
There are about 800 different Stores to choose from in this slicer.
I need to save a pdf of EVERY store's dashboard. The process of manually selecting each slicer item, then saving the sheet as a pdf file, is extremely time consuming with 800+ stores, so I was hoping to automate the process via VBA.
Here's my code so far:
Public Sub myMacro()
Dim sI As SlicerItem, sI2 As SlicerItem, sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store")
With sC
For Each sI In sC.SlicerItems
sC.ClearManualFilter
For Each sI2 In sC.SlicerItems
If sI.Name = sI2.Name Then sI2.Selected = True Else: sI2.Selected = False
Next
Debug.Print sI.Name
'add export to PDF code here
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\TestUser\Desktop\testfolder" & Range("b1").Text & ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End With
End Sub
The code does process all though slicer items, but the file is not being saved as a pdf. I need each file to be saved as the value in B2, so it would be Store1.pdf, Store2.pdf, Store3.pdf, etc.
Any help would be hugely appreciated. This is a big project at work and a lot of people are dependent on these pdf files..
Edited code:
This should work, but it takes forever to go over all of the slicer items (800+). Also, I need to make sure that it only prints the first page (print area) so the slicer itself won't be printed.
Public Sub myMacro()
Dim sI As SlicerItem, sI2 As SlicerItem, sC As SlicerCache
Dim ws As Worksheet
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")
Set ws = Sheet18
With sC
For Each sI In sC.SlicerItems
sC.ClearManualFilter
For Each sI2 In sC.SlicerItems
If sI.Name = sI2.Name Then sI2.Selected = True Else: sI2.Selected = False
Next
Debug.Print sI.Name
'add export to PDF code here
ws.PageSetup.PrintArea = ws.Range("A1:N34").Address
ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\testuser\Desktop\testfolder" & Range("M1").Text & ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End With
End Sub
This actually resolve the issue but the approach you get towards 800+ item would take forever to be completed. See below for another solution which needs a little bit of collaboration from the user but it is much faster.
Add this line before printing to PDF:
Range("b1") = sI.Name
This will write name of the store to the range so later you can use it as the name of your pdf file.
Also, add a slash to the end of your path:
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\TestUser\Desktop\testfolder\" & Range("b1").Text & ".pdf", Quality:= _
IF you want to only print first page, you can set the print area right before above lines or use this:
ActiveSheet.PrintOut from:=1, To:=1
UPDATE
In this solution you need to make sure that first slicer item, and only that one is selected (So you should not clear manual filter). This is coded based on that. The original code goes over all of the slicer items each time, select one and deselect the others which causes an extremely high computational cost.
Public Sub myMacro()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")
'This reminds the user to only select the first slicer item
If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
MsgBox "Please Only Select Store-Number 1"
Exit Sub
End If
For i = 1 To sC.SlicerItems.Count
'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)
sC.SlicerItems(i).Selected = True
If i <> 1 Then sC.SlicerItems(i - 1).Selected = False
'Debug.Print sI.Name
'add export to PDF code here
With Sheet18.PageSetup
.PrintArea = Sheet18.Range("A1:N34" & lastRow).Address
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Sheet18.Range("M1") = sC.SlicerItems(i).Name
'This prints to C directory, change the path as you wish
Sheet18.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\" & Range("M1").Text & ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End Sub
Sub FacultyToPDF()
Dim wb As String
Dim sh As Worksheet
Dim fname As String
Dim location As String
Dim sI As SlicerItem, sI2 As SlicerItem, sC As SlicerCache
Dim index As Integer
Const PrintRange = "Print_Area"
fPath = "C:\Users\xiaz01\Desktop\Special Project\PDF"
Set sC = ActiveWorkbook.SlicerCaches("Slicer_billing_phys_name")
For Each sI In ActiveWorkbook.SlicerCaches("Slicer_billing_phys_name").SlicerCacheLevels(1).SlicerItems
ActiveWorkbook.SlicerCaches("Slicer_billing_phys_name").VisibleSlicerItemsList = Array(sI.Name)
fname = Range("B1").Text & Format(Date, " yy-mm-dd") & ".pdf"
Range(PrintRange).ExportAsFixedFormat Type:=xlTypePDF, Filename:=fPath & "\" & fname
Next
End Sub

Only save populated spreadsheets with filled in cells as PDF

I'm currently trying to modify a Visual Basic macro to only save spreadsheets in a workbook that have had populated cells.
The current macro just saves the entire 16 sheet workbook as a PDF yet a maximum of 9 of these sheets are sometimes left uncompleted, yet are still saved.
I would like the macro to automatically check if these sheets have been populated, once the 'SAVE' button is clicked and then proceed to only save the filled out (complete) sheets as a PDF.
I would massively appricate any help!
The code below is how the macro currently works when just saving the entire workbook. (There is an IF statement check before it is saved to PDF.)
Sub SaveAsPDF()
With ThisWorkbook.Sheets("COVERPage1PRINT")
If (Len(.Range("C24")) = 0) Then
MsgBox "Ensure Serial Number or Stamp number are filled."
Exit Sub
ElseIf (Len(.Range("H17")) = 0) Then
MsgBox "Ensure Serial Number or Stamp Number are filled."
Exit Sub
Else
ChDir _
"P:\Cells\Spool & Sleeves Cell\Flow Plot Records\EFA\Saved EFA PDF Archive"
fname = Sheets("COVERPage1PRINT").Range("H17")
ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"P:\Cells\Spool & Sleeves Cell\Flow Plot Records\EFA\Saved EFA PDF Archive\" & fname, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=True
End If
End With
End Sub
This should do the job
(edited code)
Sub test1()
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim test() As String
Dim i As Integer
Dim pdfpath As String
Dim sheets_to_be_checked() As Variant
Dim a As Boolean
pdfpath = ActiveWorkbook.Path 'YOU CAN ADD YOUR PDF SAVING LOCATION e.g. "C\Users\ABC\Desktop"
i = 0
sheets_to_be_checked = Array("Sheet1", "Sheet3")
Set wbBook = ActiveWorkbook
With ThisWorkbook.Sheets("COVERPage1PRINT")
If (Len(.Range("C24")) = 0) Then
MsgBox "Ensure Serial Number & Tag Number or Stamp number are filled."
Exit Sub
ElseIf (Len(.Range("H16")) = 0) Then
MsgBox "Ensure Serial Number & Tag Number or Stamp Number are filled."
Exit Sub
ElseIf (Len(.Range("H19")) = 0) Then
MsgBox "Ensure Serial Number & Tag Number or Stamp Number are filled."
Exit Sub
Else:
For Each wsSheet In wbBook.Worksheets
With wsSheet
If IsInArray(wsSheet.Name, sheets_to_be_checked) Then
wsSheet.Activate
If WorksheetFunction.CountA(Range("D4:D9, E10:E15, F4:F9, G10:G15, H4:H9, I10:I15, J4:J9, K10:K15")) = 48 Then
ReDim Preserve test(i)
test(i) = wsSheet.Name
i = i + 1
End If
Else:
ReDim Preserve test(i)
test(i) = wsSheet.Name
i = i + 1
End If
End With
Next wsSheet
End If
End With
ThisWorkbook.Sheets(test()).Select
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=pdfpath & "\ouput.pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
End Sub
Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function
The answer might change a little depending on your definition of populated sheets. You would have to alter the condition "If .UsedRange.Address <> "$A$1" Then "
One possible alternative to above is WorksheetFunction.CountA(Range("A1:Z100")) <> 0
Please let me know if you need any assistance with the condition or the code.
This is going to depend somewhat on what exactly you mean by 'automatically check if these sheets have been populated'. My crystal ball says that each worksheet has a header row and would be considered 'populated' if there was any data below the first row. In that case, you could cycle through all worksheets and construct an array of worksheet names to be selected. Once multiple worksheets are selected, the PDF creation would be on ActiveSheet.ExportAsFixedFormat not ActiveWorkbook.ExportAsFixedFormat and only those worksheets selected would be included in the PDF.
Dim w As Long, sWSs As String, vWSs As Variant
For w = 1 To Sheets.count
With Sheets(w)
If .Cells(1, 1).CurrentRegion.Rows.count > 1 Then _
sWSs = sWSs & .Name & Chr(215)
End With
Next w
If CBool(Len(sWSs)) Then
vWSs = Split(Left(sWSs, Len(sWSs) - 1), Chr(215))
Sheets(vWSs).Select
ChDir _
"P:\Cells\Spool & Sleeves Cell\Flow Plot Records\EFA\Saved EFA PDF Archive"
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"P:\Cells\Spool & Sleeves Cell\Flow Plot Records\EFA\Saved EFA PDF Archive\" & fname, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
Else
MsgBox "Nothing to publish to PDF."
End If
I've tested this with my own sample workbook then tried to incorporate your code sample specifics into my method. If it doesn't work the first time post back a comment and I may be able to offer assistance.

Resources