猿问
下载APP

VBA可以跨越Excel的实例吗?

VBA可以跨越Excel的实例吗?

在一个Excel实例中运行的Excel VBA宏是否可以访问另一个正在运行的Excel实例的工作簿?例如,我想创建一个在任何正在运行的Excel实例中打开的所有工作簿的列表。



慕盖茨9453107
浏览 45回答 3
3回答

慕圣8478803

科尼利厄斯的回答是部分正确的。他的代码获取当前实例,然后创建一个新实例。无论有多少实例可用,GetObject都只获得第一个实例。我相信的问题是如何从许多实例中获取特定实例。对于VBA项目,使用一个名为Command1的命令按钮创建两个模块,一个代码模块,另一个作为表单。您可能需要添加对Microsoft.Excel的引用。此代码在“立即”窗口中显示每个运行的Excel实例的每个工作簿的所有名称。'-------------&nbsp;Code&nbsp;Module&nbsp;--------------Option&nbsp;ExplicitDeclare&nbsp;Function&nbsp;FindWindowEx&nbsp;Lib&nbsp;"User32"&nbsp;Alias&nbsp;"FindWindowExA"&nbsp;(ByVal&nbsp;hWnd1&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;hWnd2&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;lpsz1&nbsp;As&nbsp;String,&nbsp;ByVal&nbsp;lpsz2&nbsp;As&nbsp;String)&nbsp;As&nbsp;LongDeclare&nbsp;Function&nbsp;GetClassName&nbsp;Lib&nbsp;"User32"&nbsp;Alias&nbsp;"GetClassNameA"&nbsp;(ByVal&nbsp;hWnd&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;lpClassName&nbsp;As&nbsp;String,&nbsp;ByVal&nbsp;nMaxCount&nbsp;As&nbsp;Long)&nbsp;As&nbsp;LongDeclare&nbsp;Function&nbsp;IIDFromString&nbsp;Lib&nbsp;"ole32"&nbsp;(ByVal&nbsp;lpsz&nbsp;As&nbsp;Long,&nbsp;ByRef&nbsp;lpiid&nbsp;As&nbsp;UUID)&nbsp;As&nbsp;LongDeclare&nbsp;Function&nbsp;AccessibleObjectFromWindow&nbsp;Lib&nbsp;"oleacc"&nbsp;(ByVal&nbsp;hWnd&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;dwId&nbsp;As&nbsp;Long,&nbsp;ByRef&nbsp;riid&nbsp;As&nbsp;UUID,&nbsp;ByRef&nbsp;ppvObject&nbsp;As&nbsp;Object)&nbsp;As&nbsp;LongType&nbsp;UUID&nbsp;'GUID &nbsp;&nbsp;Data1&nbsp;As&nbsp;Long &nbsp;&nbsp;Data2&nbsp;As&nbsp;Integer &nbsp;&nbsp;Data3&nbsp;As&nbsp;Integer &nbsp;&nbsp;Data4(7)&nbsp;As&nbsp;ByteEnd&nbsp;Type'-------------&nbsp;Form&nbsp;Module&nbsp;--------------Option&nbsp;ExplicitConst&nbsp;IID_IDispatch&nbsp;As&nbsp;String&nbsp;=&nbsp;"{00020400-0000-0000-C000-000000000046}"Const&nbsp;OBJID_NATIVEOM&nbsp;As&nbsp;Long&nbsp;=&nbsp;&HFFFFFFF0'Sub&nbsp;GetAllWorkbookWindowNames()Sub&nbsp;Command1_Click() &nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;Error&nbsp;GoTo&nbsp;MyErrorHandler&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;hWndMain&nbsp;As&nbsp;Long &nbsp;&nbsp;&nbsp;&nbsp;hWndMain&nbsp;=&nbsp;FindWindowEx(0&,&nbsp;0&,&nbsp;"XLMAIN",&nbsp;vbNullString) &nbsp;&nbsp;&nbsp;&nbsp;Do&nbsp;While&nbsp;hWndMain&nbsp;<>&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWbkWindows&nbsp;hWndMain &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hWndMain&nbsp;=&nbsp;FindWindowEx(0&,&nbsp;hWndMain,&nbsp;"XLMAIN",&nbsp;vbNullString) &nbsp;&nbsp;&nbsp;&nbsp;Loop &nbsp;&nbsp;&nbsp;&nbsp;Exit&nbsp;SubMyErrorHandler: &nbsp;&nbsp;&nbsp;&nbsp;MsgBox&nbsp;"GetAllWorkbookWindowNames"&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Err&nbsp;=&nbsp;"&nbsp;&&nbsp;Err.Number&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Description:&nbsp;"&nbsp;&&nbsp;Err.DescriptionEnd&nbsp;SubPrivate&nbsp;Sub&nbsp;GetWbkWindows(ByVal&nbsp;hWndMain&nbsp;As&nbsp;Long) &nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;Error&nbsp;GoTo&nbsp;MyErrorHandler&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;hWndDesk&nbsp;As&nbsp;Long &nbsp;&nbsp;&nbsp;&nbsp;hWndDesk&nbsp;=&nbsp;FindWindowEx(hWndMain,&nbsp;0&,&nbsp;"XLDESK",&nbsp;vbNullString) &nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;hWndDesk&nbsp;<>&nbsp;0&nbsp;Then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;hWnd&nbsp;As&nbsp;Long &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hWnd&nbsp;=&nbsp;FindWindowEx(hWndDesk,&nbsp;0,&nbsp;vbNullString,&nbsp;vbNullString) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;strText&nbsp;As&nbsp;String &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;lngRet&nbsp;As&nbsp;Long &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do&nbsp;While&nbsp;hWnd&nbsp;<>&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strText&nbsp;=&nbsp;String$(100,&nbsp;Chr$(0)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lngRet&nbsp;=&nbsp;GetClassName(hWnd,&nbsp;strText,&nbsp;100) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;Left$(strText,&nbsp;lngRet)&nbsp;=&nbsp;"EXCEL7"&nbsp;Then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetExcelObjectFromHwnd&nbsp;hWnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit&nbsp;Sub &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;If &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hWnd&nbsp;=&nbsp;FindWindowEx(hWndDesk,&nbsp;hWnd,&nbsp;vbNullString,&nbsp;vbNullString) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loop &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;Error&nbsp;Resume&nbsp;Next &nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;If &nbsp;&nbsp;&nbsp;&nbsp;Exit&nbsp;SubMyErrorHandler: &nbsp;&nbsp;&nbsp;&nbsp;MsgBox&nbsp;"GetWbkWindows"&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Err&nbsp;=&nbsp;"&nbsp;&&nbsp;Err.Number&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Description:&nbsp;"&nbsp;&&nbsp;Err.DescriptionEnd&nbsp;SubPublic&nbsp;Function&nbsp;GetExcelObjectFromHwnd(ByVal&nbsp;hWnd&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Boolean &nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;Error&nbsp;GoTo&nbsp;MyErrorHandler&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;fOk&nbsp;As&nbsp;Boolean &nbsp;&nbsp;&nbsp;&nbsp;fOk&nbsp;=&nbsp;False &nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;iid&nbsp;As&nbsp;UUID&nbsp;&nbsp;&nbsp;&nbsp;Call&nbsp;IIDFromString(StrPtr(IID_IDispatch),&nbsp;iid) &nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;obj&nbsp;As&nbsp;Object &nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;AccessibleObjectFromWindow(hWnd,&nbsp;OBJID_NATIVEOM,&nbsp;iid,&nbsp;obj)&nbsp;=&nbsp;0&nbsp;Then&nbsp;'S_OK &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;objApp&nbsp;As&nbsp;Excel.Application&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&nbsp;objApp&nbsp;=&nbsp;obj.Application &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print&nbsp;objApp.Workbooks(1).Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;myWorksheet&nbsp;As&nbsp;Worksheet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;For&nbsp;Each&nbsp;myWorksheet&nbsp;In&nbsp;objApp.Workbooks(1).Worksheets &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&&nbsp;myWorksheet.Name &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoEvents&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Next &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fOk&nbsp;=&nbsp;True &nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;If &nbsp;&nbsp;&nbsp;&nbsp;GetExcelObjectFromHwnd&nbsp;=&nbsp;fOk&nbsp;&nbsp;&nbsp;&nbsp;Exit&nbsp;FunctionMyErrorHandler: &nbsp;&nbsp;&nbsp;&nbsp;MsgBox&nbsp;"GetExcelObjectFromHwnd"&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Err&nbsp;=&nbsp;"&nbsp;&&nbsp;Err.Number&nbsp;&&nbsp;vbCrLf&nbsp;&&nbsp;"Description:&nbsp;"&nbsp;&&nbsp;Err.DescriptionEnd&nbsp;Function

慕莱坞7535251

我相信VBA比Charles想象的更强大;)如果只有一些棘手的方法指向GetObject和CreateObject中的特定实例,我们将解决您的问题!编辑:如果您是所有实例的创建者,那么列出工作簿应该没有问题。看看这段代码:Sub Excels()&nbsp; &nbsp; Dim currentExcel As Excel.Application&nbsp; &nbsp; Dim newExcel As Excel.Application&nbsp; &nbsp; Set currentExcel = GetObject(, "excel.application")&nbsp; &nbsp; Set newExcel = CreateObject("excel.application")&nbsp; &nbsp; newExcel.Visible = True&nbsp; &nbsp; newExcel.Workbooks.Add&nbsp; &nbsp; 'and so on...End Sub

萧十郎

我认为在VBA中,您可以访问另一个正在运行的实例中的应用程序对象。如果您知道在另一个实例中打开的工作簿的名称,那么您可以获得对该应用程序对象的引用。请参阅Allen Waytt的页面最后一部分,Dim xlApp As Excel.ApplicationSet xlApp = GetObject("c:\mypath\ExampleBook.xlsx").Application允许我获取指向已ExampleBook.xlsx打开实例的应用程序对象的指针。我相信“ExampleBook”需要成为完整的路径,至少在Excel 2010中。我正在尝试自己,所以我会尝试更新,因为我得到更多的细节。如果单独的实例打开相同的工作簿,可能会出现并发症,但只有一个可能具有写访问权限。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答