Pass variable from PowerShell to VBA macro? - vba

I have a PowerShell script that automates some report processing, and I have numerous separate macros to perform very similar autofilter functions, but on different criteria.
Is it possible to pass this criteria from PowerShell into the macro? I could then just have the 1 macro.
ColNum = Application.Match("*header", Range("A1:Z1"), 0)
If Not IsError(ColNum) Then
ActiveSheet.Range("A1").AutoFilter Field:=ColNum, Criteria1:="$criterafromPowerShell", Operator:=xlAnd
End If
I currently do a similar thing but the other way round, the output from these macros I insert to the workbook and extract back to PowerShell like so:
$counts = $workbook.worksheets.item(2)
$xRows = $counts.cells.item(1,1).Text
$yeRows = $counts.cells.item(1,2).Text
I concede I could possibly do this the other way round, and insert the text I want to use in a worksheet after the file is opened and before the macros are run, then pick it up inside the macro... but it seems messy.
Any suggestions?

Example:
$xlApp = New-Object -ComObject "Excel.Application"
$xlApp.Workbooks.Open("C:\Users\MacroMan\Documents\MyMacroWorkbook.xlsm")
$returnValue = $xlApp.Run("'MyMacroWorkbook.xlsm'!GenerateString", 6)
Echo $returnValue
FOOBAR
$returnValue = $xlApp.Run("'MyMacroWorkbook.xlsm'!GenerateString", 3)
Echo $returnValue
FOO
In the "MyMacroWorkbook" (VBA):
Public Function GenerateString(strLength As Integer) As String
GenerateString = Left("FOOBAR_SOMETHING", strLength)
End Function

I use the below code to pass two arguments from my VBscript to open a prticular workbook and launch required macro, you could pass the variable you want as a variable to the sub, i.e. Sub test(passedvariablehere) and make the sub to account for it:
'Create a WshShell to get the current directory
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
If (Wscript.Arguments.Count < 2) Then
Wscript.Quit
End If
'retrieve the arguments
Dim strWorkerWB
strWorkerWB = Wscript.Arguments(0)
Dim strMacroName
strMacroName = Wscript.Arguments(1)
' Create an Excel instance
Dim myExcelWorker
Set myExcelWorker = CreateObject("Excel.Application")
myExcelWorker.Application.Visible = True
' Open the Workbook specified on the command-line
Dim oWorkBook
Set oWorkBook = myExcelWorker.Workbooks.Open(strWorkerWB)
on error resume next
' Run the calculation macro
myExcelWorker.Run strMacroName
if err.number <> 0 Then
' Error occurred - just close it down.
oWorkBook.Close
Set oWorkBook = Nothing
myExcelWorker.Quit
Wscript.Quit
End If
err.clear
oWorkBook.Close
Set oWorkBook = Nothing
myExcelWorker.Quit
Set myExcelWorker = Nothing
Set WshShell = Nothing
on error goto 0
First argument is the fullpath/name to workbook, second argument is the sub name

Related

Automated Export of Access Table-Data to Populate Template Excel Sheet

