Re: Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- From: Michael Schwimmer <Schwimmer@xxxxxxxxxxx>
- Date: Tue, 3 Aug 2010 10:44:14 +0200
Hallo Andreas,
Am Mon, 02 Aug 2010 16:12:10 +0200 schrieb Andreas Killer:
Am 02.08.2010 13:44, schrieb Peter Schleif:
Mein Problem ist, dass ich nicht weiß, wie ich aus der zweiten,Hab ich auch schon (mehrfach) probiert, das geht nicht.
ferngesteuerten Instanz heraus, Zugriff auf die erste Instanz erhalte.
das würde ich so nicht sagen, zumindestens unter XL 2007 klappt das, der
Teufel steckt aber im Detail.
Prinzipiell musst du einen anderen Excel-Prozess starten (ich sage extra
nicht "andere Instanz"), das geht mit CreateObject. Unter Excel 2007 haben
nach meinen Tests aber alle Excel-Objekte das gleiche Instanzhandle, egal
ob mit CreateObject neu angelegt, oder durch den Start über Programme.
Anschließend übergibst du der anderen Applikation einen Verweis auf die
eigene Applikation, am besten als Parameterübergabe mit Application.Run und
einer vorbereiteten Prozedur in der Clientmappe.
Damit Application.Run sofort zurückkehrt, kannst du ja in der
Clientprozedur zum Entkoppeln mit OnTime arbeiten. In der Clientmappe
besitzt du nun einen Verweis auf das Serverobjekt, zusammen mit der
Run-Methode kannst du anschließend Prozeduren in der Servermappe starten.
Problematisch wird es erst, wenn die Clientmappe bereits offen sein kann
und du mit GetObject einen Verweis darauf enthalten möchtest. Übergibst du
an GetObject den Pfad der Mappe und das Objekt existiert, ist alles in
Ordnung. GetObject erstellt aber auch ein Objekt, wenn es noch nicht
existiert und zwar in der eigenen Application, also auch im gleichen
Prozess.
In der Server-Mappe:
Private Declare Function GetWindowThreadProcessId _
Lib "user32.dll" ( _
ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
Private Sub Server()
Dim objExtWB As Workbook
Dim objExtApp As Excel.Application
Dim objThisWB As Workbook
Dim objThisApp As Excel.Application
Dim HwndMe As Long
Dim HwndEx As Long
Dim HinstanceMe As Long
Dim HinstanceEx As Long
Dim HThreadMe As Long
Dim HThreadEx As Long
Dim HPidMe As Long
Dim HPidEx As Long
On Error Resume Next
Set objThisWB = ThisWorkbook
Set objThisApp = objThisWB.Application
' GetObjekt öffnet in der gleichen App die Mappe, wenn
' nicht die Mappe bereits mit einer anderen App geöffnet
' wurde.
Set objExtWB = GetObject( _
ThisWorkbook.Path & "\Client.xlsm")
Set objExtApp = objExtWB.Application
' Instanzhandle ist immer das gleiche, egal wie oft Excel (2007)
' geöffnet wird.
HinstanceMe = objThisApp.Hinstance
HinstanceEx = objExtApp.Hinstance
HwndMe = objThisApp.hwnd
HwndEx = objExtApp.hwnd
HThreadMe = GetWindowThreadProcessId(HwndMe, HPidMe)
HThreadEx = GetWindowThreadProcessId(HwndEx, HPidEx)
Debug.Print "Me: " & HinstanceMe & _
" " & HwndMe & " " & HThreadMe & " " & HPidMe
Debug.Print "Ext: " & HinstanceEx & _
" " & HwndEx & " " & HThreadEx & " " & HPidEx
If HwndMe = HwndEx Then
' Gleiche App, also auch gleicher Prozess
objExtWB.Close ' WB schließen
Set objExtApp = Nothing
' Scheinbar hat sich Excel als ein Objekt mit nur einer
' Instanz registriert.
' Dann wird nur eine Instanz des Objekts erstellt, ungeachtet
' dessen, wie oft CreateObject ausgeführt wird.
' Neuen Prozess der gleichen Instanz anlegen
Set objExtApp = CreateObject("Excel.Application")
objExtApp.Visible = True
Set objExtWB = objExtApp.Workbooks.Open( _
ThisWorkbook.Path & "\test\Client.xlsm")
Else
Set objExtApp = objExtWB.Application
End If
objExtApp.Run "XYZ_Client", ThisWorkbook.Application
End Sub
Public Sub ServerRun()
MsgBox "ServerRun"
End Sub
Im Client:
Private mobjServer As Excel.Application
Public Sub XYZ_Client(objApp As Excel.Application)
Set mobjServer = objApp
Application.OnTime Now + TimeSerial(0, 0, 2), "RunServerProc"
End Sub
Private Sub RunServerProc()
mobjServer.Run "ServerRun"
End Sub
Alles natürlich ohne Gewähr und um das Aufräumen muss man sich auch noch
selber kümmern. Die Prozess- und Threadhandles brauchst du ja auch nicht,
da kann man den Code noch etwas entschlacken.
Viele Grüße
Michael
.
- Follow-Ups:
- References:
- Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- From: Peter Schleif
- Re: Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- From: Andreas Killer
- Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- Prev by Date: Re: wie in gefilterter liste nächste zeile ansprechen? (vba)
- Next by Date: Formelhilfe
- Previous by thread: Re: Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- Next by thread: Re: Eine zweite Excel-Instanz starten und von dort auf die Original-Instanz zugreifen
- Index(es):
Relevant Pages
|