Microsoft Excel

Herbers Excel/VBA-Archiv

Informationen und Beispiele zum Thema MsgBox
BildScreenshot zu MsgBox MsgBox-Seite mit Beispielarbeitsmappe aufrufen

Speichern per VBA klappt nur zuällig

Betrifft: Speichern per VBA klappt nur zuällig von: nedo.sr0x
Geschrieben am: 11.09.2020 22:15:06

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 < 1 Minute zu now() war.


Hilft alles nicht.


Jemand einen Tipp wie ich da weiter komme.


Danke im Voraus


Gruß


Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Marc
Geschrieben am: 12.09.2020 00:20:02

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

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: nedo.sr0x
Geschrieben am: 12.09.2020 07:39:17

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

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nepumuk
Geschrieben am: 12.09.2020 09:48:53

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

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nedo.sr0x
Geschrieben am: 12.09.2020 09:55:00

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ß

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nepumuk
Geschrieben am: 12.09.2020 10:09:01

Hallo,

tja schade.

Gruß
Nepumuk

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nepumuk
Geschrieben am: 12.09.2020 11:02:36

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

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nedo.sr0x
Geschrieben am: 12.09.2020 15:10:11

Danke für die Mühe. Werde ich testen und mich dann melden. Aber heute komme ich nicht dazu....

Grüße

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Hajo_Zi
Geschrieben am: 12.09.2020 18:28:50

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.

GrußformelHomepage

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nedo.sr0x
Geschrieben am: 13.09.2020 21:22:13

Hallo,

leider auch mit diesem Code keine Besserung. Ca. die Hälfte der Dateien wurde beim ersten Durchlauf nicht aktualisiert.

Grüße

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Nedo.sr0x
Geschrieben am: 13.09.2020 21:22:35

Hallo,

leider auch mit diesem Code keine Besserung. Ca. die Hälfte der Dateien wurde beim ersten Durchlauf nicht aktualisiert.

Grüße

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: Peter Kloßek
Geschrieben am: 14.09.2020 00:56:24

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

Betrifft: AW: Speichern per VBA klappt nur zuällig
von: nedo.sr0x
Geschrieben am: 14.09.2020 06:14:59

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

Beiträge aus dem Excel-Forum zum Thema "Speichern per VBA klappt nur zuällig"