简体   繁体   中英

SAP GUI script opens an Excel window and I can't stop it

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:

  1. 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.

  2. 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:

  1. Open your spreadsheet with the macro
  2. After it opens, hold down the ALT key
  3. Still holding down ALT, new right mouse the Excel icon in the task bar
  4. Still holding down ALT, select the Excel icon from the pop up menu
  5. Still holding down ALT, eventually a message will appear to ask if you want a new instance, answer Yes
  6. When the green Excel start up message is displayed, release the ALT key Make sure that the new instance is open to a blank spreadsheet
  7. Now run your macro/script like normal.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM