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

时间:2015-10-21 09:57:20

标签: excel vba sap wsh

我试图自动将SAP导出到Excel文件,然后由另一个带有一些VBA代码的Excel文件使用它来自动过滤和格式化数据。

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

如果我只运行sap_export子程序,则会打开Excel文件,这简直令人讨厌。但是,如果我运行refresh_sap(),后面跟sap_export(),后面跟refresh(),它访问导出的Excel文件导入数据,我会收到提示,告诉我该文件已在使用中。< / p>

我发现没有办法阻止SAP GUI脚本打开文件,因为它似乎在运行时没有发生。我怀疑这就是为什么我找不到任何方法来使用Application.Wait或DoEvents来解决这个问题。无论我等多久,它都行不通,因为文件在运行之后才会打开。

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

由于我的印象是我无法在子程序中关闭文件(因为它只在运行时间之后打开)我目前正在寻找一种方法:告诉SAP不要打开文件所有,或者禁止它能够访问Excel,或者只是完全关闭SAP,看看是否有效 - 尽管我不愿意这样做。

3 个答案:

答案 0 :(得分:0)

据我所知,SAP SDK导出功能总是使用虚拟文件来处理数据导出。这是通过Auto Open导出的文件调用创建的。您可以尝试允许此操作,以便在调用refresh()方法后打开新的导出文件。见http://rmps.cygnaltech.net/?p=779

答案 1 :(得分:0)

将SAP输出保存为Excel格式后,我的VBA例程通常会做很多工作。像您的经验一样,Excel在宏完成后立即尝试打开文件。我通常会直接对其他VBA例程中的数据进行后处理。我发现,如果我在VBA算法中做两件事,则不会打开文件,并且不会中断VBA。这是我的工作:

  1. 从SAP导出文件后,立即通过在文件名中将.XLS之前的日期和时间串联在一起来重命名文件。我将该名称保存在Excel文件中并单独打开。如果您的VBA在导出后结束,则您将在Excel中收到“找不到文件”错误。

  2. 重命名后,我立即继续打开重命名的文件或在VBA中打开其他例程,大多数情况下,打开无法找到的文件名不会中断VBA处理。

答案 2 :(得分:0)

我想出了一个变通办法,有一次我在运行带有 SAP 脚本的 VBA 时观察到了这一点,而 Excel 太忙而无法响应 SAP 的打开文件请求。因此,当 SAP 打开文件时,它会尝试在最新的 Excel 实例中打开它。如果您的脚本在旧实例的电子表格中运行,SAP 会将打开文件命令发送到新实例,这意味着 Excel 打开错误消息将显示在较新的单独 Excel 实例中。操作方法如下:

  1. 使用宏打开电子表格
  2. 打开后,按住ALT键
  3. 仍然按住ALT,新鼠标右键单击任务栏中的Excel图标
  4. 仍然按住 ALT,从弹出菜单中选择 Excel 图标
  5. 仍然按住ALT,最终会出现一条消息,询问您是否想要一个新实例,回答是
  6. 当显示绿色 Excel 启动消息时,松开 ALT 键确保 新实例对空白电子表格开放
  7. 现在像往常一样运行您的宏/脚本。

在 Excel 365 中的作用就像一个魅力。我没有在旧版本中测试过它。最终,您必须转到 Excel 的新实例并逐一清除所有错误消息。

除此之外,您可能还需要阻止新实例打开文件。我通过在导出文件后立即重命名目录中的 SAP 导出文件来处理此问题。我通过在文件名中添加日期戳来重命名文件。这样我确保新实例不会偶然打开导出的文件。因此,如果我总是导出到 SAP_MMUsers.xlsx,我会在 VBA 编码中将其重命名为 SAP_MMUsers_0312.xlsx。所以,我总是导出到 SAP_MMUsers.xlsx 并且只需要在我第一次运行宏/脚本时回答 SAP GUI“允许”问题。导出文件名不应存在于目录中,因此我不必为“替换”选项编写代码,并且如果我需要返回查看原始数据,我会将输出与时间戳一起保存。在我的流程中,我总是删除目录中遵循我的 SAP 导出命名约定的所有 SAP 导出文件(它们总是以“SAP_”开头)。这样,该进程就会在 VBA 代码中内置一些冗余,以避免处理中断。