SAP MIGO动态ID问题:VBA脚本运行时错误619求解
解决SAP MIGO动态子屏幕ID导致的VBA运行时错误619
核心问题
SAP MIGO事务的主容器控件ID(如ssubSUB_MAIN_CARRIER:SAPLMIGO:0003中的0003)是动态生成的,会随操作步骤、SAP配置或版本变化,硬编码固定ID会导致FindById找不到控件,抛出运行时错误619。
获取动态ID的两种方法
1. 手动查看(快速验证)
- 打开SAP GUI进入MIGO事务,按
Ctrl+F1调出「技术信息」窗口 - 点击目标控件(如操作下拉框、物料凭证输入框),查看「属性」中的
ID字段,提取SAPLMIGO:后的数字部分 - 也可通过SAP GUI脚本录制功能,执行一遍业务流程,录制完成后查看生成的脚本,直接获取当前会话的动态ID
2. VBA自动遍历获取(自动化场景)
通过SAP GUI的API遍历当前窗口的子屏幕控件,自动匹配SAPLMIGO程序对应的动态ID,无需手动硬编码:
Function GetMigoMainSubScreenId(Session As Object) As String Dim subscreens As Object Dim subscreen As Object Set subscreens = Session.ActiveWindow.FindAllByName("ssubSUB_MAIN_CARRIER", "GuiSubScreen") For Each subscreen In subscreens If subscreen.Program = "SAPLMIGO" Then GetMigoMainSubScreenId = Split(subscreen.Id, ":")(2) Exit Function End If Next subscreen ' 未找到时返回默认值,可根据实际场景调整 GetMigoMainSubScreenId = "0003" End Function
修改后的完整VBA代码
将原代码中的硬编码ID替换为动态获取的ID,注意每次屏幕切换后需重新获取ID(如执行sendVKey、press操作后):
Sub MigoCancellation() Dim Session As Object Dim migoMainScreenId As String Dim MatDoc As String ' 需提前赋值物料凭证号 ' 假设已建立SAP会话连接,此处省略连接代码 ' Set Session = ... ' -------------------------- ' 第一步:初始屏幕操作(获取初始动态ID) ' -------------------------- migoMainScreenId = GetMigoMainSubScreenId(Session) ' 填充操作类型、物料凭证 Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/cmbGODYNPRO-ACTION").SetFocus Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/cmbGODYNPRO-ACTION").Key = "A03" Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-MAT_DOC").Text = "" Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-DOC_YEAR").Text = "" Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-MAT_DOC").Text = MatDoc Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-MAT_DOC").caretPosition = 1 Session.FindById("wnd[0]").sendVKey 0 ' 处理财年问题 If InStr(Session.FindById("wnd[0]/sbar").Text, "Fiscal") <> 0 Then Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-DOC_YEAR").Text = Year(Date) - 1 Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-DOC_YEAR").SetFocus Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_FIRSTLINE:SAPLMIGO:0011/subSUB_FIRSTLINE_REFDOC:SAPLMIGO:2010/txtGODYNPRO-DOC_YEAR").caretPosition = 4 Session.FindById("wnd[0]").sendVKey 0 End If ' 点击物料明细按钮,屏幕切换后重新获取ID Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_ITEMDETAIL:SAPLMIGO:0301/btnBUTTON_ITEMDETAIL").press migoMainScreenId = GetMigoMainSubScreenId(Session) ' 更新为新的动态ID ' -------------------------- ' 第二步:选择物料行、修改抬头信息 ' -------------------------- Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_ITEMLIST:SAPLMIGO:0200/tblSAPLMIGOTV_GOITEM/chkGOITEM-TAKE_IT[4,0]").Selected = True Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_HEADER:SAPLMIGO:0101/subSUB_HEADER:SAPLMIGO:0100/tabsTS_GOHEAD/tabpOK_GOHEAD_GENERAL").Select ' 填充日期信息 Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_HEADER:SAPLMIGO:0101/subSUB_HEADER:SAPLMIGO:0100/tabsTS_GOHEAD/tabpOK_GOHEAD_GENERAL/ssubSUB_TS_GOHEAD_GENERAL:SAPLMIGO:0112/ctxtGOHEAD-BLDAT").Text = Day(Date) & "." & Month(Date) & "." & Year(Date) Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_HEADER:SAPLMIGO:0101/subSUB_HEADER:SAPLMIGO:0100/tabsTS_GOHEAD/tabpOK_GOHEAD_GENERAL/ssubSUB_TS_GOHEAD_GENERAL:SAPLMIGO:0112/ctxtGOHEAD-BUDAT").Text = Day(Date) & "." & Month(Date) & "." & Year(Date) Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_HEADER:SAPLMIGO:0101/subSUB_HEADER:SAPLMIGO:0100/tabsTS_GOHEAD/tabpOK_GOHEAD_GENERAL/ssubSUB_TS_GOHEAD_GENERAL:SAPLMIGO:0112/ctxtGOHEAD-BUDAT").SetFocus Session.FindById("wnd[0]/usr/ssubSUB_MAIN_CARRIER:SAPLMIGO:" & migoMainScreenId & "/subSUB_HEADER:SAPLMIGO:0101/subSUB_HEADER:SAPLMIGO:0100/tabsTS_GOHEAD/tabpOK_GOHEAD_GENERAL/ssubSUB_TS_GOHEAD_GENERAL:SAPLMIGO:0112/ctxtGOHEAD-BUDAT").caretPosition = 10 ' 执行过账 Session.FindById("wnd[0]/tbar[1]/btn[7]").press Session.FindById("wnd[1]/tbar[0]/btn[0]").press Session.FindById("wnd[0]").sendVKey 0 End Sub ' 获取MIGO主容器动态ID的辅助函数 Function GetMigoMainSubScreenId(Session As Object) As String Dim subscreens As Object Dim subscreen As Object Set subscreens = Session.ActiveWindow.FindAllByName("ssubSUB_MAIN_CARRIER", "GuiSubScreen") For Each subscreen In subscreens If subscreen.Program = "SAPLMIGO" Then GetMigoMainSubScreenId = Split(subscreen.Id, ":")(2) Exit Function End If Next subscreen ' 未找到时返回默认值,可根据实际场景调整 GetMigoMainSubScreenId = "0003" End Function
关键注意事项
- 每次执行会触发屏幕切换的操作(如
sendVKey、press)后,必须重新调用GetMigoMainSubScreenId获取最新的动态ID - 可添加错误处理逻辑(如
On Error Resume Next+控件存在性检查),避免因SAP响应延迟导致的控件找不到问题 - 确保SAP GUI已启用脚本支持:打开SAP GUI选项→「脚本设置」→勾选「启用脚本」
内容的提问来源于stack exchange,提问作者mick5003
相关产品推荐
相关产品推荐

