Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1780to1784
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Speichern per VBA klappt nur zuällig

Speichern per VBA klappt nur zuällig
11.09.2020 22:15:06
nedo.sr0x
Hallo zusammen,
ich möchte Daten aus SAP in Excel exportieren und die entstandene Excel Datei per Macro an einem Speicherort ablegen.
Das Erzeugen der Datei funktioniert einwandfrei. SAP öffnet eine Exceldatei. Diese muss noch gespeichert werden. Allerdings funktioniert das speichern scheinbar nur zufällig. Manchmal wird die Datei einfach nicht geschrieben bzw. überschrieben. Wenn ich das Makro mehrfach durchlaufen lasse klappt es dann ggfs. irgendwann.
Ich habe keine Ahnung woran das liegt, da es manchmal auch auf Anhieb klappt.
Ich nutze folgenden Code:

WB.SaveAs dateipfad & dateiname

Ich habe auch schon versucht die Datei erst mit kill zu löschen und dann neu zu schreiben. Ich habe auch eine Schleife gebaut und das DateLastModified mit now() verglichen und die Schleife mehrfach wiederholt bis das DateLastModified Hilft alles nicht.
Jemand einen Tipp wie ich da weiter komme.
Danke im Voraus
Gruß

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Speichern per VBA klappt nur zuällig
12.09.2020 00:20:02
Marc
Hallo nedo.sr0x,
mit dem kleinen Makrofitzel ist es schwierig zu verstehen, wo dein Problem liegt...
Entweder du stellst die Datei hoch oder schreibst die ganze Sub rein.
Gruß Marc
AW: Speichern per VBA klappt nur zuällig
12.09.2020 07:39:17
nedo.sr0x
Hallo,
ich hatte nicht die ganze Sub eingefügt, weil da eigentlich nichts Besonderes dran ist, was mit dem speichern zu tun hat. In meinem PRogramm werden mehrere Exporte aus SAP erzeugt. Jedesmal wird die Datei mit folgender Sub gespeichert. Der COde sucht die Datei die SAP erzeugt und geöffnet hat. Diese hat eine (1) im Namen, daher der Code um das richtige Workbook zu finden. Dann wird gespeichert und geschlossen:
Sub save()
Dim objXL
Dim WB
Set objXL = GetObject(, "Excel.Application")
objXL.DisplayAlerts = False
For Each WB In objXL.Workbooks
If InStr(WB.Name, "(1)") > 0 Then 'da Name typischerweise  _
Tabelle von Basis (1)
WB.ActiveSheet.Name = "Tabelle1"
WB.SaveAs dateipfad & dateiname
Exit For
End If
Next
End Sub
Mein Dateipfad liegt übrigens auf einem Netzlaufwerk oder auf einem SharePoint. Ich vermute irgendwie hat das Garnichts mit dem Code direkt zu tun, sondern mit irgendwelchen anderen Randbedingungen.
Wenn ich .DisplayAlerts = True setze, kommt vor dem Speichern ja immer die Abfrage ob die Vorhandene Datei überschrieben werden soll. Dann muss man ja klicken. So funktioniert es zu 100 %.
Nur mit .DisplayAlerts = False (ohne Nachfrage zum Überschreiben) tritt das Problem auf.
Grüße
Anzeige
AW: Speichern per VBA klappt nur zuällig
12.09.2020 09:48:53
Nepumuk
Hallo,
wenn die der Pfad der Datei bekannt ist, dann greife so darauf zu:
Public Sub saveSAP()
    
    Dim objXL As Excel.Application
    Dim WB As Workbook
    
    Set objXL = GetObject(PathName:=dateipfad & dateiname)
    
    objXL.DisplayAlerts = False
    
    For Each WB In objXL.Workbooks
        
        If InStr(WB.Name, "(1)") > 0 Then 'da Name typischerweise Tabelle von Basis (1)
            WB.ActiveSheet.Name = "Tabelle1"
            WB.SaveAs dateipfad & dateiname
            Exit For
        End If
        
    Next
End Sub

Wobei ich jetzt nicht weis, ob der Pfad und der Dateiname stimmen.
Gruß
Nepumuk
Anzeige
AW: Speichern per VBA klappt nur zuällig
12.09.2020 09:55:00
Nedo.sr0x
Mmmmh. Der Dateipfad und Name ist in dem Moment ja noch unbekannt weil SAP die Datei irgendwo im Temp anlegt. Man muss dann die Datei speichern, sonst ist Sie wieder weg.
Gruß
AW: Speichern per VBA klappt nur zuällig
12.09.2020 10:09:01
Nepumuk
Hallo,
tja schade.
Gruß
Nepumuk
AW: Speichern per VBA klappt nur zuällig
12.09.2020 11:02:36
Nepumuk
Hallo,
teste mal:
Option Explicit