I am working on exporting filtered table data from Access to an Excel sheet, yet I can only get the table data to export into new Excel files and not into template Excel files (with pre-made graphs to be populated).
I mainly have been using macros on Access to create a switchboard where the user presses a switchboard-button and the filtered data exports from a table in Access to a new Excel file in a Reports folder. I do not know that macros are able to export with template Excel files, so I have turned to learning VBA. I am new to VBA so I apologize for my trivial understanding. I have created some VBA code based off of a tutorial from Access Jujitsu on Youtube.
Private Sub Command0_Click()
On Error GoTo SubError
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim SQL As String
Dim rs1 As DAO.Recordset
Dim i As Integer
Dim qtr As String
'Show user work is being performed
DoCmd.Hourglass (True)
'*********************************************
' RETRIEVE DATA
'*********************************************
'SQL statement to retrieve data from database
SQL = "SELECT Obj, Owner, Recom, Goal, Quality of Measure" & _
"FROM Inventory " & _
"WHERE Owner = ASM" &
"ORDER BY Recom "
'Execute query and populate recordset
Set rs1 = CurrentDb.OpenRecordset(SQL, dbOpenSnapshot)
'If no data, don't bother opening Excel, just quit
If rs1.RecordCount = 0 Then
MsgBox "No data selected for export", vbInformation + vbOKOnly, "No data exported"
GoTo SubExit
End If
'*********************************************
' BUILD SPREADSHEET
'*********************************************
'Create an instance of Excel and start building a spreadsheet
'Early Binding
Set xlApp = Excel.Application
xlApp.Visible = True
Set xlBook = xlApp.Workbooks.Open("\Users\Desktop to TemplateACC.xlsx")
Set xlSheet = xlBook.Worksheets(1)
With xlSheet
'Set second page title - pull quarter and year off of first row
'Won't work if you are pulling multiple time periods!
Select Case Nz(rs1!SalesQuarter, "")
Case 1
qtr = "1st"
Case 2
qtr = "2nd"
Case 3
qtr = "3rd"
Case 4
qtr = "4th"
Case Else
qtr = "???"
End Select
.Range("B3").Value = qtr & " Quarter " & Nz(rs1!SalesYear, "????")
'provide initial value to row counter
i = 1
'Loop through recordset and copy data from recordset to sheet
Do While Not rs1.EOF
.Range("I" & i).Value = Nz(rs1!Owner, "")
.Range("J" & i).Value = Nz(rs1!Goal, 0)
.Range("K" & i).Value = Nz(rs1!Recom, 0)
i = i + 1
rs1.MoveNext
Loop
End With
SubExit:
On Error Resume Next
DoCmd.Hourglass False
xlApp.Visible = True
rs1.Close
Set rs1 = Nothing
Exit Sub
SubError:
MsgBox "Error Number: " & Err.Number & "= " & Err.Description, vbCritical + vbOKOnly, _
"An error occurred"
GoTo SubExit
End Sub
Private Sub Form_Load()
End Sub
My code will not run as it says the "User-defined type is not defined" upon error. I have built this code from a button on a new form, opening the VBA coding template by building the event from the button. I am not sure why the code will not run. It is supposed to export to a pre-existing file called "TemplateACC" but instead this error appears. Thank you for sticking with me on this!
Have you added the Excel object library?
In the VBA editor go to Tools -> References, find Microsoft Excel 1X.0 Object Library and check it.
X depends on the version of Excel installed, but there should only be one, probably 14 to 16.
Binding may be your issue. You can implement early binding by adding the MS Excel Object Library to your References (Tools --> References), or you can implement late binding like below:
Private Sub Command0_Click()
Dim xlApp As object
Dim xlBook As object
Dim xlSheet As object
''If excel is already Running, grab that instance of the program, if not, create new
set xlApp = GetExcel
set xlBook = xlApp.Workbooks.Open("\Users\Desktop to TemplateACC.xlsx")
Set xlSheet = xlBook.Worksheets(1)
''... do other stuff
End sub
Function GetExcel() As Object 'Excel.Application
'Updated: 2009-10-13
'Used to grab the Excel application for automation
If DetectExcel Then
Set GetExcel = GetObject(, "Excel.Application")
Else
Set GetExcel = CreateObject("Excel.Application")
End If
End Function
Function DetectExcel() As Boolean
' Procedure dectects a running Excel and registers it.
Const WM_USER = 1024
Dim hwnd As Long
''If Excel is running this API call returns its handle.
hwnd = FindWindow("XLMAIN", 0)
If hwnd = 0 Then ' 0 means Excel not running.
DetectExcel = False
Exit Function
''Excel is running so use the SendMessage API
''function to enter it in the Running Object Table.
DetectExcel = True
SendMessage hwnd, WM_USER + 18, 0, 0
End If
End Function

VBA Code crashes PPT Application - unclear reason

