如何激活从 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