AW: Was ist der Projekt-Explorer ? (owT)
26.09.2019 17:49:08
Nepumuk
Hallo Andreas,
SAP öffnet die Datei in einer eigenen Application. Schau mal in den Taskmanager da findest du zwei Excel-Prozesse. Der Zugriff auf diese Application ist möglich, aber nicht ohne.
Option Explicit
Private Declare Function GetClassNameA Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function EnumWindows Lib "user32.dll" ( _
ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Boolean
Private Declare Function EnumChildWindows Lib "user32.dll" ( _
ByVal hWndParent As Long, _
ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
Private Declare Sub IIDFromString Lib "ole32.dll" ( _
ByVal lpsz As String, _
ByRef lpiid As GUID)
Private Declare Sub AccessibleObjectFromWindow Lib "oleacc.dll" ( _
ByVal hwnd As Long, _
ByVal dwId As Long, _
ByRef riid As GUID, _
ByRef ppvObject As Any)
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Const GC_CLASSNAMEEXCEL = "XLMAIN"
Private Const GC_CLASSNAMEEXCEL7 = "EXCEL7"
Private Const IID_EXCELWINDOW = "{00020893-0000-0000-C000-000000000046}"
Private Const OBJID_NATIVEOM = &HFFFFFFF0
Private lalngChildHwnd() As Long, lialngChildCount As Long
Private lalngMainHwnd() As Long, lialngMainCount As Long
Private Function GetApplications() As Application()
Dim ialngIndex As Long, ialngCount As Long
Dim udtGuid As GUID
Dim objWindow As Window
Dim aobjTempApplications() As Application
'Alle lokalen Variablen zuruecksetzen
Erase lalngChildHwnd
lialngChildCount = 0
Erase lalngMainHwnd
lialngMainCount = 0
'Konvertiere die IID des Excel-Window-Objektes in die GUID-Struktur
Call IIDFromString(StrConv(IID_EXCELWINDOW, vbUnicode), udtGuid)
'Callback Aufruf um alle Fenster zu klassifizieren
Call EnumWindows(AddressOf EnumWindowsProc, ByVal 0&)
'Schleife ueber alle gefundenen Parent-Excelfenster
For ialngIndex = LBound(lalngMainHwnd) To UBound(lalngMainHwnd)
'Callback Aufruf um alle Child-Fenster der
'entsprechenden Parent-Fenster zu durchlaufen
Call EnumChildWindows(lalngMainHwnd(ialngIndex), _
AddressOf EnumChildWindowsProc, ByVal 0&)
Next
'Schleife ueber die jeweils ersten gefundenen Window-Fenster
For ialngIndex = LBound(lalngChildHwnd) To UBound(lalngChildHwnd)
'Hole ueber die Zugriffsnummer das entsprechende Window-Objekt
Call AccessibleObjectFromWindow(lalngChildHwnd(ialngIndex), _
OBJID_NATIVEOM, udtGuid, objWindow)
'Wenn das Objekt gefunden wurde setze einen Verweis
'auf dessen Application-Objekt in das Array
If Not objWindow Is Nothing Then
Redim Preserve aobjTempApplications(ialngCount)
Set aobjTempApplications(ialngCount) = objWindow.Application
ialngCount = ialngCount + 1
End If
Next
'Array an die Funktionsvariable uebergeben
GetApplications = aobjTempApplications
End Function
Private Function EnumWindowsProc( _
ByVal pvlngHwnd As Long, _
ByVal pvlnglParam As Long) As Long
'Callback Funktion um alle Fenster zu durchlaufen
'Wenn ein Excelfenster gefunden wurde schreibe dessen Handle in das Array
If ClassName(pvlngHwnd) = GC_CLASSNAMEEXCEL Then
Redim Preserve lalngMainHwnd(lialngMainCount)
lalngMainHwnd(lialngMainCount) = pvlngHwnd
lialngMainCount = lialngMainCount + 1
End If
EnumWindowsProc = 1
End Function
Private Function EnumChildWindowsProc( _
ByVal pvlngHwnd As Long, _
ByVal pvlnglParam As Long) As Long
'Callback Funktion um alle Child-Fenster zu durchlaufen
'Wenn ein Window-Fenster im Excel-Fenster gefunden wurde schreibe
'dessen Handle in das Array und verlasse die Callback-Prozedur
If ClassName(pvlngHwnd) = GC_CLASSNAMEEXCEL7 Then
Redim Preserve lalngChildHwnd(lialngChildCount)
lalngChildHwnd(lialngChildCount) = pvlngHwnd
lialngChildCount = lialngChildCount + 1
EnumChildWindowsProc = 0
Else
EnumChildWindowsProc = 1
End If
End Function
Private Function ClassName( _
ByVal pvlngHwnd As Long) As String
'Funktion zum Ermitteln des Klassennames
Dim strClassName As String * 256
Dim lngReturn As Long
'Lese den Klassenname des Handles
lngReturn = GetClassNameA(pvlngHwnd, strClassName, Len(strClassName))
'Klassenname an die Funktionsvariable uebergeben
ClassName = Left$(strClassName, lngReturn)
End Function
Public Sub Test()
'Testprozedur die in allen Instanzen alle Tabellen in allen Mappen durchsucht
Dim aobjApplications() As Application
Dim ialngIndex As Long
Dim objWorkbook As Workbook, objWorksheet As Worksheet
Dim objDictionary As Object
Dim avntApplications As Variant, vntApplicationItem As Variant
Dim strFirstAddress As String
'Hole die Application-Objekte alle geoeffneten Excelinstanzen
aobjApplications = GetApplications
'Neue Instanzt eines Dictionary-Objektes erstellen
Set objDictionary = CreateObject("Scripting.Dictionary")
'Schleife ueber alle Application-Objekte
For ialngIndex = LBound(aobjApplications) To UBound(aobjApplications)
'Mehrfach gefundene Instanzen herausfiltern
If Not objDictionary.Exists(aobjApplications(ialngIndex).hwnd) Then _
Call objDictionary.Add(aobjApplications(ialngIndex).hwnd, aobjApplications(ialngIndex))
'Objet zuruecksetzen
Set aobjApplications(ialngIndex) = Nothing
Next
'Instanzen aus dem Dictionary holen
avntApplications = objDictionary.Items
'Objet zuruecksetzen
Set objDictionary = Nothing
'Schleife ueber alle Application-Objekte
For Each vntApplicationItem In avntApplications
For Each objWorkbook In vntApplicationItem.Workbooks
MsgBox objWorkbook.Name
For Each objWorksheet In objWorkbook.Worksheets
MsgBox objWorksheet.Name
Next
Next
Next
'Array zuruecksetzen
Erase avntApplications
End Sub
Gruß
Nepumuk