Trouble running a VBA macro from VBS - excel

I'm writing a script in VBS to run a macro on many excel files in a directory. I'm new to VBS and macros.
The root directory has a number of folders in it. Inside each folder is a number of sub folders. I'm looking for folders at this level called "inspection". Inside of those folders I'm looking for files that match the pattern .050. or .120.. If those files are found I want to run an Excel macro on them to modify the footer.
I've managed to set up all of the logic to search for the files and that seems to be working. I've got a macro recorded in my PERSONAL.XLSB file and I can open files individually and run the macro successfully.
The problem: When I try to call the macro from code I get the following error:
Cannot run the macro
The macro may not be available in this workbook or all macros may be disabled.
I have macros enabled in Excel. I've tried a number of methods for running the macro but haven't been able to get any to work.
My VBS script:
DIM FSO, rootFolder, subFolders, subFolder, inspectionFolders, inspectionFolder, inspectionFiles, inspectionFile, wb
Set FSO = CreateObject("Scripting.FileSystemObject")
Set rootFolder = FSO.GetFolder("N:\ENGINEERING-Test")
Set subFolders = rootFolder.SubFolders
For Each subFolder in subFolders
WScript.Echo "in " + rootFolder
WScript.Echo "found folder " + subFolder.Name
Set inspectionFolders = subFolder.SubFolders
For Each inspectionFolder in inspectionFolders
WScript.Echo "found folder " + inspectionFolder.name
If InStr(1, inspectionFolder.Name, "Inspection", vbTextCompare) Then
WScript.Echo "In inspection Folder"
Set inspectionFiles = inspectionFolder.files
For Each inspectionFile in inspectionFiles
WScript.Echo "Checking File " + inspectionFile.name
If InStr(1, inspectionFile.Name, ".050.", vbTextCompare) > 0 Or InStr(1, inspectionFile.Name, ".120.", vbTextCompare) > 0 Then
WScript.Echo "Found file " + inspectionFile.name
Set xlApp = CreateObject("Excel.application")
Set xlBook = xlApp.Workbooks.Open(inspectionFolder & "\" & inspectionFile.name, 0, False)
xlApp.Application.Visible = False
xlApp.Application.Run "C:\Users\Nick\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB!Module1.ModifyHeaderFooter"
xlApp.ActiveWindow.close
xlApp.Quit
Else
End If
Next
Else
End If
Next
Next
My macro:
Sub ModifyHeaderFooter()
'
' ModifyHeaderFooter Macro
'
'
With ActiveSheet.PageSetup
.PrintTitleRows = "$1:$3"
.PrintTitleColumns = ""
End With
ActiveSheet.PageSetup.PrintArea = ""
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = "Company, LLC"
.RightFooter = "Page &P of &N&8" & Chr(10) & ""
.LeftMargin = Application.InchesToPoints(0.45)
.RightMargin = Application.InchesToPoints(0)
.TopMargin = Application.InchesToPoints(0)
.BottomMargin = Application.InchesToPoints(0.58)
.HeaderMargin = Application.InchesToPoints(0)
.FooterMargin = Application.InchesToPoints(0)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 300
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlLandscape
.Draft = False
.PaperSize = xlPaperLetter
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = 100
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = False
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
End Sub
At this point I'm able to find the files I'm looking for, and the script attempts to execute the macro, but I get an error. Can anyone see what I'm doing wrong?

Try just xlApp.Run("PERSONAL.XLSB!ModifyHeaderFooter")

In the end I moved
Set xlApp = CreateObject("Excel.application")
outside of my loops and changed
xlApp.Application.Run "C:\Users\Nick\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB!Module1.ModifyHeaderFooter"
to
xlApp.Run("PERSONAL.XLSB!ModifyHeaderFooter")
and my error was resolved. I also added
xlApp.Workbooks.Open("C:\Users\Nick\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
at the point just before I called the macro. I may have been doing something else wrong, but when I opened it once outside of the loops it only worked for one iteration. Thanks to Scott and Garbb for the contributions and thanks to Scott for the additional efficiency tips.

Related

VBA - PRINT VIEW show selection range on ONE page

I'm trying to get a code which will automatically set the print view mode around a certain range of cells (selected cells - as it has to be dynamic) and remove the page number (PAGE 1 in black superposed on cells).
I have tried the following (below), however it doesn't work as it grabs all the sheet data and puts it on one page instead of just showing the selected range on one page.
Dim myRange As Range
Set myRange = Selection
ActiveWindow.View = xlPageBreakPreview
myRange.Select
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
Application.PrintCommunication = True
ActiveSheet.PageSetup.PrintArea = ""
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.708661417322835)
.RightMargin = Application.InchesToPoints(0.708661417322835)
.TopMargin = Application.InchesToPoints(0.748031496062992)
.BottomMargin = Application.InchesToPoints(0.748031496062992)
.HeaderMargin = Application.InchesToPoints(0.31496062992126)
.FooterMargin = Application.InchesToPoints(0.31496062992126)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
Application.PrintCommunication = True
End Sub
So basically I want the selected cells to be highlighted (white) and put only on one page (no page breaks) and anything else in the sheet to be put outside of the print view (in that gray/black view).
Any thoughts would be welcome.
Thank you !
One thing to remember when recording macros is that default settings don't usually need to be mentioned, unless you're changing the figure.
So things like .LeftHeader = "" aren't needed unless you're specifically removing text from the left header - by default it's blank, and this code is just saying keep it blank.
The page number superimposed on the sheet is just because you're in Page Break Preview (your code puts you in that at the start). You only need to look at that view if you're manually changing the print - using code just stay in the Normal view (it's rare you have to Select anything with VBA before working with it).
This code worked for me:
Sub Test()
Dim PrintRange As Range
Set PrintRange = Selection
With PrintRange.Parent.PageSetup 'The Parent of Selection is the sheet.
Application.PrintCommunication = True
.PrintArea = PrintRange.Address
Application.PrintCommunication = False
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
End Sub

Excel VBA Shape in Header

I'm currently working on a worksheet where I want to print a certain shape/picture on the header of the print page. Right now, I have saved the picture on my pc and call it from there. However, the workbook is going to be spread, and I just don't want everybody to download the picture. I have de picture currently in the same worksheet as what needs to be printed however it would be a dream if the picture could also be in a different worksheet within the workbook. The name of the picture = Logo. The code I use right now is when the picture is downloaded locally on the pc.
Dim PathLogo As String
PathLogo = Sheets("HOME").Range("BI78").Value
With ActiveSheet.PageSetup.RightHeaderPicture
.Filename = PathLogo
.Height = Application.CentimetersToPoints(1.5)
.Width = Application.CentimetersToPoints(1.5)
End With
With ActiveSheet.PageSetup
.PrintArea = "$A$2:$X$103"
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.HeaderMargin = 0
.TopMargin = Application.CentimetersToPoints(1.5)
.BottomMargin = Application.CentimetersToPoints(1)
.CenterHorizontally = True
.CenterVertically = True
.RightHeader = "&G"
.CenterHeader = "&B&16&U&K595959" & Worksheets("HOME").Range("AJ71").Value
.RightFooter = "&D" & " " & "&T"
End With
ActiveSheet.Range("A2:X103").PrintOut

VBA loop only works for first two sheets - how to fix?

I have been working on this macro for a few days now, and have hit a problem which I haven't been able to solve with my limited VBA knowledge. It works fine for the first two sheets, but after that it seems to be going wrong and not returning the correct ranges from the second workbook (MACRO Customs Invoices) or re-merging the cells in ThisWorkbook, so the end pdf doesn't have the information I want as is formatted all wrong. Please help me, good people! Your help would be hugely appreciated.
Sub VBAexperimentalv6()
Dim invoice As Workbook
Dim invoicews As Worksheet
Dim origlotno As Range
Dim invoiceci As Range
Dim macroci As Range
Dim remlotno As Range
Dim rhci As Range
Set invoice = ThisWorkbook
For Each invoicews In ThisWorkbook.Worksheets
invoicews.Activate
Set origlotno = Range("D15", Range("D15").End(xlDown))
Set invoiceci = Range("F15", Range("F15").End(xlDown))
Set remlotno = invoicews.Range("D15:E15")
Set remlotno = remlotno.Resize(origlotno.Rows.Count)
remlotno.UnMerge 'unmerges lot number column
With origlotno
Workbooks("MACRO Customs Invoices.xlsx").Sheets("Sheet1").Range("A2").Resize(.Rows.Count, .Columns.Count).Value2 = .Value2 'copies lot numbers from invoice to macro in dynamic ranges
End With
invoicews.Range("D5:K5").UnMerge 'unmerges client name cells
Workbooks("MACRO Customs Invoices.xlsx").Sheets("Sheet1").Range("M3").Value = invoicews.Range("D5").Value ' copies client name to formula sheet
Set macroci = Workbooks("MACRO Customs Invoices.xlsx").Sheets("Sheet1").Range("J2")
Set macroci = macroci.Resize(invoiceci.Rows.Count, invoiceci.Columns.Count)
invoiceci.Value = macroci.Value ' copies customs info into invoice
invoicews.Range("D5:K5").Merge 'merges client name
remlotno.Merge (True) ' merges lot no in variable range
invoicews.Rows("2:2").RowHeight = 60 ' sets address row to correct height
Set rhci = invoicews.Rows("15:15")
Set rhci = rhci.Resize(origlotno.Rows.Count)
rhci.RowHeight = 21 'resizes lot no rows to allow for two lines
Application.PrintCommunication = False
With invoicews.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
Application.PrintCommunication = True
invoicews.PageSetup.PrintArea = ""
Application.PrintCommunication = False
With invoicews.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.393700787401575)
.RightMargin = Application.InchesToPoints(0.196850393700787)
.TopMargin = Application.InchesToPoints(0.393700787401575)
.BottomMargin = Application.InchesToPoints(0.393700787401575)
.HeaderMargin = Application.InchesToPoints(0.393700787401575)
.FooterMargin = Application.InchesToPoints(0.393700787401575)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 300
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 0
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = False
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
Application.PrintCommunication = True
invoicews.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\Richard\Documents\Sortcoding\Customs Invoices\" & Workbooks("MACRO Customs
Invoices.xlsx").Sheets("Sheet1").Range("M2").Value _
, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=False ' saves as pdf using formula generated file name
Workbooks("MACRO Customs Invoices.xlsx").Sheets("Sheet1").Range("A2:A250").Clear ' clear formula sheet ready for next invoice
Next invoicews
End Sub

Excel VBA Set Print Area and Print ALL

I am new to the wonders and world of Macro, VBA and RPA, and would like to study it more. Recently did a short course on RPA.
Just want to share my problem and throw a question out to the Community here.
My Pain Point:
I’m the person printing the Payslips for the Company.
Currently I am opening all 30+ Single Excel File Payslips generated by Excel VBA (not done by me) for my company one by one and setting to print by Set Print Area for EACH Payslip Standalone Excel File, and printing them one by one.
This takes up quite some time which I believe can be saved with either the right Print Settings, VBA or RPA.
Unfortunately I am still exploring these and know nothing about VBA.
Id like to check for VBA, how I can go about macro-ing the process such that I can ease my workflow in the following:
Opening Payslip one by one
Setting the Print Area (same throughout)
Printing
If any of these can be automated it'd save me time and frustration.
Regarding the code it might be a merge of these two
https://www.ablebits.com/office-addins-blog/2019/08/20/set-change-print-area-excel/
https://www.excelhowto.com/macros/print-all-workbooks-in-a-folder/
Anyone can advise step by step what I am to do? I have read and tried but do not understand still.
Tested and working.
This code loops files in a folder, selects A1:K41 and prints the selected range to your standard printer.
Sub run()
FolderPath = "PATH TO FOLDER"
FileNme = Dir(FolderPath & "\*.xlsx") ' returns the first xlsx file in the folder
Do While Len(FileNme) > 0 ' loop while there are files.
Set wb1 = Workbooks.Open(FolderPath & "\" & FileNme) ' open file
wb1.Sheets("Sheet1").Range("A1:K41").Select ' select the range
'below is recorded macro of print selected area
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.7)
.RightMargin = Application.InchesToPoints(0.7)
.TopMargin = Application.InchesToPoints(0.75)
.BottomMargin = Application.InchesToPoints(0.75)
.HeaderMargin = Application.InchesToPoints(0.3)
.FooterMargin = Application.InchesToPoints(0.3)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
Application.PrintCommunication = True
Selection.PrintOut Copies:=1, Collate:=True
'close payslip
Application.DisplayAlerts = False
wb1.Close
Application.DisplayAlerts = True
FileNme = Dir ' get the next file name
Loop
End Sub

Select cell ranges and then print

I have the following code which works fine:
Sheets("File1").Select
Range("B2:J56").Select
Selection.PrintOut Copies:=1, Collate:=True
But I need to print several ranges and the pages should comply with the following formats:
every selection should fit an A4 paper
double-sided
columns adjusted in one page so that the content fits entirely in the page width
quality print of 600 dpi
margins centred (horizontally and vertically)
pages should include a header "This data was collected a year ago"
After struggling on the internet to no avail, I have recorded a macro but there are still many errors when I try to reproduce the code snippet,
specially in time execution error #1004 in line ActiveSheet.PageSetup.PrintArea = "$B$2:$J$56;$L$2:$T$37;$V$2:$AH$37" and print communication method failed.
[EDIT]: Solution implemented below
Sub RECORDED_Macro_Print_test()
Application.ScreenUpdating = False
Sheets("File1").Select
Range("B2:J83,L2:T37,V2:AO92").Select
Range("V2").Activate
ActiveSheet.PageSetup.PrintArea = "$B$2:$J$83;$L$2:$T$37;$V$2:$AO$92" ' <----- Fix it by replacing ';' by ',' as suggested by the user 'Siva'
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintTitleRows = "" ' <----- Not necessary
.PrintTitleColumns = "" ' <----- Not necessary
.LeftHeader = "" ' <----- Not necessary
.CenterHeader = "This data was collected a year ago"
.RightHeader = "" ' <----- Not necessary
.LeftFooter = "" ' <----- Not necessary
.CenterFooter = "" ' <----- Not necessary
.RightFooter = "" ' <----- Not necessary
.LeftMargin = Application.InchesToPoints(0.511811023622047)
.RightMargin = Application.InchesToPoints(0.511811023622047)
.TopMargin = Application.InchesToPoints(0.78740157480315)
.BottomMargin = Application.InchesToPoints(0.78740157480315)
.HeaderMargin = Application.InchesToPoints(0.31496062992126)
.FooterMargin = Application.InchesToPoints(0.31496062992126)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = True
.CenterVertically = True
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
.EvenPage.LeftHeader.Text = "" ' <----- Not necessary
.EvenPage.CenterHeader.Text = "" ' <----- Not necessary
.EvenPage.RightHeader.Text = "" ' <----- Not necessary
.EvenPage.LeftFooter.Text = "" ' <----- Not necessary
.EvenPage.CenterFooter.Text = "" ' <----- Not necessary
.EvenPage.RightFooter.Text = "" ' <----- Not necessary
.FirstPage.LeftHeader.Text = "" ' <----- Not necessary
.FirstPage.CenterHeader.Text = "" ' <----- Not necessary
.FirstPage.RightHeader.Text = "" ' <----- Not necessary
.FirstPage.LeftFooter.Text = "" ' <----- Not necessary
.FirstPage.CenterFooter.Text = "" ' <----- Not necessary
.FirstPage.RightFooter.Text = "" ' <----- Not necessary
End With
Application.PrintCommunication = True ' <----- Remove this line to fix it. This is an error issue
Selection.PrintOut Copies:=1, Collate:=True
End Sub
To record the macro I have basically selected all the ranges I needed by holding the SHIFT key, then I defined the print area, then pressed print, specified all constraints in the dialog box and voilà. How to get it to work?
Replace your code line
ActiveSheet.PageSetup.PrintArea = "$B$2:$J$56;$L$2:$T$37;$V$2:$AH$37"
with
ActiveSheet.PageSetup.PrintArea = "$B$2:$J$56,$L$2:$T$37,$V$2:$AH$37"
I have tried it in my machine and that line didn't give any error after replacing

Resources