I'm trying to automate SAP export to an Excel file, which in turn is then used by another Excel file with some VBA code to automate filtering and formatting the data.
I've got it all running, except for one (seemingly minor) problem: SAP always opens the exported Excel file automatically and there seems to be no way of stopping this as it seems to happen AFTER the subroutines to import the Data in Excel VBA have finished (they contain the SAP GUI script).
If I only run the sap_export
subroutine, then the Excel file opens, which is simply annoying. But if I run refresh_sap()
, which calls sap_export()
, followed by refresh()
, which accesses the exported Excel file importing data, I get the prompt telling me that the file is already in use.
I have found no way to stop the file from being opened by the SAP GUI script as it does not seem to happen during run time. I suspect that this is why I couldn't find any way to use Application.Wait or DoEvents to solve this. However long I wait, it will not work, as the file is simply never open until after runtime.
Sub refresh_sap()
Call sap_export
Call refresh
End Sub
Sub refresh()
'refreshes the connection to the SAP-exported Excel-file
ActiveWorkbook.Connections("export").refresh
'deleting unwanted data
ActiveWorkbook.Sheets("PC-Liste komplett").Select
Selection.AutoFilter
ActiveSheet.ListObjects("Tabelle_export").Range.AutoFilter Field:=4, Criteria1:="Löschen"
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.EntireRow.Delete
ActiveSheet.ListObjects("Tabelle_export").Range.AutoFilter Field:=4
Range("A1").Select
End Sub
Sub sap_export()
Dim set0 As Integer
Dim set1 As String
Dim set2 As Boolean
'vbs-script recorded with the SAP-GUI
If Not IsObject(sapp) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set sapp = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(Scon) Then
Set Scon = sapp.Children(0)
End If
If Not IsObject(session) Then
Set session = Scon.Children(0)
End If
If IsObject(WScript) Then
WScript.connectobject session, "on"
WScript.connectobject sapp, "on"
End If
session.findById("wnd[0]/tbar[0]/okcd").Text = "/n KE5X"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/ctxtGT_PRCTR-LOW").Text = "*"
session.findById("wnd[0]").sendVKey 8
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").contextMenu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectContextMenuItem "&XXL"
If session.findById("wnd[1]/usr/radRB_1").Selected = True Then
set0 = 0
ElseIf session.findById("wnd[1]/usr/radRB_2").Selected = True Then
set0 = 1
ElseIf session.findById("wnd[1]/usr/radRB_OTHERS").Selected = True Then
set0 = 2
End If
set1 = session.findById("wnd[1]/usr/cmbG_LISTBOX").Key
set2 = session.findById("wnd[1]/usr/chkCB_ALWAYS").Selected
session.findById("wnd[1]/usr/radRB_OTHERS").Select
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "10"
session.findById("wnd[1]/usr/chkCB_ALWAYS").Selected = False
session.findById("wnd[1]").sendVKey 0
session.findById("wnd[1]/usr/ctxtDY_PATH").Text = "S:\FIN-Alle\Kostenstellen - Innenauftragsliste\SAP"
session.findById("wnd[1]/tbar[0]/btn[11]").press
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").contextMenu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectContextMenuItem "&XXL"
Select Case set0
Case 0
session.findById("wnd[1]/usr/radRB_1").Select
Case 1
session.findById("wnd[1]/usr/radRB_2").Select
Case 2
session.findById("wnd[1]/usr/radRB_OTHERS").Select
End Select
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = set1
session.findById("wnd[1]/usr/chkCB_ALWAYS").Selected = set2
session.findById("wnd[1]").sendVKey 12
session.findById("wnd[0]/tbar[0]/okcd").Text = "/n"
session.findById("wnd[0]").sendVKey 0
End Sub
As I have the impression that I can do nothing to close the file within the subroutines (as it only opens after the run time) I'm currently looking for a way to: tell SAP not to open the file at all, or to prohibit it from being able to access Excel, or maybe just close SAP altogether and see if that works - although I would prefer not to do that.
As far as I know, SAP SDK export functions always use a dummy file in order to process exporting of data. This is by so, created via the Auto Open exported file calls. You may try to allow this in order for you to open new exported file after calling refresh() method. See http://rmps.cygnaltech.net/?p=779
My VBA routines usually do a lot of work after I save the SAP output to Excel format. Like your experience, Excel immediately tries to open the file after the macro completes. I usually go right into post-processing the data in other VBA routines. I discovered that if I do two things in the VBA algorithm, the file isn't opened and the VBA isn't interrupted. Here's what I do:
Immediately after I export the file from SAP, I rename the file by concatenating the date and time before the .XLS in the filename. I save that name in the Excel file and open it separately. If your VBA ends after the export, you will get a file not found error in Excel.
After the rename, I immediately go on to open the renamed file or to other routines in the VBA, most of the time the open of the can't-be-found filename does not interrupt the VBA processing.
I figured out a work around, which I observed one time when I ran a VBA with SAP scripting and Excel was too busy to answer SAP's open file request. So, when SAP goes to open the file, it tries to open it in the newest instance of Excel. If your script is running in a spreadsheet in an older instance, SAP will send the open file command to the new one, which means the Excel open error message will show up in the newer separate instance of Excel. Here's how you do it:
Works like a charm in Excel 365. I have not tested it in older versions. Eventually, you have to go to the new instance of Excel and clear out all the error messages, one by one.
In addition to this, you may need to keep the new instance from opening the file anyway. I handle this by renaming the SAP export file in the directory immediately after exporting the file. I rename the file by adding a date stamp in the file name. That way I make sure that the new instance does not by chance open the exported file. So, if I'm always exporting to SAP_MMUsers.xlsx, I rename it to SAP_MMUsers_0312.xlsx in VBA coding. So, I'm always exporting to SAP_MMUsers.xlsx and only have to answer the SAP GUI "allow" questions the first time I run the macro/script. The export file name should not exist in the directory, so I don't have to code for the Replace option and I have the output saved with a timestamp if I need to go back and look at the original data. As a point of my process, I always delete any SAP export files in the directory that follow my naming convention for SAP exports (they always begin with "SAP_"). That way the process has some redundancy built in to the VBA code to avoid processing interruptions.
I usually find it quicker to load the ALV table into an array and then export the array into the required location in Excel. This by-passes the need to open additional workbooks for processing. This approach is typically faster if there are < approx 1000 rows.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.