...I'm simply trying to open an excel file and run a specific macro. So far I have:...
Option Explicit
Public Sub Test1()
MsgBox "Hi there!"
End Sub
Option Explicit
Private Declare Function FindWindowEx Lib "User32" _
Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String _
) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpsz As Long, ByRef lpiid As GUID) As Long
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" (ByVal hWnd As Long, _
ByVal dwId As Long, _
ByRef riid As GUID, _
ByRef ppvObject As Object _
) As Long
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Const RETURN_OK As Long = &H0
Private Const IID_IDispatch As String = "{00020400-0000-0000-C000-000000000046}"
Private Const OBJID_NATIVEOM As Long = &HFFFFFFF0
Sub example2()
Dim objExcelApp As Object
Dim WB As Workbook
Dim hWndMAIN As Long
Dim dblID As Double
Dim sFullName As String
Dim sExeFullName As String
'Full path to .exe and FullName to file.
sExeFullName = "C:\Microsoft Office 2010\Office14\EXCEL.EXE"
sFullName = "C:\Users\stumpm\Desktop\vbax 04-03-2016\Book3.xls"
dblID = Shell("""" & sExeFullName & """ """ & sFullName & """", vbMaximizedFocus)
Do
DoEvents
Loop While dblID = 0
AppActivate dblID, False
'Return a handle to an available instance of Excel (which as we are running in,
'cannot fail.
hWndMAIN = FindWindowEx(0&, 0&, "XLMAIN", vbNullString)
Do While hWndMAIN > 0
If GetReferenceToXLApp(hWndMAIN, objExcelApp) Then
'See if the workbook exists in this instance (i.e. - see if we found the
'instance that Shell started
On Error Resume Next
Set WB = objExcelApp.Workbooks("Book3.xls")
On Error GoTo 0
'If we fail, there must be severak instances running
If Not WB Is Nothing Then
WB.Application.Run "'" & WB.Name & "'!Module1.Test1"
WB.Close False
Set WB = Nothing
objExcelApp.Quit
Set objExcelApp = Nothing
Exit Sub
End If
End If
'Find Next (notice that we pass our current handle for the second parameter
hWndMAIN = FindWindowEx(0&, hWndMAIN, "XLMAIN", vbNullString)
Loop
End Sub
'FROM: http://www.ozgrid.com/forum/showthread.php?t=182853
'// Returns a reference to a specific instance of Excel.
'// The Instance is defined by the Handle (hWndXL) passed
'// by the calling procedure
Function GetReferenceToXLApp(hWndXL As Long, oXLApp As Object) As Boolean
Dim hWinDesk As Long
Dim hWin7 As Long
Dim obj As Object
Dim iID As GUID
'// Rather than explaining, go read
'// http://msdn.microsoft.com/en-us/library/windows/desktop/ms687262(v=vs.85).aspx
Call IIDFromString(StrPtr(IID_IDispatch), iID)
'// We have the XL App (Class name XLMAIN)
'// This window has a child called 'XLDESK' (which I presume to mean 'XL desktop')
'// XLDesk is the container for all XL child windows....
hWinDesk = FindWindowEx(hWndXL, 0&, "XLDESK", vbNullString)
'// EXCEL7 is the class name for a Workbook window (and probably others, as well)
'// This is used to check there is actually a workbook open in this instance.
hWin7 = FindWindowEx(hWinDesk, 0&, "EXCEL7", vbNullString)
'// Deep API... read up on it if interested.
'// http://msdn.microsoft.com/en-us/library/windows/desktop/dd317978(v=vs.85).aspx
If AccessibleObjectFromWindow(hWin7, OBJID_NATIVEOM, iID, obj) = RETURN_OK Then
Set oXLApp = obj.Application
GetReferenceToXLApp = True
End If
End Function
Hi Mark,
I am running this from Excel. I can not do it in any of the simple ways because I need the code to continue to run and launch other instances with other files and other macros without waiting. For example below is one way that works except that it must wait until the first macro is finished before moving on:
AppPathAndFileName = "C:\Program Files (x86)\Microsoft Office\Office12\Excel.exe " & "C:\MyFile1.xlsm"
Shell (AppPathAndFileName), 3
Set Otherinstance = GetObject("C:\MyFile1.xlsm")
Otherinstance.Application.Run "MyMacro1"
AppPathAndFileName = "C:\Program Files (x86)\Microsoft Office\Office12\Excel.exe " & "C:\MyFile2.xlsm"
Shell (AppPathAndFileName), 3
Set Otherinstance = GetObject("C:\MyFile2.xlsm")
Otherinstance.Application.Run "MyMacro2"
I'm also aware that the workbook_open event would work but that is also not an option for me.
Thanks for helping out.