I have a problem with the following Code. What happens is that my PPT application crashes while running the code. It does not always happen and it happens in different parts of the code.
I tried the application.wait-method, but it did not work.
help is appreciated since I am already working on this for days -.-. Thanks in advance.
Option Explicit
Public myfilename As String
Sub filepicker()
Dim i As Variant
MsgBox ("In the following dialog please choose the current file")
Dim myfilenamepicker As FileDialog
Set myfilenamepicker = Application.FileDialog(msoFileDialogFilePicker)
myfilenamepicker.InitialFileName = "C:\Users\Michael\Desktop\Test PPT"
myfilenamepicker.Show
If myfilenamepicker.SelectedItems.Count <> 0 Then
myfilename = myfilenamepicker.SelectedItems(1)
End If
End Sub
Sub Saveas_PPT_and_PDF()
Dim PP As PowerPoint.Presentation
Dim sh As Variant
Dim company, strPOTX, strPfad, pptVorlage, newpath, newpathpdf As String
Dim Cell As Range
Dim pptApp As Object
Call filepicker
Application.ScreenUpdating = False
' set the dropdown from which the company Is Selected
Set DropDown.ws_company = Tabelle2
' the company is the value selected in the dropdown, stored in "C2"
company = DropDown.ws_company.Range("C2").Value
On Error Resume Next
Set pptApp = GetObject(, "PowerPoint.Application")
On Error Resume Next
If pptApp Is Nothing Then
Set pptApp = CreateObject("PowerPoint.Application")
End If
On Error GoTo 0
'loop through the companies in the dropdown menu
For Each Cell In DropDown.ws_company.Range(DropDown.ws_company.Cells(5, 3), _
DropDown.ws_company.Cells(Rows.Count, 3).End(xlUp)).SpecialCells(xlCellTypeVisible)
DropDown.ws_company.Range("C2") = Cell
pptVorlage = myfilename
Debug.Print (myfilename)
Set PP = pptApp.Presentations.Open(pptVorlage)
newpath = Replace(myfilename, "AXO", "" & Cell & " AXO")
PP.UpdateLinks
PP.SaveAs newpath
newpathpdf = Replace(newpath, "pptx", "pdf")
Debug.Print (newpathpdf)
PP.ExportAsFixedFormat "" & newpathpdf & "", ppFixedFormatTypePDF, ppFixedFormatIntentPrint
pptApp.Presentations(newpath).Close
Set PP = Nothing
Next
' this part below closes PPT application if there are no other presentation
' object open. If there is at least 1, it leaves it open
If IsAppRunning("PowerPoint.Application") Then
If pptApp.Windows.Count = 0 Then
pptApp.Quit
End If
End If
Set pptApp = Nothing
Set PP = Nothing
End Sub
Function IsAppRunning(ByVal sAppName) As Boolean
Dim oApp As Object
On Error Resume Next
Set oApp = GetObject(, sAppName)
If Not oApp Is Nothing Then
Set oApp = Nothing
IsAppRunning = True
End If
End Function
I don't see anything obviously wrong but I can give you a strategy for debugging.
You will want to test all major manipulations seperately. You will want to run each test in the debugger and have screenupdating on so you can see what happens:
test the filepicker
test GetObject/CreateObject - do you really need it? You already have PowrPoint open it seems;
test your loop with a single hardcoded value. What happens with the focus when opening a presentation?
try without UpdateLinks; try without SaveAs and try without Export (i.e. just open a presentation and close it again).
check if the presentation really closes, otherwise you might end up with lots of open presentations.
test closing the application
test reading from a dropdown box
test the IsAppRunning function. Note that it sets On Error Resume Next but does not reset it. Note it does not set IsAppRunning = False anywhere.
try relevant parts of the above in a loop with and without debugging to see what happens and see if it crashes - there could be a timing problem in the Office application, e.g. trying to manipulate a presentation while it is not yet fully loaded.
Minimising your code can help isolate the area that causes the problem. I hope this helps.

Execute .vbs from a batch for a specific workbook