Private Declare PtrSafe Function GetClassNameA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal lpClassName As String, _
    ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Function EnumWindows Lib "user32.dll" ( _
    ByVal lpEnumFunc As LongPtr, _
    ByVal lParam As LongPtr) As Long
Private Declare PtrSafe Function EnumChildWindows Lib "user32.dll" ( _
    ByVal hWndParent As LongPtr, _
    ByVal lpEnumFunc As LongPtr, _
    ByVal lParam As LongPtr) As Long
Private Declare PtrSafe Sub IIDFromString Lib "ole32.dll" ( _
    ByVal lpsz As String, _
    ByRef lpiid As GUID)
Private Declare PtrSafe Sub AccessibleObjectFromWindow Lib "oleacc.dll" ( _
    ByVal hwnd As LongPtr, _
    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 Const FOLDER_PATH As String = "" 'Anpassen !!!
Private Const FILE_NAME As String = "" 'Anpassen !!!

Private lalngptrChildHwnd() As LongPtr, lialngChildCount As Long
Private lalngptrMainHwnd() As LongPtr, 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
    Erase lalngptrChildHwnd
    lialngChildCount = 0
    Erase lalngptrMainHwnd
    lialngMainCount = 0
    Call IIDFromString(StrConv(IID_EXCELWINDOW, vbUnicode), udtGuid)
    Call EnumWindows(AddressOf EnumWindowsProc, ByVal 0)
    For ialngIndex = LBound(lalngptrMainHwnd) To UBound(lalngptrMainHwnd)
        Call EnumChildWindows(lalngptrMainHwnd(ialngIndex), _
            AddressOf EnumChildWindowsProc, ByVal 0&)
    Next
    For ialngIndex = LBound(lalngptrChildHwnd) To UBound(lalngptrChildHwnd)
        Call AccessibleObjectFromWindow(lalngptrChildHwnd(ialngIndex), _
            OBJID_NATIVEOM, udtGuid, objWindow)
        If Not objWindow Is Nothing Then
            Redim Preserve aobjTempApplications(ialngCount)
            Set aobjTempApplications(ialngCount) = objWindow.Application
            ialngCount = ialngCount + 1
        End If
    Next
    GetApplications = aobjTempApplications
End Function

Private Function EnumWindowsProc( _
        ByVal pvlngptrHwnd As LongPtr, _
        ByVal pvlnglParam As LongPtr) As LongPtr

    If ClassName(pvlngptrHwnd) = GC_CLASSNAMEEXCEL Then
        Redim Preserve lalngptrMainHwnd(lialngMainCount)
        lalngptrMainHwnd(lialngMainCount) = pvlngptrHwnd
        lialngMainCount = lialngMainCount + 1
    End If
    EnumWindowsProc = 1
End Function

Private Function EnumChildWindowsProc( _
        ByVal pvlngptrHwnd As LongPtr, _
        ByVal pvlngptrlParam As LongPtr) As LongPtr

    If ClassName(pvlngptrHwnd) = GC_CLASSNAMEEXCEL7 Then
        Redim Preserve lalngptrChildHwnd(lialngChildCount)
        lalngptrChildHwnd(lialngChildCount) = pvlngptrHwnd
        lialngChildCount = lialngChildCount + 1
        EnumChildWindowsProc = 0
    Else
        EnumChildWindowsProc = 1
    End If
End Function

Private Function ClassName( _
        ByVal pvlngptrHwnd As LongPtr) As String

    Dim strClassName As String * 256
    Dim lngReturn As Long
    lngReturn = GetClassNameA(pvlngptrHwnd, strClassName, Len(strClassName))
    ClassName = Left$(strClassName, lngReturn)
End Function

Public Sub Save_SAP_Export()
    Dim aobjApplications() As Application
    Dim ialngIndex As Long
    Dim objWorkbook As Workbook, objWorksheet As Worksheet
    Dim objCell As Range
    Dim objDictionary As Object
    Dim avntApplications As Variant, vntApplicationItem As Variant
    Dim strFirstAddress As String
    Dim blnFound As Boolean
    aobjApplications = GetApplications
    Set objDictionary = CreateObject("Scripting.Dictionary")
    For ialngIndex = LBound(aobjApplications) To UBound(aobjApplications)
        If Not objDictionary.Exists(aobjApplications(ialngIndex).hwnd) Then _
            Call objDictionary.Add(aobjApplications(ialngIndex).hwnd, aobjApplications(ialngIndex))
        Set aobjApplications(ialngIndex) = Nothing
    Next
    avntApplications = objDictionary.Items
    Set objDictionary = Nothing
    For Each vntApplicationItem In avntApplications
        For Each objWorkbook In vntApplicationItem.Workbooks
            If InStr(objWorkbook.Name, "(1)") > 0 Then
                vntApplicationItem.DisplayAlerts = False
                objWorkbook.Worksheets(1).Name = "Tabelle1"
                Call objWorkbook.SaveAs(Filename:=FOLDER_PATH & FILE_NAME)
                vntApplicationItem.DisplayAlerts = True
                Call MsgBox("Speichern erfolgreich.", vbInformation, "Information")
                blnFound = True
                Exit For
            End If
        Next
        If blnFound Then Exit For
    Next
    Erase avntApplications
End Sub

Vergiss nicht den Pfad und den Dateinamen anzupassen !!!
Gruß
Nepumuk
Anzeige
AW: Speichern per VBA klappt nur zuällig
12.09.2020 15:10:11
Nedo.sr0x
Danke für die Mühe. Werde ich testen und mich dann melden. Aber heute komme ich nicht dazu....
Grüße
AW: Speichern per VBA klappt nur zuällig
12.09.2020 18:28:50
Hajo_Zi
offen bedeutet es soll noch eine Antwort kommen.
Warum ist dein Beitrag Offen.
Du willst doch was machen. Soll jemand vorbei kommen?
Das ist nur meine Meinung zu dem Thema.

AW: Speichern per VBA klappt nur zuällig
13.09.2020 21:22:13
Nedo.sr0x
Hallo,
leider auch mit diesem Code keine Besserung. Ca. die Hälfte der Dateien wurde beim ersten Durchlauf nicht aktualisiert.
Grüße
AW: Speichern per VBA klappt nur zuällig
13.09.2020 21:22:35
Nedo.sr0x
Hallo,
leider auch mit diesem Code keine Besserung. Ca. die Hälfte der Dateien wurde beim ersten Durchlauf nicht aktualisiert.
Grüße
Anzeige
AW: Speichern per VBA klappt nur zuällig
14.09.2020 00:56:24
Peter
Hallo nedo,
der übliche Weg, eine von SAP erzeugte Excel-Datei zu speichern, ist der manuelle mit "Datei", "Speichern unter". Eine automatische Speicherung per Makro durchzuführen, ist aufwendig. Vor allen Dingen muss zuvor geklärt werden, in welcher Weise SAP die Excel-Dateien erzeugt (im Batch oder online, bzw. eine einzige Excel-Datei oder mehrere, die dann im Haupspeicher geladen ist/sind). Mitunter werden auch mehrere Auswertungen von SAP hintereinander in ein Excel-Arbeitsblatt geschrieben. Danach kommt die Frage, wie die Auswertung/die Auswertungen gespeichert werden sollen und nach welchen Kriterien (Datei-Benamung). Das Ganze kann man nur dann beurteilen, wenn man ein genaues Bild von der erzeugten Excel-Auswertung hat. Hier ist also unbedingt eine Beispiel-Arbeitsmappe hochzuladen.
Die Auswertungen sind mit Sicherheit in den Excel-Auswertungen an irgendeiner Stelle benannt (z. B. Konto-Nr., KSt.-Nr., usw.). Aus diesen Benennungen müsste dann der Dateiname konstruiert werden und mit Hilfe einer Formel an einer genau definierten Stelle in das Tabellenblatt geschrieben werden. Den Speichermakro würde ich in einer speziellen persönlichen Makro-Arbeitsmappe speichern und von dort mit einem Short-Cut (Kombination aus "STRG" und Buchstabentaste) aufrufen.
Ich habe übrigens in meiner früheren beruflichen Tätigkeit oft mit SAP in der Kombination mit Excel gearbeitet.
Mit freundlichem Gruß
Peter Kloßek
Anzeige
AW: Speichern per VBA klappt nur zuällig
14.09.2020 06:14:59
nedo.sr0x
Hallo Herr Kloßek,
danke für die Antwort.
Das funktioniert in meinem Makro so: Ich rufe eine Transaktion auf und gebe die Selektionsparameter ein. Danach wird die Suche ausgeführt. Das Ergebnis (Tabelle in SAP) wird per Befehl "Tabellenkalkulation" an Excel geschickt. Dabei öffnet SAP eine Excel Datei mit dem Namen XY. Dieses Excelfenster wird dann angesprochen und der SaveAs ausgeführt.
Dabei schließt sich die Excel Datei wieder. Danach rufe ich die Nächste Transaktion in SAP auf und wiederhole den Export.
Es sind verschiedene Transaktionen die ich jeden Morgen abrufen will. Der Dateiname des SaveAs ist immer entsprechend der aktuell exportierten Transaktion gewählt - also bei jedem Durchlauf unterschiedlich, aber jeden Tag gleich.
Ich glaube ehrlich gesagt, dass das Problem eher Zufällig auftritt und irgendwie mit der aktuellen Rechner bzw. Netzwerk Performance zu tun hat. Denn Grundsätzlich funktioniert der der Export ja.
Wenn ich DisplayALerts aktiviere und vor dem Überschreiben der Datei die Nachfrage kommt funktioniert es perfekt. Nur bei DisplayAlerts False wird das Schreiben der Datei scheinbar manchmal "verschluckt".
Ich kann das Problem aber nicht näher eingrenzen.
Grüße
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige