Registriert seit: 06.09.2016
Version(en): 2016
Hallo wertes Forum,
ich hatte bereits vor längerer Zeit mal das Thema, dass ich aus SAP Dateien exportiert bekomme, die aber nicht unbedingt sofort, sondern erst nach einigen Sekunden und "Do events" und dann (warum auch immer) in einer zweiten Excel-Instanz geöffnet werden. Ich hatte eine Lösung, dass ich die dazugehörige temporäre Datei abfrage und sie dann über Set wkbCOOISPIOrders = GetObject(strPfadData & "\" & strCOOISPIOrders) ansprechen kann.
Jetzt ziehen wir auf den Sharepoint um und das Ganze funktioniert nicht mehr, da es keine temporäre Datei mehr gibt. Wie funktioniert das auch auf dem Sharepoint?
Ich hatte dazu (ohne Sharepoint) mal mit @Warkings im MS-Office-Forum einen detaillierten Thread, aber der ist leichter nicht mehr verfügbar...
Vielen Dank für Eure Hilfe, Lutz
Registriert seit: 09.01.2022
Version(en): Microsoft 365
Mir ist nicht bekannt, dass aus SAP heraus irgend etwas direkt auf deinen PC exportieren kann. Aber du kannst dir automatisiert Berichte als PDF an Outlook senden lassen und die Anhänge mittels Makro in Outlook direkt iwo speichern lassen. Und immer wenn du dann deine Mappe öffnest, könntest bspw. mittels Power Query, automatisiert, dann sofort die neuesten Daten importieren und verarbeiten.
Registriert seit: 06.09.2016
Version(en): 2016
Hallo ws-53, wahrscheinlich ist das abhängig von den Berechtigungen, die das Unternehmen freigibt. In meiner alten Firma ging das auch nicht, aber aktuell funktioniert es manuell und per Makro (was auch freigeschaltet sein muss). Einfach, um die Kiste komplett aufzumachen, mein Wissen zu teilen und neue Ideen zu bekommen... Mein bisheriger funktionierender Stand war, dass ich: - per Makro einen Export aus SAP anstoße (hier wird übrigens der Pfad zum Sharepoint benötigt, NICHT die URL)
- diese Export-Datei automatisch geöffnet wird (ACHTUNG: die Datei wird manchmal in einer zweiten Instanz von Excel geöffnet!!!)
- ich per Do-Loop-Schleife darauf warte, dass die Datei geöffnet ist (Suche nach der temporären Datei)
- dann per GetObject auf die Datei zugreife und alles machen kann, was ich benötige
- Am Ende die Datei und falls nötig die zweite Instanz wieder schließe
- Code für das Warten und Zugreifen auf die Export-Datei:
Code: Do Application.Wait (DateAdd("s", 1, Now)) DoEvents Loop Until Dir(strPfadTemp & "\~$" & strBOMDATAProd & " (" & intVersuch & "_" & intEbene & ").xlsx", 63) <> ""
Set wkbBOMDATAProd = GetObject(strPfadTemp & "\" & strBOMDATAProd & " (" & intVersuch & "_" & intEbene & ").xlsx")
....
If wkbBOMDATAProd.Parent.Workbooks.Count > 1 Then wkbBOMDATAProd.Close savechanges:=False Else wkbBOMDATAProd.Parent.Quit End If
Jetzt stellen wir auf Sharepoint um und damit gibt es keine temporäre Datei mehr. Sämtliche Versuche und Modifikationen von Codeschnipseln aus dem Web scheitern an dem Punkt, wenn die Export-Datei in einer zweiten Excel-Instanz geöffnet wird. Ich bekomme keinen sicheren Zugriff auf genau diese Datei. Und wenn es denn mal irgendwie funktioniert, bleibt am Ende die Export-Datei in der zweiten Instanz geöffnet und wird nicht geschlossen (weil eben doch die Datei ein zweites Mal geöffnet wurde und nicht die bereits geöffnete Datei verwendet wird). Aktuell behelfe ich mir mit dem Workaround, die Export-Datei auf unserem Server abzulegen (hier funktioniert meine alte Variante), die Datei wieder zu schließen, in den Sharepoint zu verschieben und dann von dort wieder zu öffnen. Leider wird diese Möglichkeit in absehbarer Zeit entfallen, da der lokale Server komplett auf den Sharepoint verschoben wird. Auch das C:\-Laufwerk kommt nicht in Frage, da wir keine Berechtigung haben, hier zu schreiben. Bleibt also die Frage, wie bekomme ich sicher Zugriff auf eine Datei auf dem Sharepoint, auch wenn sie in einer zweiten (nicht von mir selbst geöffneten) Excel-Instanz geöffnet ist. Gruß, Lutz
Registriert seit: 12.07.2025
Version(en): 2021
(18.05.2026, 11:54)Lutz Fricke schrieb: Bleibt also die Frage, wie bekomme ich sicher Zugriff auf eine Datei auf dem Sharepoint, auch wenn sie in einer zweiten (nicht von mir selbst geöffneten) Excel-Instanz geöffnet ist. Hallo Lutz, auf die (SAP generierte temporäre) Datei im Sharepoint kriegst Du keinen Zugriff, aber die 2te Instanz läuft in einem Fenster und über das Fensterhandle kriegst Du Zugriff auf das Accessible Object und darüber dann die Instanz. Ermittle alle Fenster, prüfe welches Excelfenster sind, schließe das eigene aus (via Application.hWnd), dann sollte das hWnd der 2ten Instanz übrig bleiben. Den Rest machst Du nach dem Beispielcode unten. Andreas. Code: Option Explicit
Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type
#If Win64 Then Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" (ByVal hWnd As LongPtr, ByVal dwId As Long, riid As UUID, ppvObject As Object) As LongPtr Private Declare PtrSafe Function IIDFromString Lib "ole32" (ByVal lpsz As Long, ByRef lpiid As GUID) As Long #Else Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 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 AccessibleObjectFromWindow Lib "oleacc" (ByVal hWnd As Long, ByVal dwId As Long, ByRef riid As GUID, ByRef ppvObject As Object) As Long Private Declare Function IIDFromString Lib "ole32" (ByVal lpsz As Long, ByRef lpiid As GUID) As Long #End If
Private Sub Example_GetApplicationFromWindow() 'https://msdn.microsoft.com/de-de/library/windows/desktop/dd317978%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 #If Win64 Then Dim hWnd As LongPtr, hChild As LongPtr #Else Dim hWnd As Long, hChild As Long #End If Dim App As Object 'Excel hWnd = FindWindow("XLMAIN", vbNullString) hWnd = FindWindowEx(hWnd, 0, "XLDESK", vbNullString) hChild = FindWindowEx(hWnd, 0, "EXCEL7", vbNullString) If hChild <> 0 Then Set App = GetApplicationFromWindow(hChild) End If End Sub
Function GetApplicationFromWindow(ByVal hWnd As Long) As Object Const IID_IDispatch As String = "{00020400-0000-0000-C000-000000000046}" Const OBJID_NATIVEOM As Long = &HFFFFFFF0 Dim IID As GUID Dim AccObj As Object Call IIDFromString(StrPtr(IID_IDispatch), IID) If AccessibleObjectFromWindow(hWnd, OBJID_NATIVEOM, IID, AccObj) = 0 Then Set GetApplicationFromWindow = AccObj.Application End If End Function
Registriert seit: 09.01.2022
Version(en): Microsoft 365
Hi Lutz,
aus meiner früheren Erfahrung kann ich bestätigen, dass es da, zumindest anfangs, bis einer wusste, wie es mit einem Sharepoint geht, oft viel schwieriger war. Ich selbst habe nun seit über 5J keinen Zugang mehr zu einem SAP-System und kann somit auch nichts testen. Eventuell ist aber das von dir beschriebene Problem schon mal in einem SAP- oder Sharepoint-Forum geschildert worden. Und auch wenn Antworten der KI oft mehrfach hinterfragt werden müssen, bis das Ergebnis hilfreich ist, könnte es helfen, diese zu befragen.
Um evtl. mögliche Alternativen aufzuzeigen, könnte es hilfreich sein, wenn du mal erläuterst um was es dabei grob geht und wie zeitkritisch das Ganze ist.
Registriert seit: 29.09.2015
Version(en): 2030,5
Hast du je den Makrorecorder benützt wenn du ein SAP exportdatei in Sharepoint öffnest ? Wie sieht die Pathname aus in deine Sharepoint ?
Registriert seit: 06.09.2016
Version(en): 2016
Hallo zusammen, vielen Dank für die schnellen Antworten. @Andreas, nach gaaanz viel Suchen habe ich den Weg auch schon gesehen, aber bisher nicht zum Laufen bekommen. Bin halt doch kein Programmierer, sondern mache das Ganze nur nebenbei. Aber dann werde ich da wohl weiter dran arbeiten müssen. @ws-53, die KI hat mir da bisher nur bedingt weitergeholfen. Offenbar habe ich zu schlecht gefragt. Die Lösungen, die ich üblicherweise bekomme, steigen bei der zweiten Instanz aus. Zuletzt bin ich auf den Weg gestoßen, den Andreas geschildert hat. Aber da fehlt noch irgendetwas, dass es endgültig läuft. @snb, der Code ist Code: ChDir "C:\Users\Lutz.Fricke\OneDrive - MeineFirma\Sharepoints\Screen Harmonisation Project - General\Fricke\TP_UV-K\Daten" Workbooks.Open Filename:="https://MeineFirma.sharepoint.com/sites/ScreenHarmonisationProject/Shared%20Documents/General/Fricke/TP_UV-K/Daten/BOMDATAProd%20(2_3).xlsx"
Das Öffnen der Datei ist nicht das Problem. Ich kenne den Pfad als C:\... und auch als URL. Die Datei wird automatisch durch SAP/Excel direkt während des Exports geöffnet. Es gibt im Code keinen Befehl zum Öffnen der Datei. Dadurch auch das Problem, dass ich Zugriff auf eine Datei benötige, bei der ich weiß, wo sie gespeichert ist, aber nicht weiß, in welcher Instanz sie geöffnet ist. Gruß, Lutz
Registriert seit: 29.09.2015
Version(en): 2030,5
Das wird doch einfach erledigt mit Code: Sub M_snb() with getobject("https://MeineFirma.sharepoint.com/sites/ScreenHarmonisationProject/Shared Documents/General/Fricke/TP_UV-K/Daten/BOMDATAProd (2_3).xlsx") ' deine VBA-code End with End Sub
Registriert seit: 12.07.2025
Version(en): 2021
(18.05.2026, 13:51)Lutz Fricke schrieb: @Andreas, nach gaaanz viel Suchen habe ich den Weg auch schon gesehen, aber bisher nicht zum Laufen bekommen. Bin halt doch kein Programmierer, sondern mache das Ganze nur nebenbei. Aber dann werde ich da wohl weiter dran arbeiten müssen. Hallo Lutz, kriegst Du den Code oben und diesen Code hier alleine zusammen? Code: Option Explicit
Private Const GWL_STYLE = (-16) Private Const WS_VISIBLE = &H10000000 #If Win64 Then Private Declare PtrSafe Function EnumWindows Lib "user32" (ByVal lpEnumFunc As LongPtr, ByVal lParam As LongPtr) As Long Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long #Else Private Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long #End If
Dim C As Collection
#If Win64 Then Private Function IsWindowVisible(ByVal hWnd As LongPtr) As Boolean #Else Private Function IsWindowVisible(ByVal hWnd As Long) As Boolean #End If Const WS_VISIBLE = &H10000000 Dim lngStyle As Long lngStyle = GetWindowLong(hWnd, GWL_STYLE) IsWindowVisible = ((lngStyle And WS_VISIBLE) = WS_VISIBLE) End Function
Function EnumProc(ByVal hWnd As Long, ByVal lParam As Long) As Long Dim Retval As Long, WindowClass As String
'Fensterklasse ermitteln WindowClass = Space(256) Retval = GetClassName(hWnd, WindowClass, Len(WindowClass)) WindowClass = Left$(WindowClass, Retval)
Select Case WindowClass Case "XLMAIN" If IsWindowVisible(hWnd) Then If hWnd <> Application.hWnd Then C.Add hWnd End If End If End Select
EnumProc = 1 End Function
Sub Main() Set C = New Collection EnumWindows AddressOf EnumProc, 0
Select Case C.Count Case 0 MsgBox "Keine Excelinstanz gefunden" Case 1 MsgBox "Dies ist die andere Instanz: " & C.Item(1) Case Else MsgBox "Mehr als eine Excelinstanz gefunden" End Select End Sub
Andreas.
|