I have a .bat file and I'm using it to execute a .vbs which I've pulled out of an excel workbook.
Currently, my .bat file looks like:
echo Starting program
start C:\Users\midi\Desktop\Refresh_Data_Connection.vbs
echo Finish program
However, the issue with my .vbs file is that it doesn't reference a specific workbook which I need it to. How could I set the .vbs to alter a specific workbook stored on my desktop? Any help/feedback or push in the right direction would be really helpful, thanks in advance!
My vbs is:
Sub RefreshConns()
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Sheets("Run Macro").Activate
Dim connName As String ' connection name
Dim connStr As String ' connection string
Dim sqltext ' SQL text
Dim TempconnName As String ' temporary connection name
Dim TempconnStr As String ' temporary connection string
Dim Tempsqltext ' temporary SQL text
Dim i As Integer
Dim SiteName As String
SiteName = ActiveSheet.Cells(1, 2)
'MsgBox (SiteName)
For i = 5 To 11
connName = ActiveSheet.Cells(i, 1).Value
connStr = ActiveSheet.Cells(i, 2).Value
sqltext = ActiveSheet.Cells(i, 4).Value
'MsgBox (connName)
TempconnStr = Replace(connStr, "SiteNameVBA", SiteName)
'Debug.Print (ActiveWorkbook.Connections(connName).ODBCConnection.Connection)
'MsgBox (TempconnStr)
'Tempsqltext = Replace(sqltext, "SiteNameVBA", SiteName)
'On Error Resume Next
ActiveWorkbook.Connections(connName).ODBCConnection.CommandText = sqltext
ActiveWorkbook.Connections(connName).ODBCConnection.Connection = "ODBC;" & TempconnStr
ActiveWorkbook.Connections(connName).Refresh
Next i
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Public Function ZeroToBlank(x As String) As String
If x = "0" Then
ZeroToBlank = ""
Else
ZeroToBlank = x
End If
End Function
One way is to declare a system environment variable using setx.
Running your batch with administration privilege try this:
setx PATHFILE "/path/file.xls" /M
Check if is declared:
set | find "PATHFILE"
And read it with the function Environ() to open you Workbook in your vbs:
Workbooks.Open Environ("PATHFILE")
EDIT
You do not need to use system environment variable (/m argument) as you can use only user environment. You need to just remember that the programs need to restart to read the user and system environment variable.
Set xlBook = GetObject("C:\Users\User\Documents\Super.xls")
For each wsheet in xlbook.worksheets
msgbox wsheet.name
next
Is how. Remember there are no excel constants in VBS, there is no dim x as something as vbs only does variants. so just dim x.
Other ways to a running copy of excel
Set GetExcelApp = GetObject("", "Excel.Application")
Msgbox GetExcelApp
To start a new excel and showing an excel constant replaced by it's value (43).
set xlapp = createobject("Excel.Application")
xlapp.Workbooks.Open "C:\Users\User\Documents\Super.xls"
'43 is 95/97 look up xlExcel9795 in object browser to see other options
xlapp.ActiveWorkbook.SaveAs "C:\Users\User\Documents\Super.xls", 43

How to make Excel VBA variables available to multiple macros?

