Current Situation
My Excel workbook contains anywhere from 10 to 32 worksheets used as templates. It also contains 1 worksheet called "Report". I currently loop through all template worksheets and put the information into the Report worksheet, then I create a PDF using that report worksheet.
However this creates 1 PDF per template because it passes through my Report worksheet.
Everytime I send the information to my Report worksheet, that gets turned into a PDF. The problem with that is it generates a PDF everytime my report worksheet gets filled in. I am not exporting my templates as PDF.
Code
Here's the code that generates 1 PDF file per template:
Sub CreatePDF()
Dim currentSerialNumber As String 'Worksheet name is the same as the serial number
Dim ws As Worksheet
Dim pdfFilePath As String
'Create a report for each serial number written in the Summary worksheet and export it to PDF
For i = 10 To Rows.Count 'Start at row #10
If IsEmpty(Worksheets("Summary").Range("B" & i).Value) = False Then
'Do work
currentSerialNumber = Worksheets("Summary").Range("B" & i).Value 'Fetches the serial number
pdfFilePath = "C:\" & currentSerialNumber & ".pdf" 'Ex: C:\1000.pdf
Worksheets(currentSerialNumber).Activate 'Activate the template for this current serial number
GenerateReport (currentSerialNumber) 'Put all the info from the template of this serial # into the report worksheet
Set ws = Worksheets("Reports") 'Set ws object as the report worksheet
ws.UsedRange.Select
ws.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=pdfFilePath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Else
'No more serial numbers found, exit this loop
Exit For
End If
Next i
End Sub
Goal
I want to loop through each template, send the information to my report, add that report information as a page in a PDF file, and repeat until no more templates.
The similar question linked would work if I was printing all my templates. But I'm actually sending my template information to a more professional, sleek looking report Worksheet. The report is then the one that I want into a PDF. The problem is, I only have one report worksheet that gets filled in by multiple templates.
Is this possible using VBA in Excel?
I think you can handle this in a loop. My idea is to do the following:
After copying the data to the "Report" sheet, create a Copy of that sheet in a new workbook. This new workbook will contain each of the "Report" sheets, and then you can export the entire new workbook
I haven't tested it, but let's try something like this:
Sub CreatePDF()
Dim currentSerialNumber As String 'Worksheet name is the same as the serial number
Dim ws As Worksheet
Dim pdfFilePath As String
Dim reports As Workbook
'## Add a new workbook an
Set reports = Workbooks.Add
ThisWorkbook.Activate
Do Until reports.Worksheets.Count = 1
reports.Worksheets(reports.Worksheets.Count).Delete
Loop
'Create a report for each serial number written in the Summary worksheet and export it to PDF
For i = 10 To Rows.Count 'Start at row #10
If IsEmpty(Worksheets("Summary").Range("B" & i).Value) = False Then
'Do work
currentSerialNumber = Worksheets("Summary").Range("B" & i).Value 'Fetches the serial number
pdfFilePath = "C:\" & currentSerialNumber & ".pdf" 'Ex: C:\1000.pdf
Worksheets(currentSerialNumber).Activate 'Activate the template for this current serial number
GenerateReport (currentSerialNumber) 'Put all the info from the template of this serial # into the report worksheet
Set ws = Worksheets("Reports") 'Set ws object as the report worksheet
'## Copy the Reports sheet to the new workbook
ws.Copy After:=reports.Worksheets(reports.Worksheets.Count)
Else
'No more serial numbers found, exit this loop
Exit For
End If
Next i
'## There is an empty worksheet in the Reports file, so we can remove it:
reports.Worksheets(1).Delete
'## select all sheets in reports:
reports.Worksheets.Select
'## Export the entire file as fixedformat:
reports.ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=pdfFilePath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Related
I am creating a workbook which will be used as a template for monthly reports (let's call it 'ReportWorkbookTest') and am struggling to write or record a macro which will paste data into the ReportWorkbookTest from various, unspecified workbooks.
To create the monthly reports, data is exported from a server to a .xlsx file named by the date/time the report was exported. Therefore, the name of the workbook which information will be pasted form will always have different names. The columns that the information in the monthly data exports will always remain the same (columns D:G & I). I've managed to do this for two specified workbooks but cannot transpose to new monthly data exports.
Range("I4").Select
Windows("Export 2018-06-21 11.51.34.xlsx").Activate
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=9, Criteria1:= _
xlFilterLastMonth, Operator:=xlFilterDynamic
Range("D2:G830,I2:I830").Select
Range("I2").Activate
Selection.Copy
Windows("ReportWorkbookTest.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Is there a way to set up the VBA so that the workbook names do not need to be specified while running the macro? Also, how do I specify that the macro only copies the active rows in the table if the number of rows changes per export?
Thanks!
If only these two workbooks will be open you can use numbers instead of the name:
Workbooks(1)
and
Workbooks(2)
Workbooks(1) will be the one that was opened first, more likely ReportWorkbookTest.xlsm where the macro will be, so you can provide instructions that this file should be opened first. If more than these two workbooks will be open you can try a loop approach, here is an example to use:
Dim wkb as Workbook
Dim thisWb as Workbook
Dim expWb as Workbook
Set thisWb = ThisWorkbook
For Each wkb in Workbooks
If wkb.Name Like "Export 2018-*" Then
expWb = wkb
Exit For
End If
Next
If Not expWb Is Nothing Then
'Found Export, do stuff like copy from expWb to thisWb
expWb.Worksheets(1).Range("B20:B40").Copy
thisWb.Sheets("PasteSheet").Range("A3").PasteSpecial xlValues
Else
'Workbook with Export name not found
End If
This is your framework, if you have multiple files to import then I would suggest a wizard instead.
Wizard framework would be:
1) prompt the user to select a file (of a certain type you might check for, can be a column name - header)
2) if it passes validation then import the data (and process it)
2b) if doesn't pass report it wasn't a valid file and prompt again
3) prompt for the next file type
......
I have a project like this that takes 4 different data "dumps" and merges them into a summary workbook each month.
But for a single file of changing name, here you go for a framework:
you can eliminate cycling through all of the worksheets if there is only one
you might also not be appending data to what already exists, but that is what finding the new last row is for.
Option Explicit
'Sub to get the Current FileName
Private Sub getFN()
Dim Finfo As String
Dim FilterIndex As Long
Dim Title As String
Dim CopyBook As Workbook 'Workbook to copy from
Dim CopySheet As Worksheet 'Worksheet to copy from
Dim FN As Variant 'File Name
Dim wsNum As Double 'worksheet # as you move through the Copy Book
Dim cwsLastRow As Long 'copy worksheet last row
Dim mwsLastRow As Long 'master worksheet last row
Dim masterWS As Worksheet 'thisworkbook, your master worksheet
Dim rngCopy1 As Range
Dim rngCopy2 As Range
Set masterWS = ThisWorkbook.Worksheets("Master Security Logs")
'Set up file filter
Finfo = "Excel Files (*.xls*),*.xls*"
'Set filter index to Excel Files by default in case more are added
FilterIndex = 1
' set Caption for dialogue box
Title = "Select the Current AP Reconcile Workbook"
'get the Forecast Filename
FN = Application.GetOpenFilename(Finfo, FilterIndex, Title)
'Handle file Selection
If FN = False Then
MsgBox "No file was selected.", vbExclamation, "Not so fast"
Else
'Do your Macro tasks here
'Supress Screen Updating but don't so this until you know your code runs well
Application.ScreenUpdating = False
'Open the File
Workbooks.Open (FN)
'Hide the file so it is out of the way
Set CopyBook = ActiveWorkbook
For wsNum = 1 To CopyBook.Sheets.Count 'you stated there will be 8, this is safer
'Do your work here, looks like you are copying certain ranges from each sheet into ThisWorkbook
CopySheet = CopyBook.Worksheets(wsNum) '1,2,3,4,5,6,7,8
'Finds the lastRow in your Copysheet each time through
cwsLastRow = CopySheet.Cells(CopySheet.Rows.Count, "A").End(xlUp).Row
'Set your copy ranges
Set rngCopy1 = CopySheet("D2:D"&cwsLastRow) 'this is your D column
Set rngCopy2 = CopySheet("I2:I"&cwsLastRow) 'this is your I column
'so you would have to keep tabs on what the lastRow of this sheet is too and always start at +1
mwsLastRow = masterWS.Cells(masterWS.Rows.Count, "A").End(xlUp).Row
'Copy the ranges in where you want them on the master sheet
'rngCopy1.Copy destination:= masterWS.Range("D"&mwsLastRow+1)
'rngCopy2.Copy destination:= masterWS.Range("I"&mwsLastRow+1)
'Clear the clipboard before you go around again
Application.CutCopyMode = False
Next wsNum
End If
'Close the workbook opened for the copy
CopyBook.Close savechanges:=False 'Not needed now
'Screen Updating Back on
Application.ScreenUpdating = True
End Sub
I have a VBA macro which allows me to export in CSV (using the comma as separator) some sheets of my excel file, in this case, first 7 sheets. I have following problems:
The code allows to export first 1 - n sheets, but I would like to put the code to select sheets by name. In this case I could also export the sheet 1, called "MILANO" and the sheet 5, called "ROME".
I cannot find the way to save the CSV files automatically in the same folder of the source excel file. I used ActiveWorkbook.Path or ThisWorkbook.Path, but I guess I wrong something
I cannot export only rows of each sheet not-empty as in the CSV I see hundreds of rows with ,,,,,,,,,
Here the macro:
Sub CreateCSV()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'-----------------------------
'DECLARE AND SET VARIABLES
Dim wb1 As Workbook, ws1 As Worksheet
Dim wbname As String, I As Integer
Set wb1 = ThisWorkbook
'-----------------------------
'CYCLE THROUGH SHEETS AND MATCH UPLOAD
For I = 1 To 7
wbname = Worksheets(I).Name
'-----------------------------
'COPY SHEET INTO NEW CSV FILE
Worksheets(I).Copy
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "/" & wbname & "/.csv", _
FileFormat:=xlCSV, CreateBackup:=False
ActiveWorkbook.Close
wb1.Activate
Next I
'-----------------------------
'CLEANUP
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Thanks!
try this for your point 2
ActiveWorkbook.SaveAs Filename:=wb1.Path & "\" & wbname & ".csv", _
With regards to accessing you sheets by name you can do this,
set sh = ThisWorkBook.Sheets("MILANO")
but since you would want to loop through your sheets anyway, you need have an array with you sheet names like so,
Dim mySheets as Variant
Dim sh as WorkSheet
Dim I as Long
mySheets=Array("MILANO" , "MONACO", "ROME")
For I = 0 to UBound(mySheets)
Set sh = ThisWorkBook.Sheets(mySheets(I))
sh.SaveAs FileName:=ThisWorkBook.Path & "\" & mySheets(I), _
FileFormat:=xlCSV
Next I
So you need to use the WorkSheet.SaveAs and not the WorkBook.SaveAs
as far as "I cannot export only rows of each sheet not-empty as in the CSV I see hundreds of rows with ,,,,,,,,," Perhaps you need to cleanup the Worksheet first
Does there exist a code to for example save every hour the data from A1:B10 in sheet1 to a CSV file ?
Although this can be done in many different ways, this is what I'd do:
1) Add the following sub to a new file. Let's call it "auto.xlsb"
Sub SaveRangeToCSV()
Dim rng As Range
Dim originWB As Workbook
Dim originWS As Worksheet
Dim newBook As Workbook
Dim newBookWS As Worksheet
'Open the file you want to copy the range from
Set originWB = Workbooks.Open("path_to_file_that_contains_the_range_you_want_to_copy.xlsx")
Set originWS = ThisWorkbook.Sheets("name_of_the_sheet_where_the_range_is")
Set rng = originWS.Range("A1:B10")
'Add new workbook (csv file)
Workbooks.Add
Set newBook = ActiveWorkbook
Set newBookWS = newBook.Sheets(1)
'Copy range from origin to destination (csv file)
rng.Copy Destination:=newBookWS.Range("A1")
'Save csv file
newBook.SaveAs Filename:=ThisWorkbook.Path & "\output.csv"
End Sub
If you want to avoid the output.csv to be overwritten every 10 minutes, you could, for example, add current datetime to the filename like this:
'Save csv file
newBook.SaveAs Filename:=ThisWorkbook.Path & "\output_" & Replace(Replace(Replace(Now, "/", ""), ":", ""), " ", "") & ".csv"
2) Add this code to Workbook_Open Sub (click ThisWorkbook sheet in VBA IDE, and select Workbook and Open from the dropdown) in auto.xlsb, and Save:
Private Sub Workbook_Open()
Call Module1.SaveRangeToCSV
End Sub
Every time you doble-click to open the file, SaveRangeToCSV will be triggered and, hence, the csv created.
3) Automating the execution of this file really depends on your preferences and the Operating System you are working on. I'm assuming your are on Windows, so the easiest way to do it would be creating a task in Windows' Task Scheduler which runs "auto.xlsb" every 10 minutes.
I hope this helps.
I am trying to extract a selection of worksheets from a workbook; worksheets whose names contain the string: "STRINGY", and export those worksheets as one single pdf. The code below creates a blank pdf.
Sub Test()
Application.CutCopyMode = False
For Each sht In ActiveWorkbook.Worksheets
If InStr(1, sht.Name, "STRINGY") > 0 Then
Sheets(sht.Name).Select Replace:=False
End If
Next sht
Selection.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\File.pdf"
Any help would be greatly appreciated.
You were along the right lines, but didn't use the Selection correctly. The following should do what you need:
Option Explicit
Sub Test()
Dim arrSheets() As String
Dim sht As Worksheet
Dim i As Integer
i = 0
For Each sht In ActiveWorkbook.Worksheets
If InStr(1, sht.Name, "STRINGY") > 0 Then
ReDim Preserve arrSheets(i)
arrSheets(i) = sht.Name
i = i + 1
End If
Next sht
ThisWorkbook.Sheets(arrSheets).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\File.pdf", _
OpenAfterPublish:=True
End Sub
Basically, you need to add the sheets whose name contain your search string in an array and select them all at the same time. Then use that selection as the basis for the export to PDF.
I added the OpenAfterPublish export option so that the file opens in your PDF reader after export; it's not a requirement.
The above code has been successfully tested with Excel 2010, but can't be certain it'll work in Excel 2007 or previous. Notice that an error will occur if the PDF add-in is not currently installed. If that's the case, you can find it at http://www.microsoft.com/downloads/details.aspx?familyid=4d951911-3e7e-4ae6-b059-a2e79ed87041.
I am working on writing a VBA code to export some of the sheets in excel to same PDF. I have several chart sheets in my excel file each of which name ends with "(name)_Chart".
I want to export all sheets with names ending wioth chart to one PDF file.
Here is the code I am trying to write.
Sub FindWS()
'look if it at least contains part of the name
Dim s As Worksheet
Dim strPath As String
strPath = ActiveWorkbook.Path & "\"
For Each s In ThisWorkbook.Sheets
If InStr(1, s.Name, Chart) Then
s.Activate
ActiveSheet.ExportAsFixedFormat xlTypePDF, strPath & s.Name & ".pdf"
Exit Sub
End If
Next s
End Sub
This code is not limting export to only the chart sheets but exporting thy whole workbook. Can anyone help me with figurint out whats is missing in my code.
Thanks!
MODIFIED CODE:
Sub FindWS()
'look if it at least contains part of the name
Dim s As Worksheet
Dim strPath As String
strPath = ActiveWorkbook.Path & "\"
For Each s In ThisWorkbook.Worksheets
If InStr(1, s.Name, "Chart") = 0 Then
' Hide the sheet so it is not exported as PDF
s.Visible = False
End If
Next s
With ActiveWorkbook
.ExportAsFixedFormat xlTypePDF, strPath & "TEST.pdf"
End With
End Sub
I am surprised that your code is running in the first place :) You should have actually got an error run time error '13', type mismatch
Sheets and Worksheets are two different things in Excel
The Worksheets collection is a collection of all the Worksheet objects in the specified or active workbook. Each Worksheet object represents a worksheet. Whereas the Sheets collection, on the other hand, consist of not only a collection of worksheets but also other types of sheets to include Chart sheets, Excel 4.0 macro sheets and Excel 5.0 dialog sheets.
So if you declare your object as Worksheet
Dim s As Worksheet
Then ensure that while looping you loop through the correct collection
For Each s In ThisWorkbook.Worksheets
and not
For Each s In ThisWorkbook.Sheets
else you will get a run time error '13', type mismatch
FOLLOWUP (Based on Comments)
# Siddharth: 1. Yes, I want to export Chart sheets that ends with name "Chart". 2. I want all those charts in one PDF and the name of the PDF should be the "original" file name. (I will have to save the final PDF files in different location so there will be no overlapping of files.) – datacentric
Option Explicit
Sub Sample()
Dim ws As Object
Dim strPath As String, OriginalName As String, Filename As String
On Error GoTo Whoa
'~~> Get activeworkbook path
strPath = ActiveWorkbook.Path & "\"
'~~> Get just the name without extension and path
OriginalName = Left(ActiveWorkbook.Name, (InStrRev(ActiveWorkbook.Name, ".", -1, vbTextCompare) - 1))
'~~> PDF File name
Filename = strPath & OriginalName & ".pdf"
'~~> Loop through Sheets Collesction
For Each ws In ActiveWorkbook.Sheets
'~~> Check if it is a Chart Sheet and also it ends in "Chart"
If ws.Type = 3 And UCase(Right(Trim(ws.Name), 5)) = "CHART" Then
ws.Visible = True
Else
ws.Visible = False
End If
Next ws
'~~> Export to pdf
ActiveWorkbook.ExportAsFixedFormat xlTypePDF, Filename
LetsContinue:
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
This code will look through all the sheets. If the sheet name doesn't match it will hide it. When it's finished that it exports all visible sheets into one PDF. Make sure yuo don't save the Excel file afterwards or the sheets will remain hidden.
Of course this code is not tested so if you have issues ask back (or try and resolve themself as you may learn something)
Sub FindWS()
'look if it at least contains part of the name
Dim s As Worksheet
Dim strPath As String
strPath = ActiveWorkbook.Path & "\"
For Each s In ThisWorkbook.Sheets
If InStr(1, s.Name, "Chart") = 0 Then
' Hide the sheet so it is not exported as PDF
s.Visible = False
End If
Next s
' Export all sheets as PDF
ActiveSheet.ExportAsFixedFormat xlTypePDF, strPath & "TEST.pdf"
End Sub