VBA 有时无法识别通过 SAP GUI 脚本打开的 Excel 文件

Posted

技术标签:

【中文标题】VBA 有时无法识别通过 SAP GUI 脚本打开的 Excel 文件【英文标题】:VBA is sometimes not recognizing Excel file that has been opened through SAP GUI script 【发布时间】:2022-01-24 06:15:30 【问题描述】:

我有一个每天在 VBA 中运行的 SAP GUI 脚本。在脚本中,我将一些数据从 SAP 导出到几个不同的 Excel 文件,并将这些文件保存到网络驱动器。在第一个宏中,我正在导出数据。在第二个中,我将数据复制到与脚本所在的工作簿相同的工作簿中。

奇怪的是,有时脚本会运行得很好,而有时我会收到运行时错误“下标超出范围”。错误来自这一行@ 987654321@。所以看起来 Excel 文件没有被识别为打开。然后我需要手动关闭 Excel,然后重新打开它,然后脚本就会成功运行。

我试图在给出错误的Set ws2 行前面插入下面的代码,而这段代码总是给出文件打开的消息。

    Dim Ret
    Ret = IsWorkBookOpen(filepath & "FEBA_EXPORT_" & today2 & ".XLSX")
    If Ret = True Then
        MsgBox "File is open"
    Else
        MsgBox "File is Closed"
    End If

这是函数:

Function IsWorkBookOpen(FileName As String)
    Dim ff As Long, ErrNo As Long

    On Error Resume Next
    ff = FreeFile()
    Open FileName For Input Lock Read As #ff
    Close ff
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
    Case 0:    IsWorkBookOpen = False
    Case 70:   IsWorkBookOpen = True
    Case Else: Error ErrNo
    End Select
End Function

这是代码的相关部分:

Sub CopyExportedFEBA_ExtractFEBRE()

    Dim SapGuiAuto As Object
    Dim SAPApp As Object
    Dim SAPCon As Object
    Dim session As Object

    Set SapGuiAuto = GetObject("SAPGUI")
    Set SAPApp = SapGuiAuto.GetScriptingEngine
    Set SAPCon = SAPApp.Children(0)
    Set session = SAPCon.Children.ElementAt(0) ' <--- Assumes you are using the first session open. '
    
    Dim ws0, ws1, ws2, ws6, ws7 As Worksheet
    
    Set ws0 = Workbooks("FEB_BSPROC.xlsm").Worksheets("INPUT")
    Set ws1 = Workbooks("FEB_BSPROC.xlsm").Worksheets("FEB_BSPROC")
    Set ws6 = Workbooks("FEB_BSPROC.xlsm").Worksheets("FBL3N_1989")
    
    Dim today2, filepath As String
    today2 = ws0.Range("E2")
    filepath = ws0.Range("A7")
    
    ' Check if  if FEBA_EXPORT wb is open
    ' This is giving the message that the file is open
    
    Dim Ret
    Ret = IsWorkBookOpen(filepath & "FEBA_EXPORT_" & today2 & ".XLSX")
    If Ret = True Then
        MsgBox "File is open"
    Else
        MsgBox "File is Closed"
    End If
    
    ' This is giving runtime error 9 Subscript out of range
    ' If manually close the Excel and the  reopen, then it will always work after this
    Set ws2 = Workbooks("FEBA_EXPORT_" & today2 & ".XLSX").Worksheets("Sheet1")
    
    'This is never giving any errors
    Set ws7 = Workbooks("1989_" & today2 & ".XLSX").Worksheets("Sheet1")

filepath 变量是网络驱动器的完整文件路径:\\fisv00j-55\UiPath\UiPath_PEC\InputFilesForRobots\PEC-TR-002-FEB_BSPROC\SAP_EXTRACTS\,所以这不是问题。此外,我还有另一个以相同方式打开的 Excel,并且从未出现任何错误。 today2 变量也是正确的。

我认为如果我可以使用 VBA 关闭 ws2 工作簿然后重新打开它,它会起作用。所以我试图关闭它而不将其设置为变量,但后来我得到了同样的错误。我真的不知道如何让这个脚本始终如一地工作。

有人遇到过类似的问题吗?当您将任何内容导出到 Excel 文件时,使用 SAP GUI 脚本,文件将在保存后自动打开。我想知道这可能是问题吗?但奇怪的是,我只有这个 Excel 文件有问题,而其他几个以相同方式保存和打开的文件中的任何一个都没有。

【问题讨论】:

有时 SAP 会将文件导出到由它创建的新 Excel 会话。而您的检查方式只能证明它在某处开放 【参考方案1】:

正如我在上面的评论中所说,工作簿可能会在新会话中打开,与运行代码的会话不同。请使用下一个函数来确定是否是不同 Excel 会话的问题:

Function sameExSession(wbFullName As String, Optional boolClose As Boolean) As Boolean
   Dim sessEx As Object, wb As Object
  
   Set sessEx = GetObject(wbFullName).Application
   If sessEx.hwnd = Application.hwnd Then
        sameExSession = True
   Else
        sameExSession = False
        If boolClose Then
            sessEx.Workbooks(Right(wbFullName, Len(wbFullName) - InStrRev(wbFullName, "\"))).Close False
            sessEx.Quit: Set sessEx = Nothing
        End If
   End If
End Function

它识别工作簿打开的会话,然后将其句柄与活动会话一比较,如果不相同,则关闭工作簿(如果调用第二个参数为True的函数),退出会话并返回False。如果只是检查,则调用第二个参数为False的函数(工作簿不会关闭,会话仍然存在)。

可以按以下方式使用:

Sub testSameExSession()
   Dim wbFullName As String, wbSAP As Workbook
   wbFullName = filepath & "FEBA_EXPORT_" & today2 & ".XLSX"
   If sameExSession(wbFullName, True) Then
        Debug.Print "The same session"
        Set wbSAP = Workbooks("FEBA_EXPORT_" & today2 & ".XLSX")
   Else
        Debug.Print "Different session..."
        Set wbSAP = Workbooks.Open(wbFullName)        
   End If
   Debug.Print wbSAP.Name
   'use the set workbook to do what you need...
End Sub

当您遇到上述问题时,请使用上述方式测试是否是不同会话的问题。

如果是这样,我认为在您现有的代码中输入这部分很容易。如果工作簿将在不同的会话中打开,则无需手动关闭(并重新打开),上面的功能就可以了...

【讨论】:

@sebsee 你没有抽出时间来测试上述解决方案吗?如果经过测试,它没有按您的需要工作吗?据我所知,一点反馈并没有杀死任何人...... 嗨,抱歉耽搁了。我无法自己复制错误,所以我不得不等到我再次收到错误。但我现在遇到了同样的错误,我可以确认该错误是由于 Excel 在不同的会话中打开所致。这个解决方案就像一个魅力。我不知道工作簿可以在不同的会话中打开。非常感谢!

以上是关于VBA 有时无法识别通过 SAP GUI 脚本打开的 Excel 文件的主要内容,如果未能解决你的问题,请参考以下文章

无法通过UFT正确识别SAP对象

打开sap,然后通过c#Automation继续登录屏幕

通过EXCEL VBA 连接SAP系统后,导出打开的电子表格文件另存(不是系统自带的导出EXCEL表)

VBA 无法识别我已经打开的工作簿

sap sfp事务 布局设计器无法打开

Autodesk Inventor VBA 脚本