excel 如何在工作表中的行处循环?

wf82jlnq  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(148)

我每天都会收到一个Excel文件,里面有大约500个文档,我需要从SAP系统下载每个文档的附件。我记录了一个SAP GUI脚本,但我无法循环遍历所有文档。需要帮助
我需要输入文件编号、公司代码和会计年度(所有都将是动态的”)。如何创建一个变量和循环,以便从Excel工作表中为这三个条件选取值?

Public Sub SAPlogin()
    
    Set WshShell = CreateObject("WScript.Shell")
    Set proc = WshShell.Exec("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe")
               
    Dim temp
    temp = Timer
    Do While Timer - temp < 5
        Loop
    Set SapGui = GetObject("SAPGUI")
    Set Appl = SapGui.GetScriptingEngine
    
    Set Connection = Appl.Openconnection("ERP", True)
    Set session = Connection.Children(0)
    
    session.findById("wnd[0]/usr/txtRSYST-BNAME").Text = "XXXX"
    session.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = "XXXX"
    session.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "EN"
    session.findById("wnd[0]").sendVKey 0
    
    If Not IsObject(Application) Then
       Set SapGuiAuto = GetObject("SAPGUI")
       Set Appl = SapGuiAuto.GetScriptingEngine
    End If
    If Not IsObject(Connection) Then
       Set Connection = Application.Children(0)
    End If
    If Not IsObject(session) Then
       Set session = Connection.Children(0)
    End If
    If IsObject(WScript) Then
       WScript.ConnectObject session, "on"
       WScript.ConnectObject Application, "on"
    End If
    session.findById("wnd[0]").maximize
    session.findById("wnd[0]/tbar[0]/okcd").Text = "fb03"
    session.findById("wnd[0]").sendVKey 0
    session.findById("wnd[0]/usr/txtRF05L-BELNR").Text = "1"
    session.findById("wnd[0]/usr/ctxtRF05L-BUKRS").Text = "20"
    session.findById("wnd[0]/usr/txtRF05L-GJAHR").Text = "2019"
    session.findById("wnd[0]/usr/txtRF05L-GJAHR").SetFocus
    session.findById("wnd[0]/usr/txtRF05L-GJAHR").caretPosition = 4
    session.findById("wnd[0]").sendVKey 0
    session.findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
    session.findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").currentCellColumn = "BITM_DESCR"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
    session.findById("wnd[1]/tbar[0]/btn[0]").press
    session.findById("wnd[0]").sendVKey 12
    session.findById("wnd[0]/usr/txtRF05L-BELNR").Text = "2"
    session.findById("wnd[0]").sendVKey 0
    session.findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
    session.findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").currentCellColumn = "BITM_DESCR"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"
    session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
    session.findById("wnd[1]/tbar[0]/btn[0]").press
    session.findById("wnd[0]").sendVKey 12

End Sub
rryofs0p

rryofs0p1#

首先简化您的脚本,将其分解为更小的组件。例如,创建一个用于登录的函数,特别是如果您要开始创建几个不同的函数。

Public Function StartSAPSession() as Variant
    ' Enter your script here for logging in and starting a new session
    '....

    ' Return the session
    Set StartSAPSession = Connection.Children(0)
End Function

我将全局声明会话对象,这样每次运行宏时,就不需要登录并打开新的会话。请注意,使用会话作为小写将简化从SAP GUI脚本记录器的复制和粘贴。

Public session as Variant

然后是真正“做”你所追求的...
让我们假设Table 1包含需要查询的3个字段;文件编号、公司代码和会计年度。我们将循环遍历此表中的每一行。我们还将假设每个文件的数量可能会发生变化。我们检查会话是否存在(如果不存在,则创建一个),填充查询字段,通过上下文菜单查看附件并下载它们。注意:我现在没有访问SAP示例的权限,所以没有机会测试它。它改编自我以前编译的工具。这将需要逐步通过并做一些测试。我通常还做了大量的测试,以了解可能收到的错误,然后找到有效处理它们的方法。不管怎样,给你…

Public Function ExtractDocuments()
    Dim Arr() as Variant
    Dim DocNum as String
    Dim Company as String
    Dim FY as String
    Dim AttCnt as Integer
    Dim i as Long
    Dim j as Long

    ' When session is Nothing then we need to create a new session
    ' else assume we can re-use the session 
    If session Is Nothing Then
        Set session = StartSAPSession
    End If

    ' Load the table as an Array, this will be faster
    Arr = Range("Table1").ListObject.DataBodyRange

    ' Cycle through each row of the table (Arr)
    For i = 1 to Ubound(Arr, 1)
        ' Start by loading the row you will enter
        DocNum = Arr(i, 1)
        Company = Arr(i, 2)
        FY = Arr(i, 3)

        With session
            .findById("wnd[0]").maximize
            .StartTransaction "FB03"   ' Load the transaction you are after
            .findById("wnd[0]/usr/txtRF05L-BELNR").Text = DocNum
            .findById("wnd[0]/usr/ctxtRF05L-BUKRS").Text = Company
            .findById("wnd[0]/usr/txtRF05L-GJAHR").Text = FY
            .findById("wnd[0]").sendVKey 0    ' Execute transaction

            ' The query runs and you select context menu and attachments
            .findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
            .findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"

            ' How many attachments are there? If 1 or more then save each.
            AttCnt = .findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").RowCount
            If AttCnt > 0 Then
                For j = 0 to AttCnt -1
                    .findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = j
                    .findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
                Next j
                .findById("wnd[1]/tbar[0]/btn[0]").press   ' Exit the Attachments window
            End If
        End With
    Next i
End Function

还有更多的机会将其进一步分解为更多的子函数和函数,以使其更具可读性和可重用性。
祝你好运!

相关问题