I have a string of macros that call upon each other and refer to workbooks A and B. I want the first macro to prompt the user to select document A and B and these Selections to become the workbook A and B variables I refer to in the various macros.
How do I make the selected documents the referred to variable throughout all the macros?
Thanks in advance!
Declare them outside the subroutines, like this:
Public wbA as Workbook
Public wbB as Workbook
Sub MySubRoutine()
Set wbA = Workbooks.Open("C:\file.xlsx")
Set wbB = Workbooks.Open("C:\file2.xlsx")
OtherSubRoutine
End Sub
Sub OtherSubRoutine()
MsgBox wbA.Name, vbInformation
End Sub
Alternately, you can pass variables between subroutines:
Sub MySubRoutine()
Dim wbA as Workbook
Dim wbB as Workbook
Set wbA = Workbooks.Open("C:\file.xlsx")
Set wbB = Workbooks.Open("C:\file2.xlsx")
OtherSubRoutine wbA, wbB
End Sub
Sub OtherSubRoutine(wb1 as Workbook, wb2 as Workbook)
MsgBox wb1.Name, vbInformation
MsgBox wb2.Name, vbInformation
End Sub
Or use Functions to return values:
Sub MySubroutine()
Dim i as Long
i = MyFunction()
MsgBox i
End Sub
Function MyFunction()
'Lots of code that does something
Dim x As Integer, y as Double
For x = 1 to 1000
'Lots of code that does something
Next
MyFunction = y
End Function
In the second method, within the scope of OtherSubRoutine you refer to them by their parameter names wb1 and wb2. Passed variables do not need to use the same names, just the same variable types. This allows you some freedom, for example you have a loop over several workbooks, and you can send each workbook to a subroutine to perform some action on that Workbook, without making all (or any) of the variables public in scope.
A Note About User Forms
Personally I would recommend keeping Option Explicit in all of your modules and forms (this prevents you from instantiating variables with typos in their names, like lCoutn when you meant lCount etc., among other reasons).
If you're using Option Explicit (which you should), then you should qualify module-scoped variables for style and to avoid ambiguity, and you must qualify user-form Public scoped variables, as these are not "public" in the same sense. For instance, i is undefined, though it's Public in the scope of UserForm1:
You can refer to it as UserForm1.i to avoid the compile error, or since forms are New-able, you can create a variable object to contain reference to your form, and refer to it that way:
NB: In the above screenshots x is declared Public x as Long in another standard code module, and will not raise the compilation error. It may be preferable to refer to this as Module2.x to avoid ambiguity and possible shadowing in case you re-use variable names...
You may consider declaring the variables with moudule level scope.
Module-level variable is available to all of the procedures in that module, but it is not available to procedures in other modules
For details on Scope of variables refer this link
Please copy the below code into any module, save the workbook and then run the code.
Here is what code does
The sample subroutine sets the folder path & later the file path. Kindly set them accordingly before you run the code.
I have added a function IsWorkBookOpen to check if workbook is already then set the workbook variable the workbook name
else open the workbook which will be assigned to workbook variable accordingly.
Dim wbA As Workbook
Dim wbB As Workbook
Sub MySubRoutine()
Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String
folderPath = ThisWorkbook.Path & "\"
fileNm1 = "file1.xlsx"
fileNm2 = "file2.xlsx"
filePath1 = folderPath & fileNm1
filePath2 = folderPath & fileNm2
If IsWorkBookOpen(filePath1) Then
Set wbA = Workbooks(fileNm1)
Else
Set wbA = Workbooks.Open(filePath1)
End If
If IsWorkBookOpen(filePath2) Then
Set wbB = Workbooks.Open(fileNm2)
Else
Set wbB = Workbooks.Open(filePath2)
End If
' your code here
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
Using Prompt to select the file use below code.
Dim wbA As Workbook
Dim wbB As Workbook
Sub MySubRoutine()
Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String
Dim filePath As String
cmdBrowse_Click filePath, 1
filePath1 = filePath
'reset the variable
filePath = vbNullString
cmdBrowse_Click filePath, 2
filePath2 = filePath
fileNm1 = GetFileName(filePath1, "\")
fileNm2 = GetFileName(filePath2, "\")
If IsWorkBookOpen(filePath1) Then
Set wbA = Workbooks(fileNm1)
Else
Set wbA = Workbooks.Open(filePath1)
End If
If IsWorkBookOpen(filePath2) Then
Set wbB = Workbooks.Open(fileNm2)
Else
Set wbB = Workbooks.Open(filePath2)
End If
' your code here
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
Private Sub cmdBrowse_Click(ByRef filePath As String, num As Integer)
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.AllowMultiSelect = False
fd.Title = "Select workbook " & num
fd.InitialView = msoFileDialogViewSmallIcons
Dim FileChosen As Integer
FileChosen = fd.Show
fd.Filters.Clear
fd.Filters.Add "Excel macros", "*.xlsx"
fd.FilterIndex = 1
If FileChosen <> -1 Then
MsgBox "You chose cancel"
filePath = ""
Else
filePath = fd.SelectedItems(1)
End If
End Sub
Function GetFileName(fullName As String, pathSeparator As String) As String
Dim i As Integer
Dim iFNLenght As Integer
iFNLenght = Len(fullName)
For i = iFNLenght To 1 Step -1
If Mid(fullName, i, 1) = pathSeparator Then Exit For
Next
GetFileName = Right(fullName, iFNLenght - i)
End Function
Create a "module" object and declare variables in there. Unlike class-objects that have to be instantiated each time, the module objects are always available. Therefore, a public variable, function, or property in a "module" will be available to all the other objects in the VBA project, macro, Excel formula, or even within a MS Access JET-SQL query def.

VBScript - How do I get these workbooks to talk?

I posted earlier about getting my VBScript to wait until a process had finished before continuing (further info: VBScript - How to make program wait until process has finished?.
I was given an adequate answer after some discussion. However, it seems that I am now going in a new direction with the code as the solution presented another problem that I am hoping you may be able to help me with.
Basically I have some code which I have provided below. It takes in 4 arguments, one of which is a PATH to a folder containing many files which I want to use along with the other three in my VBA macro.
If WScript.Arguments.Count = 4 Then
' process input argument
Set args = WScript.Arguments
arg1 = args.Item(0)
arg2 = args.Item(1)
arg3 = args.Item(2)
arg4 = args.Item(3)
' Create a WshShell instance
Dim WShell
Set WShell = CreateObject("WScript.Shell")
' Create an Excel instance
Dim x1
Set x1 = CreateObject("Excel.Application")
' Disable Excel UI elements
x1.DisplayAlerts = False
x1.AskToUpdateLinks = False
'x1.AlertBeforeOverwriting = False
x1.FeatureInstall = msoFeatureInstallNone
' Open the Workbooks specified on the command-line
Dim x1WB
Dim x2WB
Dim x3WB
Dim x4WB
Dim strWB1
Dim strWB2
Dim strWB3
Dim strWB4
Dim FSO
Dim FLD
Dim FIL
Dim strFolder
strWB1 = arg1
Set x1WB = x1.Workbooks.Open(strWB1)
' Show the workbook/Excel program interface. Comment out for silent running.
x1WB.Application.Visible = True
strWB2 = arg2
Set x2WB = x1.Workbooks.Open(strWB2)
' Show the workbook/Excel program interface. Comment out for silent running.
x2WB.Application.Visible = True
strWB3 = arg3
Set x3WB = x1.Workbooks.Open(strWB3)
' Show the workbook/Excel program interface. Comment out for silent running.
x3WB.Application.Visible = True
'To hold the string of the PATH to the multiple files
strFolder = arg4
Set FSO = CreateObject("Scripting.FileSystemObject")
'Get a reference to the folder I want to search
set FLD = FSO.GetFolder(strFolder)
Dim strMyMacro
strMyMacro = "my_excel_sheet_with_vba_module.xlsm!Sheet1.my_vba_macro"
'loop through the folder and get the file names
For Each Fil In FLD.Files
WshShell.run """C:\Program Files\Microsoft Office\Office14\EXCEL.exe"" " & Fil, 1, true
x1.Run strMyMacro
'~~> Problem - How do I get the macro to run before opening the above file but run after it has opened (due to setting the bWaitOnReturn to true)
'~~> Problem - How do I get the file on current iteration to close after the macro has completed?
'~~> Problem - If this is not the issue, can you identify it?
Next
x1WB.close
x2WB.close
x3WB.close
'x4WB.close
' Clean up and shut down
Set x1WB = Nothing
Set x2WB = Nothing
Set x3WB = Nothing
Set x4WB = Nothing
Set FSO = Nothing
Set FLD = Nothing
x1.Quit
Set x1 = Nothing
Set WshShell = Nothing
WScript.Quit 0
Else
WScript.Quit 1
End If
The script works like this:
4 arguments are passed to the script. The 3rd argument is a .xlsm file which contains my VBA macro. The last argument is a PATH to a folder containing multiple files.
It then opens up the first three Excel files.
Then I run a loop to iterate through the files Fil in the folder that was specified as the 4th argument. AFAIK this has to be done via a WScript.shell using the .run method so that the rest of the script will hang until the Excel file it is processing finishes before closing it and opening up the next file in the folder.
After opening up file Fil, I then run the macro (albeit at this moment in time unsuccessfully).
I was tempted to simply open up all of the Excel files using the WScript.shell object however AFAIK I would not be able to run the macro this way.
Hopefully I have been able to define my aims of this piece of VBScript though if I haven't let me know and I shall clarify. Can you help?
Thanks,
QF.
Something along these lines might work for you (in Excel). A few things I'm not clear on though:
Where is your existing VBA macro - I'm guessing it's in one of the 3 files you're opening?
What types of files are in the folder you're looping through? I guessed Excel.
How is the vbscript being run? It looks like you're shelling out from your HTA, but why not include it directly in the HTA? That would save you from having to shell out and pass arguments...
Option Explicit
Dim wb1 As Workbook, wb2 As Workbook
Sub ProcessFolder(path1, path2, sFolder)
Dim wb As Workbook
Dim s
Set wb1 = Workbooks.Open(path1)
Set wb2 = Workbooks.Open(path2)
If Right(sFolder, 1) <> "\" Then sFolder = sFolder & "\"
s = Dir(sFolder & "*.xls*", vbNormal)
Do While Len(s) > 0
Set wb = Workbooks.Open(sFolder & s)
ProcessFile wb
wb.Close False
s = Dir()
Loop
wb1.Close False
wb2.Close False
End Sub
Sub YourExistingMacro(wb As Workbook)
'do stuff with wb and presumably the other 3 open files...
End Sub