简体   繁体   English

SAP GUI 脚本打开一个 Excel 窗口,我无法停止它

[英]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.我正在尝试自动将 SAP 导出到 Excel 文件,然后另一个带有一些 VBA 代码的 Excel 文件使用该文件来自动过滤和格式化数据。

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).我已经把它全部运行了,除了一个(看似很小的)问题:SAP总是自动打开导出的Excel文件,似乎没有办法阻止它,因为它似乎发生在在Excel VBA中导入数据的子例程之后已完成(它们包含 SAP GUI 脚本)。

If I only run the sap_export subroutine, then the Excel file opens, which is simply annoying.如果我只运行sap_export子例程,则会打开 Excel 文件,这很烦人。 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.但是,如果我运行refresh_sap() ,它调用sap_export() ,然后是refresh() ,它访问导出的 Excel 文件导入数据,我会得到提示,告诉我该文件已在使用中。

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.我发现无法阻止文件被 SAP GUI 脚本打开,因为它似乎不会在运行时发生。 I suspect that this is why I couldn't find any way to use Application.Wait or DoEvents to solve this.我怀疑这就是为什么我找不到任何方法来使用 Application.Wait 或 DoEvents 来解决这个问题。 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.因为我的印象是我无法在子例程中关闭文件(因为它仅在运行时打开),所以我目前正在寻找一种方法:告诉 SAP 根本不要打开文件,或者禁止它无法访问 Excel,或者可能只是完全关闭 SAP 并查看它是否有效 - 尽管我不希望这样做。

As far as I know, SAP SDK export functions always use a dummy file in order to process exporting of data.据我所知,SAP SDK 导出函数总是使用一个虚拟文件来处理数据的导出。 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.您可以尝试允许这样做,以便在调用 refresh() 方法后打开新的导出文件。 See http://rmps.cygnaltech.net/?p=779http://rmps.cygnaltech.net/?p=779

My VBA routines usually do a lot of work after I save the SAP output to Excel format.在我将 SAP 输出保存为 Excel 格式后,我的 VBA 例程通常会做很多工作。 Like your experience, Excel immediately tries to open the file after the macro completes.与您的经验一样,Excel 会在宏完成后立即尝试打开文件。 I usually go right into post-processing the data in other VBA routines.我通常会直接在其他 VBA 例程中对数据进行后处理。 I discovered that if I do two things in the VBA algorithm, the file isn't opened and the VBA isn't interrupted.我发现如果我在 VBA 算法中做两件事,文件不会打开,VBA 也不会中断。 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.从 SAP 导出文件后,我立即通过在文件名中连接 .XLS 之前的日期和时间来重命名文件。 I save that name in the Excel file and open it separately.我将该名称保存在 Excel 文件中并单独打开它。 If your VBA ends after the export, you will get a file not found error in Excel.如果您的 VBA 在导出后结束,您将在 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.重命名后,我立即继续打开重命名的文件或VBA中的其他例程,大多数时候打开找不到文件名不会中断VBA处理。

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.我想出了一个解决方法,当我使用 SAP 脚本运行 VBA 并且 Excel 太忙而无法回答 SAP 的打开文件请求时,我观察到了这种情况。 So, when SAP goes to open the file, it tries to open it in the newest instance of Excel.因此,当 SAP 打开文件时,它会尝试在最新的 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.如果您的脚本在旧实例的电子表格中运行,SAP 会将打开文件命令发送到新实例,这意味着 Excel 打开错误消息将显示在较新的单独 Excel 实例中。 Here's how you do it:这是你如何做到的:

  1. Open your spreadsheet with the macro使用宏打开电子表格
  2. After it opens, hold down the ALT key打开后按住ALT键
  3. Still holding down ALT, new right mouse the Excel icon in the task bar仍然按住ALT,新鼠标右键任务栏中的Excel图标
  4. Still holding down ALT, select the Excel icon from the pop up menu仍然按住 ALT,从弹出菜单中选择 Excel 图标
  5. Still holding down ALT, eventually a message will appear to ask if you want a new instance, answer Yes仍然按住ALT,最终会出现一条消息询问您是否想要一个新实例,回答是
  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当显示绿色 Excel 启动消息时,松开 ALT 键 确保新实例打开到空白电子表格
  7. Now run your macro/script like normal.现在像往常一样运行你的宏/脚本。

Works like a charm in Excel 365. I have not tested it in older versions.就像 Excel 365 中的魅力一样。我没有在旧版本中测试过它。 Eventually, you have to go to the new instance of Excel and clear out all the error messages, one by one.最终,您必须转到 Excel 的新实例,并一一清除所有错误消息。

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.我通过在导出文件后立即重命名目录中的 SAP 导出文件来处理这个问题。 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.因此,如果我总是导出到 SAP_MMUsers.xlsx,我会在 VBA 编码中将其重命名为 SAP_MMUsers_0312.xlsx。 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.所以,我总是导出到 SAP_MMUsers.xlsx 并且只需要在我第一次运行宏/脚本时回答 SAP GUI“允许”问题。 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.导出文件名不应该存在于目录中,因此我不必为 Replace 选项编写代码,并且如果我需要返回查看原始数据,我会使用时间戳保存输出。 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_").在我的过程中,我总是删除目录中遵循我的 SAP 导出命名约定的所有 SAP 导出文件(它们总是以“SAP_”开头)。 That way the process has some redundancy built in to the VBA code to avoid processing interruptions.这样,该过程在 VBA 代码中内置了一些冗余,以避免处理中断。

I usually find it quicker to load the ALV table into an array and then export the array into the required location in Excel.我通常发现将 ALV 表加载到数组中然后将数组导出到 Excel 中所需的位置会更快。 This by-passes the need to open additional workbooks for processing.这绕过了打开其他工作簿进行处理的需要。 This approach is typically faster if there are < approx 1000 rows.如果有 < 大约 1000 行,这种方法通常更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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