如何激活从 SAP 导出的工作簿?
How to activate workbook exported from SAP?
我有一个宏来处理来自 SAP 的数据。
当出现来自 SAP 的工作簿时,我无法通过下面的 VBA 代码激活它。
即使Workbooks("export.xlsx").activate
也不行。
session.findById("wnd[0]/tbar[0]/okcd").Text = "/nFBL3N"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/btn%_SD_SAKNR_%_APP_%-VALU_PUSH").press
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,0]").Text = "179811"
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").Text = "431311"
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").SetFocus
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").caretPosition = 6
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[8]").press
session.findById("wnd[0]/usr/radX_AISEL").Select
session.findById("wnd[0]/usr/ctxtSO_BUDAT-LOW").Text = "01.03.2020"
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").Text = "31.03.2020"
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").SetFocus
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").caretPosition = 10
session.findById("wnd[0]/tbar[1]/btn[16]").press
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").Text = "L6"
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").SetFocus
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").caretPosition = 2
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/mbar/menu[0]/menu[3]/menu[1]").Select
session.findById("wnd[1]/tbar[0]/btn[11]").press
Set session = Nothing
Set Connection = Nothing
Set SapGuiAuto = Nothing
Set WScript = Nothing
Set Application = Nothing
Dim wb As Workbook
Windows("export.XLSX").Activate
为了在所有打开的 Excel 会话中检查工作簿是否存在,请使用下一个代码,我将解释
首先复制模块顶部的下一段代码(在声明部分):
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hWnd As LongPtr, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare PtrSafe Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As LongPtr, ByVal hwndChildAfter As LongPtr, _
ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
#Else
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If
然后,使用从现有代码调用的下一个函数(而不是 Windows("export.XLSX").Activate
):
Private Function GetExcelSes() As Collection
Dim g&(0 To 3), ppv As Object, hWnd, hWnd2, hWnd3
g(0) = &H20400: g(1) = &H0
g(2) = &HC0: g(3) = &H46000000
Dim AlreadyThere As Boolean, Xl As Application
Set GetExcelSes = New Collection
Do
hWnd = FindWindowExA(0, hWnd, "XLMAIN", vbNullString)
If hWnd = 0 Then Exit Do
hWnd2 = FindWindowExA(hWnd, 0, "XLDESK", vbNullString)
hWnd3 = FindWindowExA(hWnd2, 0, "EXCEL7", vbNullString)
If AccessibleObjectFromWindow(hWnd3, &HFFFFFFF0, g(0), ppv) = 0 Then
AlreadyThere = False
For Each Xl In GetExcelSes
If Xl Is ppv.Application Then
AlreadyThere = True
Exit For
End If
Next
If Not AlreadyThere Then
GetExcelSes.aDD ppv.Application
End If
End If
Loop
End Function
上面的函数可以像下面的例子一样调用(像现在这样使用它而不是你的最后一行代码)。声明很重要:
Sub TestSaveAWbFromAllSess()
Dim Ex As Collection, El As Variant
Dim wb As Workbook, expWb As Workbook
Set Ex = GetExcelSes
For Each El In Ex
For Each wb In El.Workbooks
Debug.Print wb.Name 'just to see all open wb names, confirming that the function works...
If UCase(wb.Name) = "EXPORT.XLSX" Then
Set expWb = wb
'Do here whatever you need with the found workbook. For instance:
expWb.SaveCopyAs fileName:=ThisWorkbook.path & "\TestSAPExport.XLSX"
End If
Next
Next
End Sub
我有一个宏来处理来自 SAP 的数据。
当出现来自 SAP 的工作簿时,我无法通过下面的 VBA 代码激活它。
即使Workbooks("export.xlsx").activate
也不行。
session.findById("wnd[0]/tbar[0]/okcd").Text = "/nFBL3N"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/btn%_SD_SAKNR_%_APP_%-VALU_PUSH").press
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,0]").Text = "179811"
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").Text = "431311"
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").SetFocus
session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL_255-SLOW_I[1,1]").caretPosition = 6
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[8]").press
session.findById("wnd[0]/usr/radX_AISEL").Select
session.findById("wnd[0]/usr/ctxtSO_BUDAT-LOW").Text = "01.03.2020"
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").Text = "31.03.2020"
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").SetFocus
session.findById("wnd[0]/usr/ctxtSO_BUDAT-HIGH").caretPosition = 10
session.findById("wnd[0]/tbar[1]/btn[16]").press
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").Text = "L6"
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").SetFocus
session.findById("wnd[0]/usr/ssub%_SUBSCREEN_%_SUB%_CONTAINER:SAPLSSEL:2001/ssubSUBSCREEN_CONTAINER2:SAPLSSEL:2000/ssubSUBSCREEN_CONTAINER:SAPLSSEL:1106/ctxt%%DYN009-LOW").caretPosition = 2
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/mbar/menu[0]/menu[3]/menu[1]").Select
session.findById("wnd[1]/tbar[0]/btn[11]").press
Set session = Nothing
Set Connection = Nothing
Set SapGuiAuto = Nothing
Set WScript = Nothing
Set Application = Nothing
Dim wb As Workbook
Windows("export.XLSX").Activate
为了在所有打开的 Excel 会话中检查工作簿是否存在,请使用下一个代码,我将解释
首先复制模块顶部的下一段代码(在声明部分):
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hWnd As LongPtr, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare PtrSafe Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As LongPtr, ByVal hwndChildAfter As LongPtr, _
ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
#Else
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If
然后,使用从现有代码调用的下一个函数(而不是 Windows("export.XLSX").Activate
):
Private Function GetExcelSes() As Collection
Dim g&(0 To 3), ppv As Object, hWnd, hWnd2, hWnd3
g(0) = &H20400: g(1) = &H0
g(2) = &HC0: g(3) = &H46000000
Dim AlreadyThere As Boolean, Xl As Application
Set GetExcelSes = New Collection
Do
hWnd = FindWindowExA(0, hWnd, "XLMAIN", vbNullString)
If hWnd = 0 Then Exit Do
hWnd2 = FindWindowExA(hWnd, 0, "XLDESK", vbNullString)
hWnd3 = FindWindowExA(hWnd2, 0, "EXCEL7", vbNullString)
If AccessibleObjectFromWindow(hWnd3, &HFFFFFFF0, g(0), ppv) = 0 Then
AlreadyThere = False
For Each Xl In GetExcelSes
If Xl Is ppv.Application Then
AlreadyThere = True
Exit For
End If
Next
If Not AlreadyThere Then
GetExcelSes.aDD ppv.Application
End If
End If
Loop
End Function
上面的函数可以像下面的例子一样调用(像现在这样使用它而不是你的最后一行代码)。声明很重要:
Sub TestSaveAWbFromAllSess()
Dim Ex As Collection, El As Variant
Dim wb As Workbook, expWb As Workbook
Set Ex = GetExcelSes
For Each El In Ex
For Each wb In El.Workbooks
Debug.Print wb.Name 'just to see all open wb names, confirming that the function works...
If UCase(wb.Name) = "EXPORT.XLSX" Then
Set expWb = wb
'Do here whatever you need with the found workbook. For instance:
expWb.SaveCopyAs fileName:=ThisWorkbook.path & "\TestSAPExport.XLSX"
End If
Next
Next
End Sub