VBA 有时无法识别通过 SAP GUI 脚本打开的 Excel 文件
VBA is sometimes not recognizing Excel file that has been opened through SAP GUI script
我每天 VBA 都有一个 SAP GUI 脚本 运行ning。在脚本中,我将一些数据从 SAP 导出到几个不同的 Excel 文件,并将这些文件保存到网络驱动器。在第一个宏中,我导出数据。在第二个中,我将数据复制到与脚本所在的同一工作簿中。
有时我会遇到 运行时间错误
Subscript out of range
于 Set ws2 = Workbooks("FEBA_EXPORT_" & today2 & ".XLSX").Worksheets("Sheet1")
。
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
工作簿然后重新打开它,它会起作用。所以我试图关闭它而不将其设置为变量,但后来我得到了同样的错误。
使用 SAP GUI 脚本将任何内容导出到 Excel 文件时,文件将在保存后自动打开。我想知道这是否是问题所在?我只有这个 Excel 文件有问题,其他几个以相同方式保存和打开的文件没有问题。
正如我在上面的评论中所说,工作簿可能会在新会话中打开,与运行代码的会话不同。请使用下一个函数来确定是否是不同 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
的函数),退出会话和 returns False
。如果只是检查,调用第二个参数为False
的函数(workbook不会关闭,session仍然存在)
可以用下面的方法:
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
当您遇到描述的问题时,请使用上面的方式测试是否是不同会话的问题。
如果是这样,我认为在您现有的代码中输入这部分很容易。如果工作簿将在不同的会话中打开,则无需手动关闭它(并重新打开),上面的函数就可以了...
我每天 VBA 都有一个 SAP GUI 脚本 运行ning。在脚本中,我将一些数据从 SAP 导出到几个不同的 Excel 文件,并将这些文件保存到网络驱动器。在第一个宏中,我导出数据。在第二个中,我将数据复制到与脚本所在的同一工作簿中。
有时我会遇到 运行时间错误
Subscript out of range
于 Set ws2 = Workbooks("FEBA_EXPORT_" & today2 & ".XLSX").Worksheets("Sheet1")
。
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
工作簿然后重新打开它,它会起作用。所以我试图关闭它而不将其设置为变量,但后来我得到了同样的错误。
使用 SAP GUI 脚本将任何内容导出到 Excel 文件时,文件将在保存后自动打开。我想知道这是否是问题所在?我只有这个 Excel 文件有问题,其他几个以相同方式保存和打开的文件没有问题。
正如我在上面的评论中所说,工作簿可能会在新会话中打开,与运行代码的会话不同。请使用下一个函数来确定是否是不同 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
的函数),退出会话和 returns False
。如果只是检查,调用第二个参数为False
的函数(workbook不会关闭,session仍然存在)
可以用下面的方法:
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
当您遇到描述的问题时,请使用上面的方式测试是否是不同会话的问题。
如果是这样,我认为在您现有的代码中输入这部分很容易。如果工作簿将在不同的会话中打开,则无需手动关闭它(并重新打开),上面的函数就可以了...