I have an Excel VBA macro which I need to run when accessing the file from a batch file, but not every time I open it (hence not using the open file event). Is there a way to run the macro from the command line or batch file? I'm not familiar with such a command.
Assume a Windows NT environment.
You can launch Excel, open the workbook and run the macro from a VBScript file.
Copy the code below into Notepad.
Update the 'MyWorkbook.xls' and 'MyMacro' parameters.
Save it with a vbs extension and run it.
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True)
xlApp.Run "MyMacro"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
The key line that runs the macro is:
xlApp.Run "MyMacro"
The simplest way to do it is to:
1) Start Excel from your batch file to open the workbook containing your macro:
EXCEL.EXE /e "c:\YourWorkbook.xls"
2) Call your macro from the workbook's Workbook_Open event, such as:
Private Sub Workbook_Open()
Call MyMacro1 ' Call your macro
ActiveWorkbook.Save ' Save the current workbook, bypassing the prompt
Application.Quit ' Quit Excel
End Sub
This will now return the control to your batch file to do other processing.
The method shown below allows to run defined Excel macro from batch file, it uses environment variable to pass macro name from batch to Excel.
Put this code to the batch file (use your paths to EXCEL.EXE and to the workbook):
Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"
Put this code to Excel VBA ThisWorkBook Object:
Private Sub Workbook_Open()
Dim strMacroName As String
strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
If strMacroName <> "" Then Run strMacroName
End Sub
And put your code to Excel VBA Module, like as follows:
Sub MyMacro()
MsgBox "MyMacro is running..."
End Sub
Launch the batch file and get the result:
For the case when you don't intend to run any macro just put empty value Set MacroName= to the batch.
you could write a vbscript to create an instance of excel via the createobject() method, then open the workbook and run the macro. You could either call the vbscript directly, or call the vbscript from a batch file.
Here is a resource I just stumbled accross:
http://www.codeguru.com/forum/showthread.php?t=376401
If you're more comfortable working inside Excel/VBA, use the open event and test the environment: either have a signal file, a registry entry or an environment variable that controls what the open event does.
You can create the file/setting outside and test inside (use GetEnviromentVariable for env-vars) and test easily. I've written VBScript but the similarities to VBA cause me more angst than ease..
[more]
As I understand the problem, you want to use a spreadsheet normally most/some of the time yet have it run in batch and do something extra/different. You can open the sheet from the excel.exe command line but you can't control what it does unless it knows where it is. Using an environment variable is relatively simple and makes testing the spreadsheet easy.
To clarify, use the function below to examine the environment. In a module declare:
Private Declare Function GetEnvVar Lib "kernel32" Alias "GetEnvironmentVariableA" _
(ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
Function GetEnvironmentVariable(var As String) As String
Dim numChars As Long
GetEnvironmentVariable = String(255, " ")
numChars = GetEnvVar(var, GetEnvironmentVariable, 255)
End Function
In the Workbook open event (as others):
Private Sub Workbook_Open()
If GetEnvironmentVariable("InBatch") = "TRUE" Then
Debug.Print "Batch"
Else
Debug.Print "Normal"
End If
End Sub
Add in active code as applicable. In the batch file, use
set InBatch=TRUE
Instead of directly comparing the strings (VB won't find them equal since GetEnvironmentVariable returns a string of length 255) write this:
Private Sub Workbook_Open()
If InStr(1, GetEnvironmentVariable("InBatch"), "TRUE", vbTextCompare) Then
Debug.Print "Batch"
Call Macro
Else
Debug.Print "Normal"
End If
End Sub
I have always tested the number of open workbooks in Workbook_Open(). If it is 1, then the workbook was opened by the command line (or the user closed all the workbooks, then opened this one).
If Workbooks.Count = 1 Then
' execute the macro or call another procedure - I always do the latter
PublishReport
ThisWorkbook.Save
Application.Quit
End If
# Robert: I have tried to adapt your code with a relative path, and created a batch file to run the VBS.
The VBS starts and closes but doesn't launch the macro... Any idea of where the issue could be?
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFilePath = objFSO.GetAbsolutePathName(".")
Set xlBook = xlApp.Workbooks.Open(strFilePath, "Excels\CLIENTES.xlsb") , 0, True)
xlApp.Run "open_form"
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
I removed the "Application.Quit" because my macro is calling a userform taking care of it.
Cheers
EDIT
I have actually worked it out, just in case someone wants to run a userform "alike" a stand alone application:
Issues I was facing:
1 - I did not want to use the Workbook_Open Event as the excel is locked in read only.
2 - The batch command is limited that the fact that (to my knowledge) it cannot call the macro.
I first wrote a macro to launch my userform while hiding the application:
Sub open_form()
Application.Visible = False
frmAddClient.Show vbModeless
End Sub
I then created a vbs to launch this macro (doing it with a relative path has been tricky):
dim fso
dim curDir
dim WinScriptHost
set fso = CreateObject("Scripting.FileSystemObject")
curDir = fso.GetAbsolutePathName(".")
set fso = nothing
Set xlObj = CreateObject("Excel.application")
xlObj.Workbooks.Open curDir & "\Excels\CLIENTES.xlsb"
xlObj.Run "open_form"
And I finally did a batch file to execute the VBS...
#echo off
pushd %~dp0
cscript Add_Client.vbs
Note that I have also included the "Set back to visible" in my Userform_QueryClose:
Private Sub cmdClose_Click()
Unload Me
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
ThisWorkbook.Close SaveChanges:=True
Application.Visible = True
Application.Quit
End Sub
Anyway, thanks for your help, and I hope this will help if someone needs it
I'm partial to C#. I ran the following using linqpad. But it could just as easily be compiled with csc and ran through the called from the command line.
Don't forget to add excel packages to namespace.
void Main()
{
var oExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
try{
var WB = oExcelApp.ActiveWorkbook;
var WS = (Worksheet)WB.ActiveSheet;
((string)((Range)WS.Cells[1,1]).Value).Dump("Cell Value"); //cel A1 val
oExcelApp.Run("test_macro_name").Dump("macro");
}
finally{
if(oExcelApp != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcelApp);
oExcelApp = null;
}
}
I generally store my macros in xlam add-ins separately from my workbooks so I wanted to open a workbook and then run a macro stored separately.
Since this required a VBS Script, I wanted to make it "portable" so I could use it by passing arguments. Here is the final script, which takes 3 arguments.
Full Path to Workbook
Macro Name
[OPTIONAL] Path to separate workbook with Macro
I tested it like so:
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlam" "Hello"
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlsx" "Hello" "%AppData%\Microsoft\Excel\XLSTART\Book1.xlam"
runmacro.vbs:
Set args = Wscript.Arguments
ws = WScript.Arguments.Item(0)
macro = WScript.Arguments.Item(1)
If wscript.arguments.count > 2 Then
macrowb= WScript.Arguments.Item(2)
End If
LaunchMacro
Sub LaunchMacro()
Dim xl
Dim xlBook
Set xl = CreateObject("Excel.application")
Set xlBook = xl.Workbooks.Open(ws, 0, True)
If wscript.arguments.count > 2 Then
Set macrowb= xl.Workbooks.Open(macrowb, 0, True)
End If
'xl.Application.Visible = True ' Show Excel Window
xl.Application.run macro
'xl.DisplayAlerts = False ' suppress prompts and alert messages while a macro is running
'xlBook.saved = True ' suppresses the Save Changes prompt when you close a workbook
'xl.activewindow.close
xl.Quit
End Sub
You can check if Excel is already open. There is no need to create another isntance
If CheckAppOpen("excel.application") Then
'MsgBox "App Loaded"
Set xlApp = GetObject(, "excel.Application")
Else
' MsgBox "App Not Loaded"
Set wrdApp = CreateObject(,"excel.Application")
End If
Related
I am trying to run an excel macro from access 2016. This has a lot of examples out their however they are all old. The exact error code I receive is run-time error '1004':
cannot run the macro "TestScript()". The macro may not be available in this workbook or all macros may be displayed. I am only running something easy for the test. I have ensured that macros is enabled in excel. the excel code is as follows
Public Sub TestScript()
MsgBox "IT WORKED"
End Sub
Real simple for the test. Access is opening the excel spreadsheet however it stops there with an error code.
My Access code is very simple and is below. I have also noted where the code stops. While I am new at VBA I have done a lot of research in this. I am testing as simple code as I could figure out. Any help would be welcomed.
Option Compare Database
Function runExcelmacro()
Dim XL As Object
Set XL = CreateObject("Excel.Application")
With XL
'Turn Off warnings
.Visible = False
.displayalerts = False
'WorkBook path such as "C:\Computer\WorkBook.xlsx"
.Workbooks.Open "C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm"
'Run the Macro in excel getworkbook
.Run TestScript 'Code stops here!
'Close Workbook
.ActiveWorkbook.Close (True)
.Quite
End With
Set XL = Nothing
End Function
Public Sub runMacroSub()
Call runExcelmacro("C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm", "TestScript")
End Sub
I guess OP did not put the code of Testscript in an extra module. Instead the code was put into the class module of the workbook or a worksheet. In the latter case you have to add the workbook or worksheet name in front of the name of the script.
Either it is `
.Run "ThisWorkbook.TestScript"
or in case it is in Sheet1 (codename of the sheet!)
.Run "Sheet1.TestScript"
Do not forget the quotation marks!
PS The OP's code above is working if you put testscript into a module and add quotation marks.
.Run "TestScript"
Here is a description how to create a module and add code
Here try this:
Public Sub TestScript()
MsgBox "IT WORKED"
End Sub
Option Compare Database
Function runExcelmacro()
Dim XL As Object, wb as object
Set XL = CreateObject("Excel.Application")
With XL
.Visible = False
.displayalerts = False
set wb = .Workbooks.Open "C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm"
wb.Run TestScript 'Code stops here!
.ActiveWorkbook.Close (True)
.Quite
End With
Set XL = Nothing
End Function
Public Sub runMacroSub()
Call runExcelmacro("C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm", "TestScript")
End Sub
Here i declared wb as an object and then set wb = to the workbook.
This is of course assumin your test script is in the actual workbook being opened. Would be real funny if that wasnt a thing lol
I have a .vba file located in a network folder let's call it helloworld.vba inside this file I have a sub function HelloFromTheOtherSide().
I'm trying to programmatically load this file in a way that I can execute the functions HelloFromTheOtherSide() in my excel instance.
Imagine that this is the content for simplicity:
Sub HelloFromTheOtherSide()
MsgBox ("hello there!")
End Sub
I've tried to follow these instructions on how to dynamically add and run a VBA macro from Visual Basic but that is not what I'm trying to do here as I want to be able to run calling HelloFromTheOtherSide().
I'm trying to understand if its possible to load a .vba from a folder to an excel instance programmatically in a way I could run the functions in my instance.
That would be quite usefull if possible as I would be able to store all my vba code in a single folder and load it from there everytime that I want to run something specific.
You can use both VBA or VBScript to call a Function or a Sub from another Workbook:
VBA
Sub callExternalFunction()
Dim xlApp As Object
Dim xlBook As Object
'Define Excel App
Set xlApp = CreateObject("Excel.Application")
'Open Workbook
Set xlBook = xlApp.Workbooks.Open("\\server\my\path\to\My library.xlsm", 0, True)
'Call my Sub, with eventual parameters (if you don't have any, just call the Routine)
xlApp.Run "Myfunction", "param_1", "param_2"
'Quit and clean
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
VBScript
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
'Define Excel App
Set xlApp = CreateObject("Excel.Application")
'Open Workbook
Set xlBook = xlApp.Workbooks.Open("R:\my\network\path\My Workbook.xlsm", 0, True)
'Call my Sub, with eventual parameters (if you don't have any, just call the Routine)
xlApp.Run "myRoutine"
'Quit and clean
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Edit
You can omit the Excel App initialization and directly call the Macro you need with this command (thanks to #TimWilliams):
Application.Run "'MyBook.xls'!MyMacroName"
Note: As you can see they are pretty similar. Both codes are tested and working on my Excel.
Hope this helps.
(Minimum requirements: Excel 2010 and Windows 7)
I have managed to use Bill Manville’s answer found in MSDN with minor changes. The suggested recursive code basically uses files’s Workbook_Open to create a separate instance and taht instance opens the file as editable with no prompts for read-only access.
Private Sub Workbook_Open()
Dim oXcl As Excel.Application
If Workbooks.Count > 1 Then
ThisWorkbook.Saved = True
ThisWorkbook.ChangeFileAccess xlReadOnly
Set oXcl = CreateObject("Excel.Application")
oXcl.ScreenUpdating = False
oXcl.Visible = True
oXcl.Workbooks.Open fileName:=ThisWorkbook.FullName, ReadOnly:=False
AppActivate oXcl.Caption
ThisWorkbook.Close SaveChanges:=False
Else
Call Continue_Open
End If
End Sub
The code works very well when Excel is already running as it creates a new instance of Excel and if a new Excel file is opened, it goes to a different Excel instance (running prior to it). But if the file with the Workbook_Open is the one that starts Excel, any further Excel files opened by double-clicking open within that Excel instance as it is the earliest run instance thus ceasing to be separate.
I have got as far as to be able to tell (Windows) whether that file starts Excel by using
Function NumberOfExcelInstances()
strComputer = "."
Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set proc = objWMI.ExecQuery("Select * from Win32_Process Where Name = 'Excel.exe'")
NumberOfExcelInstances = proc.Count
End Function
But I have not been able to find a way to tell NOT to use that Excel instance when opening new files. Any code should be bundled inside the Excel file with the Worbook_Open code.
How could I possibly include VBA code inside a file so that it opens in a separate Excel instance even when that file is the one that fires Excel?
After research on code at Application level, a working solution have been found. I am posting it, in case it is of interest to someone else.
When workbook opens the fist time it sets a workbook open event subroutine at Application level (rather than at Workbook level).
When a new workbook opens, the sub at Applictaion level opens a new instance with the workbook to be kept separate by recursivity - closes that workbook in the application instance that checks being separate thus removing the event handler from the application instance and sets that event handler and code on the newly created application instance.
All relevant code is included and it needs to be in three different modules.
1-a VBA Class Module named cXlEvents is created with the following code:
'VBA Class Module named cXlEvents
Public WithEvents appWithEvents As Application
'Instance variables
Dim sEventSetterPath As String
Dim sEventSetterName As String
Private Sub appWithEvents_WorkbookOpen(ByVal Wb As Workbook)
Call NewAppInstance(Wb, sEventSetterPath, sEventSetterName)
End Sub
2-ThisWorkbook Module includes:
'1-ThisWorkbook VBA Module calling events at
'Workbook level.
'2-At Workbook Open set Application level event
'handler and then instance code by calling subs
'held in VBA standard module.
Private Sub Workbook_Open()
Call SetEventHandler
Call NewAppInstance(Me)
End Sub
'Code to call "undo" special settings upon opening
'when file closes
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call UndoSettings
End Sub
3-All code necessary to create an instance at Workbook level Open event from a class which will end up at Application level is in a standard VBA Module:
'In a VBA standard Module
Dim oXlEvents As New cXlEvents
Sub SetEventHandler()
If oXlEvents.appWithEvents Is Nothing Then
Set oXlEvents.appWithEvents = Application
End If
End Sub
Sub NewAppInstance(wbWbook As Workbook, Optional sEventSetterPath As String, Optional sEventSetterName As String)
Dim oXcl As Excel.Application
Dim wbEventSet As Workbook
Dim lCaseNum As Long
Dim sResetMacro As String: sResetMacroName = "UndoSettings"
'Set instance variables
sEventSetterPath = ThisWorkbook.FullName
sEventSetterName = ThisWorkbook.Name
If wbWbook.ReadOnly And wbWbook.FullName = sEventSetterPath Then
MsgBox "Already open - please use open file.", , "WARNING"
wbWbook.Close False
Exit Sub
End If
If Workbooks.Count > 1 Then
If wbWbook.FullName <> sEventSetterPath Then
lCaseNum = 1
Set wbEventSet = Workbooks(1)
wbEventSet.Save
Application.Run "'" & sEventSetterName & "'!'" & sResetMacro & "'"
Else
lCaseNum = 2
Set wbEventSet = wbWbook
wbEventSet.Saved = True
End If
wbEventSet.ChangeFileAccess xlReadOnly
Set oXcl = CreateObject("Excel.Application")
oXcl.Workbooks.Open Filename:=sEventSetterPath, ReadOnly:=False
oXcl.Visible = True
Set oXlEvents.appWithEvents = Nothing
Select Case lCaseNum
Case Is = 1
AppActivate Application.Caption
Case Is = 2
AppActivate oXcl.Caption
End Select
wbEventSet.Close False
Else
Call Continue_Open
End If
End Sub
Sub Continue_Open()
'Code with special settings and procedures required for the workbook
End Sub
Sub UndoSettings()
'Code to "undo" any special settings when workbook opened
End Sub
I'm running a word macro that
initializes Excel
creates a temporary workbook in excel
when exiting the word userform, terminates excel
However, it seems there is some residual Excel instances/workbook that is not fully closed because when I start the word macro again, I get error: 462, remote server machine ...
initialize userform in a word document:
private sub commandbutton1_click()
dim exc as excel.application
set exc as new excel.application
dim wb as excel.workbook
set wb = exc.workbook.saveas filename:="wordexc" 'creates temp workbook
userform1.show
end sub
run excel processing via a userform1 commandbutton:
private sub commandbutton2_click()
excel.workbook("wordexc").close 'closes temp workbook
dim wb as excel.workbook
set wb = excel.workbook.saveas filename:="wordexc" 'this wb is for actual use
'i do not delete this wb after running cuz it has stored data that will be used
'if user cliks commandbutton2 again, it will be deleted and new wbook with new data
'is created
'processing code
end sub
private sub queryclose (etc...)
'Close Excel
Dim sKillExcel As String
sKillExcel = "TASKKILL /F /IM Excel.exe"
Shell sKillExcel, vbHide
end sub
btw i think the problem is the last part:
Dim sKillExcel As String
sKillExcel = "TASKKILL /F /IM Excel.exe"
Shell sKillExcel, vbHide
Cuz if I stop the macro and terminate EXCEL in task manager, it doesn't give me this problem if I run the macro again...
i
I also tried other methods, like calling a excel workbook i saved in a directory instead of a temporary one via createobject("excel.application") in one sub, exc.quit, but I have to use that termination code above cuz otherwise EXCEL still shows in task manager.
Besides not declaring your objects correctly, you are not (if I may say so) flushing the toilet correctly.
See this example (UNTESTED)
I am using Latebinding instead of Early Binding so that this code is compatible with any version of Excel
'~~> Define your Excel objects so that they are available
'~~> in other userform sub procedures as well.
Dim oXLApp As Object, oXLwb As Object
Private Sub CommandButton1_Click()
Set oXLApp = CreateObject("Excel.Application")
'~~> Show Excel
oXLApp.Visible = True
'~~> Add a new workbook
Set oXLwb = oXLApp.Workbooks.Add
'
'~~> Do some stuff
'
'~~> Save the file
oXLwb.SaveAs "C:\wordexc.xlsx", FileFormat:=51
oXLwb.Close SaveChanges:=False
End Sub
'~~> Close and Quit Excel (Flush Toilet)
Private Sub CommandButton2_Click()
oXLApp.Quit
Set oXLwb = Nothing
Set oXLApp = Nothing
End Sub
Why not do something like this? Basically, you define your excel object globally, and then you can call it's "Quit" method later.
Private objExcel As Excel.Application
Private Sub CommandButton1_Click()
Set objExcel = New Excel.Application
objExcel.Visible = True
End Sub
Private Sub CommandButton2_Click()
objExcel.Quit
End Sub
I have an excel macro saved in a blank workbook and multiple data workbooks.
I currently open the macro file and each data file individually, running the macro on each one with a keyboard shortcut.
Is there a way to run the macro on all the data workbooks without opening them, either with
a batch file,
VBA/VBScript,
powershell,
or something similar?
One way to do this is to add your macro's to the file PERSONAL.XLSB. This file will be loaded in the background every time you start Excel. Initially the PERSONAL.XLSB file will NOT be there.
To automatically create this file, just start recording a "dummy" macro (with the record button on the left-bottom of a spreadsheet) and select "Personal Macro Workbook" to store it in. After recording your macro, you can open the VBA editor with [Alt]+[F10] and you will see the PERSONAL.XLSB file with the "dummy" macro.
I use this file to store loads of general macro's which are always available. I have added these macro's to my own menu ribbon.
One disadvantage of this common macro file is that if you launch more than one instance of Excel, you will get an error message that the PERSONAL.XLSB file is already in use by Excel instance Nr. 1. This is no problem as long as you do not add new macro's at this moment.
Two potential solutions below,
vbscript which can be run directly as a vbs file
A vba solution to be run from within Excel (as per Tim Williams suggestion)
vbscript solution
Dim objFSO
Dim objFolder
Dim objFil
Dim objXl
Dim objWb
Dim objExcel
Set objExcel = CreateObject("Excel.Application")
Set objFSO = CreateObject("scripting.filesystemobject")
Set objFolder = objFSO.getfolder("c:\temp")
For Each objFil In objFolder.Files
If InStr(objFil.Type, "Excel") > 0 Then
Set Wb = objExcel.Workbooks.Open(objFil.Path)
wscript.echo Wb.name
Wb.Close False
End If
Next
vba solution
Sub OpenFilesVBA()
Dim Wb As Workbook
Dim strFolder As String
Dim strFil As String
strFolder = "c:\Temp"
strFil = Dir(strFolder & "\*.xls*")
Do While strFil <> vbNullString
Set Wb = Workbooks.Open(strFolder & "\" & strFil)
Wb.Close False
strFil = Dir
Loop
End Sub
I sort of stumbled across your post just now, maybe very late, but for all future searches.
It is possible to launch your Macro by creating a .vbs file.
To do this, open notepad and add the following:
objExcel = CreateObject("Excel.Application")
objExcel.Application.Run <insert macro workbook file path, module and macro name here>
objExcel.DisplayAlerts = False
objExcel.Application.Save
objExcel.Application.Quit
Set objExcel = Nothing
save the file as follows ("your filename".vbs)
By double clicking (opening) the saved .vbs file, it will launch your macro without you having to open your excel file at all.
Hope this helps.
You could keep the macro in your personal.xls, or a masterfile, and loop through the workbooks with vba, and activate them before running your macro. As far as I know, you still have to open them with vba though.
You could use something like this:
sub LoopFiles
Dim sFiles(1 to 10) as string 'You could also read this from a range in a masterfile
sFiles(1) = "Filename1.xls"
.
.
sFiles(10) = "Filename10.xls"
Dim wb as Workbook
Dim iCount as integer
iCount = ubound(sFiles)
Dim iCount2 as integer
For iCount2 = 1 to iCount
Workbooks(sFiles(iCount2)).open
Workbooks(sFiles(iCount2)).activate
Call YourMacro
Workbooks(sFiles(iCount2)).close
next iCount2
end sub
Other way,
Sub LoopAllWorkbooksOpened()
Dim wb As Workbook
For Each wb In Application.Workbooks
Call YourMacroWithWorkbookParam(wb)
Next wb
End Sub
Sub YourMacroWithWorkbookParam(wb As Workbook)
MsgBox wb.FullName
End Sub