I have one excel file that opens other excel files using VBA. These other excel files all run code on open — currently when the main file opens a file, it waits for the on open code to run in the file it just opened, and then opens the next file. I would like it to just open the files then move on to opening the next file without waiting for the on open code to finish — (I plan on limiting the number of files it has open at a time using process IDs) — any tips?
-
does the sub that runs when the workbook is opened start like "Private Sub Workbook_Open()" or "Sub Auto_Open()"? Also, do you want a macro to run automatically when you open it programmatically?W-hit– W-hit2019-03-27 21:19:50 +00:00Commented Mar 27, 2019 at 21:19
-
I would recommend to write a VB script instead of using VBA...user8608712– user86087122019-03-27 22:40:21 +00:00Commented Mar 27, 2019 at 22:40
-
see stackoverflow.com/questions/51888282/…simple-solution– simple-solution2019-03-27 23:29:59 +00:00Commented Mar 27, 2019 at 23:29
-
@w-hit private sub workbook_open() and I want the macro to run programmatically. —Ned Charles– Ned Charles2019-03-27 23:47:11 +00:00Commented Mar 27, 2019 at 23:47
-
@irene G yes it would be great if I could use VB but unfortunately I need a SAP VBA specific APINed Charles– Ned Charles2019-03-27 23:47:18 +00:00Commented Mar 27, 2019 at 23:47
1 Answer
First you disable the run of macros, open the workbooks as you need them and then you reenable the run of macros. (as proposed here: Getting a .xlsm file to not execute code when being opened with VBA)
Private Sub OpenWorkBookMacroDisabled(wbPath As String)
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Workbooks.Open (wbPath)
Application.AutomationSecurity = msoAutomationSecurityByUI
'or
'Application.AutomationSecurity = msoAutomationSecurityLow
End Sub
But actually this does not solve your problem. To run the macros it would be necessary to reopen the workbooks which then would again autostart the individual macros.
Workaround 1
A possible solution is mentioned here: https://www.ozgrid.com/forum/forum/help-forums/excel-general/47477-enabling-macros-without-re-opening-worksheet:
CREATE AN ENABLE/DISABLE VALIDATION CELL
The only work around if it was a problem could be something like a validation cell on your home / front page that said " enabled" / "disabled".
Then when opening the workbook always enable the macro's, then on workbook open auto set this to disabled.
then you would have all macros look at this ref and if disabled not run, and you would need to dial up enabled to allow any macro to run.
May not be what you want but a thought.
Workaround 2
Another workaround could be:
(1) Open the workbook(s) with the code mentioned above.
(2) Change Sub Workbook_Open to Sub Workbook_Open_OLD programmatically
(3) Save the workbook(s)
(4) Change AutomationSecurity to the desired level
(5) reopen your workbook(s)
Quite a lot of work!
For details see: http://www.cpearson.com/excel/vbe.aspx
Workaround 3
A variation to the enable/disable validation cell is the use of a central property
e.g. Application.Username
**This Macro calls the 'other excel files':**
Sub Main0()
'TEST 1:
'Open workbook and DON'T run macros
'Call "YourCode" manually
Application.UserName = "NoMacroRun"
Debug.Print "Test 1:"
Debug.Print Application.UserName
Workbooks.Open ThisWorkbook.Path & "\macro_010.xlsb"
Debug.Print "Open finished"
Debug.Print "Call YourCode"
Run "macro_010.xlsb!YourCode"
Workbooks("macro_010.xlsb").Close SaveChanges:=False
Debug.Print "Test 1: FINISHED successfully"
Debug.Print ""
'TEST 2:
'Open workbook and run macros
Application.UserName = "SomeThingElse"
Debug.Print "Test 2:"
Debug.Print Application.UserName
Workbooks.Open ThisWorkbook.Path & "\macro_010.xlsb"
Debug.Print "Test 2: FINISHED successfully"
Debug.Print ""
Workbooks("macro_010.xlsb").Close SaveChanges:=False
Debug.Print ""
End Sub
The other files look like:
In 'the other files' you seperate "YourCode" from "Workbook_Open" and make it callable from the outside:
'doubleclick "ThisWorkbook" in the IDE and insert this code there
Public Sub Workbook_Open()
If Application.UserName <> "NoMacroRun" Then
Debug.Print "---> " & ThisWorkbook.Name & ": Workbook_Open is part of ThisWorkbook in the IDE"
'your code
Call YourCode
End If
End Sub
This code you insert into a module:
'doubleclick "module" in the IDE and insert this code there
'OR click in the menu --> Insert --> Module
Sub YourCode()
Debug.Print "---> " & ThisWorkbook.Name & ": ""Sub YourCode"" is part of a module in the IDE!"
End Sub
And finally, the Immediate Window proves that it works as intended:
Test 1:
NoMacroRun
Open finished
Call YourCode
---> macro_010.xlsb: "Sub YourCode" is part of a module in the IDE!
Test 1: finished successfully
Test 2:
SomeThingElse
---> macro_010.xlsb: Workbook_Open is part of ThisWorkbook in the IDE
---> macro_010.xlsb: "Sub YourCode" is part of a module in the IDE!
Test 2: finished successfully
Q.E.D. ;-)
