未知表ID时如何获取SAP Script中业务范围表的行数
问题背景
编写SAP GUI脚本实现物料信息批量下载,执行逻辑如下:
- 第一步:调用SAP获取指定工厂的信息
- 第二步:将下钻维度切换为业务范围(BA)
- 第三步:按物料编码下钻,拉取每个业务范围对应的明细数据
当前卡点:
不同工厂绑定的业务范围数量不固定,编写第二层物料下钻的for循环时,无法在表ID未知的前提下获取业务范围视图下首表的总行数,无法确定循环边界值LastRowOfTheBusinessAreaTable。脚本还需补充物料编码数据导出至Excel的逻辑,该部分代码未在下方贴出。
现有脚本代码
If Not IsObject(application) Then Set SapGuiAuto = GetObject("SAPGUI") Set application = 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 'Startup session.findById("wnd[0]").maximize 'Variables filepath = "30-06-2022" 'Poner la fecha del dia de descarga CurrentDate = "07/2022" 'Poner el mes del analisis PlantList = Array(NameOfAllThePlants) 'Search for MCBA session.findById("wnd[0]/tbar[0]/okcd").text = "MCBA" session.findById("wnd[0]").sendVKey 0 For i = 0 To 23 Step 1 'MCBA Parameters session.findById("wnd[0]/usr/ctxtSL_WERKS-LOW").text = PlantList(i) session.findById("wnd[0]/usr/ctxtSL_SPMON-LOW").text = "07/2022" session.findById("wnd[0]/usr/ctxtSL_SPMON-HIGH").text = "07/2022" session.findById("wnd[0]/usr/ctxtSL_SPMON-HIGH").setFocus session.findById("wnd[0]/usr/ctxtSL_SPMON-HIGH").caretPosition = 7 session.findById("wnd[0]/tbar[1]/btn[8]").press 'Analysis Currency session.findById("wnd[0]/tbar[1]/btn[31]").press session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[0,21]").text = "usd" session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[2,21]").text = "07/04/2022" session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[2,21]").setFocus session.findById("wnd[1]/usr/sub:SAPLSPO4:0300/ctxtSVALD-VALUE[2,21]").caretPosition = 10 session.findById("wnd[1]/tbar[0]/btn[0]").press 'Change drilldown to Business Area session.findById("wnd[0]/tbar[1]/btn[7]").press session.findById("wnd[1]/tbar[0]/btn[0]").press ' 原循环逻辑,缺少边界值 For j = 0 To LastRowOfTheBusinessAreaTable 'Drilldown by MaterialCode session.findById("wnd[0]/usr/lbl[1,"&Cstr(j+6)&"]").setFocus session.findById("wnd[0]/usr/lbl[1,"&Cstr(j+6)&"]").caretPosition = 3 session.findById("wnd[0]").sendVKey 8 session.findById("wnd[1]/usr/sub:SAPLMCS2:0201/radLMCS2-MRKKZ[4,0]").select session.findById("wnd[1]/usr/sub:SAPLMCS2:0201/radLMCS2-MRKKZ[4,0]").setFocus session.findById("wnd[1]/tbar[0]/btn[0]").press 'back to Business Area view session.findById("wnd[0]/tbar[0]/btn[3]").press session.findById("wnd[0]/usr/lbl[1,7]").setFocus session.findById("wnd[0]/usr/lbl[1,7]").caretPosition = 7 session.findById("wnd[0]").sendVKey 8 'session.findById("wnd[1]/usr/sub:SAPLMCS2:0201/radLMCS2-MRKKZ[4,0]").setFocus session.findById("wnd[1]/tbar[0]/btn[0]").press Next 'back session.findById("wnd[0]/tbar[0]/btn[3]").press 'don't save session.findById("wnd[1]/usr/btnSPOP-OPTION2").press
解决方法
不需要提前获取表ID和总行数,直接用逐行探测的方式遍历业务范围列表,探测到列表末尾自动终止循环,完全适配不同工厂业务范围数量不一致的场景。
将原第二层固定边界的For循环替换为以下Do Loop逻辑即可:
' 切换到业务范围视图后初始化行计数 j = 0 ' 加最大行数兜底,防止异常死循环,可根据实际业务量调整 Const MAX_BA_COUNT = 1000 Do On Error Resume Next Set baRow = session.findById("wnd[0]/usr/lbl[1," & CStr(j+6) & "]") ' 找不到对应行控件,说明已到列表末尾 If Err.Number <> 0 Or j > MAX_BA_COUNT Then Err.Clear On Error GoTo 0 Exit Do End If On Error GoTo 0 ' 原下钻逻辑保留 'Drilldown by MaterialCode session.findById("wnd[0]/usr/lbl[1,"&Cstr(j+6)&"]").setFocus session.findById("wnd[0]/usr/lbl[1,"&Cstr(j+6)&"]").caretPosition = 3 session.findById("wnd[0]").sendVKey 8 session.findById("wnd[1]/usr/sub:SAPLMCS2:0201/radLMCS2-MRKKZ[4,0]").select session.findById("wnd[1]/usr/sub:SAPLMCS2:0201/radLMCS2-MRKKZ[4,0]").setFocus session.findById("wnd[1]/tbar[0]/btn[0]").press 'back to Business Area view session.findById("wnd[0]/tbar[0]/btn[3]").press session.findById("wnd[0]/usr/lbl[1,7]").setFocus session.findById("wnd[0]/usr/lbl[1,7]").caretPosition = 7 session.findById("wnd[0]").sendVKey 8 session.findById("wnd[1]/tbar[0]/btn[0]").press j = j + 1 Loop
关于Excel导出功能,不需要逐单元格读取拷贝,直接在物料明细视图调用SAP标准导出按钮即可,代码示例:
' 进入物料明细视图后调用导出功能 session.findById("wnd[0]/tbar[1]/btn[45]").press ' 选择电子表格格式 session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[1,0]").select session.findById("wnd[1]/tbar[0]/btn[0]").press ' 指定导出路径和文件名 session.findById("wnd[1]/usr/ctxtDY_PATH").text = "C:\导出目录\" session.findById("wnd[1]/usr/ctxtDY_FILENAME").text = "物料明细_" & PlantList(i) & "_BA" & j & ".xlsx" session.findById("wnd[1]/tbar[0]/btn[0]").press
内容的提问来源于stack exchange,提问作者Fernando Brenes
相关产品推荐
相关产品推荐

