0
votes

For example something like this to open the workbook in a new instance and then start the macro:

Shell(Excel.exe workbook.xlsm!macro1)

Or if the workbook was already open then:

Shell(xlObject macro1)

Most important thing is to use Shell so as to allow the code to continue whilst the macro runs separately. If not possible then perhaps I could Shell(file.bat) to a batch file that would do the same. What would the batch file look like?

Thank you.

1
Why would you just not use a Open event inside the workbook to be opened? What is the advantage of doing what you are doing?user6249873
Each 'Shell' or 'Open' creates a new Windows session ID. You should create only one session at a time and close it before creating another 'Shell' or 'Open'. Can a Excel session run inside of another Excel session? NO.user5952891

1 Answers

0
votes

You cannot execute VBA code inside a host application from the command line - that includes Shell. There are two alternatives, though (with Excel#1 being the current open file and Excel#2 being the one you want to run the code in):

  1. Put the code you want to run in the Excel #2 workbook's Workbook_Open event handler so it will execute every time you open that file - independet of how it was opened.
  2. Have Excel#1 create a new Excel.Application object in VBA and open Excel#2 in that application. You could now call the Run() method on the Excel#2's application object to execute code from Excel#2, but this will be done synchronous to the Excel#1's code. You can use the Excel#2 application's OnTime() method though for delayed macro execution, in which case Excel#2's application will call the code when the delay has passed and the code runs asynchronous in Excel#2's application.

Sample code for Option 2 could look like this:

Public Function RemoteRun(ByVal strFile As String) As Application
    Dim app As Application
    Dim wb As Workbook

    Set app = New Application
    Set wb = app.Workbooks.Open(strFile)
    app.OnTime Now + 1 / 24 / 60 / 60, "RemoteMacro"

    Set RemoteRun = app
End Function

Make sure to store the return value (the Excel#2's application object) somehwere so it won't automatically close (it still has to run RemoteMacro asynchronously). Setting its Visible property to True will work as well if you don't want Excel#1's code to manage the lifetime of Excel#2's application object.