Das Forum ist aktuell sporadisch nicht erreichbar - wir arbeiten dran. Laut Fehlermeldung Service Unavailable oder Internal Server Error, wir sind allerdings im Hosting ... x

VBA SAP Export
#1
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
Antworten Top
#2
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.
Antworten Top
#3
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
Antworten Top
#4
(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
Antworten Top
#5
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.
Antworten Top
#6
Hast du je den Makrorecorder benützt wenn du ein SAP exportdatei in Sharepoint öffnest ?
Wie sieht die Pathname aus in deine Sharepoint ?
Zum übersetzen von Excel Formeln:

http://dolf.trieschnigg.nl/excel/index.p...gids=en+de
Antworten Top
#7
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
Antworten Top
#8
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
Zum übersetzen von Excel Formeln:

http://dolf.trieschnigg.nl/excel/index.p...gids=en+de
Antworten Top
#9
(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.
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste