You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SAP Gui Scripting循环异常:IW31工单创建脚本仅执行首行

问题排查与修正方案

核心问题分析

你的脚本仅执行首行就终止,主要由以下几个原因导致:

1. 行数计算逻辑缺陷

Rowmax = Rng.End(xlDown).Row - Rng.Row 依赖xlDown定位最后一行,若A列数据中间存在空行,会错误截断有效行数,导致循环提前结束。此外Rowmax未声明变量,可能引发隐式类型错误。

2. 未处理SAP弹窗异常

部分行数据处理时可能不会弹出确认窗口(wnd[1]),直接执行Session.findById("wnd[1]/tbar[0]/btn[0]").press会触发"找不到元素"错误,中断循环。

3. 缺乏错误捕获机制

任何单步操作失败(如SAP元素加载延迟、数据格式错误)都会直接终止脚本,无法继续后续行处理。

修正后的代码

Public SapGuiAuto, WScript, MsgCol
Public ObjGui As GuiApplication
Public ObjCon As GuiConnection
Public Session As GuiSession

Sub WOCreate()
    'Connection to SAP
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
    
    Set SapGuiAuto = GetObject("SAPGUI")
    Set ObjGui = SapGuiAuto.GetScriptingEngine
    Set ObjCon = ObjGui.Children(0)
    Set Session = ObjCon.Children(0)
    
    ObjGui.AllowSystemMessages = False
    ObjGui.HistoryEnabled = False
    Session.findById("wnd[0]").maximize

    Dim Rng As Range
    Dim ActRng As Range
    Dim i As Long
    Dim Rowmax As Long ' 声明变量
    
    ' 正确计算有效行数:从A2开始到最后一行非空单元格
    Set ActRng = Sheets("Load").Range("A1")
    Rowmax = Sheets("Load").Cells(Sheets("Load").Rows.Count, "A").End(xlUp).Row - 1 ' A2到最后一行的行数
    
    On Error Resume Next ' 启用错误捕获
    For i = 1 To Rowmax 'Loop Starts
        Err.Clear ' 清除上一次错误
        
        ' 打开IW31事务
        Session.findById("wnd[0]/tbar[0]/okcd").Text = "/NIW31"
        Session.findById("wnd[0]").sendVKey 0
        If Err.Number <> 0 Then
            ActRng.Offset(i, 8).Value = "打开IW31失败: " & Err.Description
            GoTo NextRow ' 跳过当前行
        End If
        
        ' 填写工单类型
        Session.findById("wnd[0]/usr/ctxtAUFPAR-PM_AUFART").Text = ActRng.Offset(i, 0).Value
        If Err.Number <> 0 Then
            ActRng.Offset(i, 8).Value = "填写工单类型失败: " & Err.Description
            GoTo NextRow
        End If
        
        ' 填写功能位置
        Session.findById("wnd[0]/usr/subOBJECT:SAPLCOIH:7120/ctxtCAUFVD-TPLNR").Text = ActRng.Offset(i, 1).Value
        If Err.Number <> 0 Then
            ActRng.Offset(i, 8).Value = "填写功能位置失败: " & Err.Description
            GoTo NextRow
        End If
        
        ' 填写参考工单
        Session.findById("wnd[0]/usr/ctxtRC62C-REFNR").Text = ActRng.Offset(i, 2).Value
        If Err.Number <> 0 Then
            ActRng.Offset(i, 8).Value = "填写参考工单失败: " & Err.Description
            GoTo NextRow
        End If
        
        ' 勾选复制选项
        Session.findById("wnd[0]/usr/chkRC62C-FOLLOW_UP_ORDER").Selected = True
        Session.findById("wnd[0]/usr/chkRC62C-COPY_OPR").Selected = True
        Session.findById("wnd[0]/usr/chkRC62C-COPY_MAT").Selected = True
        Session.findById("wnd[0]/usr/chkRC62C-FOLLOW_UP_ORDER").SetFocus
        Session.findById("wnd[0]").sendVKey 0
        Session.findById("wnd[0]").sendVKey 0
        
        ' 设置优先级
        Session.findById("wnd[0]/usr/cmbCAUFVD-PRIOK").Key = "3"
        Session.findById("wnd[0]").sendVKey 0
        Session.findById("wnd[0]").sendVKey 0
        
        ' 填写描述文本
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/subSUB_KOPF:SAPLCOIH:1102/subSUB_TEXT:SAPLCOIH:1103/cntlLTEXT/shell").Text = ActRng.Offset(i, 3) & vbCr & vbCr
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/subSUB_KOPF:SAPLCOIH:1102/subSUB_TEXT:SAPLCOIH:1103/cntlLTEXT/shell").SetSelectionIndexes 28, 28
        
        ' 填写附加字段
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subHEADER:SAPLCOIH:0154/ctxtCAUFVD-INGPR").Text = ActRng.Offset(i, 4).Value
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subHEADER:SAPLCOIH:0154/ctxtCAUFVD-VAPLZ").Text = ActRng.Offset(i, 5).Value
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subHEADER:SAPLCOIH:0154/ctxtCAUFVD-ILART").Text = ActRng.Offset(i, 6).Value
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subTERM:SAPLCOIH:7300/ctxtCAUFVD-REVNR").Text = ActRng.Offset(i, 7).Value
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subTERM:SAPLCOIH:7300/ctxtCAUFVD-REVNR").SetFocus
        Session.findById("wnd[0]/usr/subSUB_ALL:SAPLCOIH:3001/ssubSUB_LEVEL:SAPLCOIH:1100/tabsTS_1100/tabpIHKZ/ssubSUB_AUFTRAG:SAPLCOIH:1120/subTERM:SAPLCOIH:7300/ctxtCAUFVD-REVNR").CaretPosition = 7
        
        ' 保存工单
        Session.findById("wnd[0]/tbar[0]/btn[11]").press
        If Err.Number <> 0 Then
            ActRng.Offset(i, 8).Value = "保存工单失败: " & Err.Description
            GoTo NextRow
        End If
        
        ' 处理确认弹窗(仅当窗口存在时)
        Err.Clear
        Session.findById("wnd[1]/tbar[0]/btn[0]").press
        If Err.Number <> 0 Then
            ' 无弹窗则忽略错误
        End If
        
        ' 记录状态消息
        ActRng.Offset(i, 8).Value = Session.findById("wnd[0]/sbar").Text
        
NextRow:
    Next i
    On Error GoTo 0 ' 关闭错误捕获
    
    MsgBox "Process Completed"
    
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
End Sub

关键优化点

  • 可靠的行数计算:改用Cells(Rows.Count, "A").End(xlUp)定位最后一行,不受中间空行影响。
  • 错误捕获与跳过机制:使用On Error Resume Next和Err.Clear捕获操作错误,记录错误信息并跳过当前行,确保循环继续执行。
  • 弹窗存在性判断:执行弹窗确认前先清除错误,若弹窗不存在则忽略错误,避免中断循环。
  • 变量声明:补全Rowmax变量声明,避免隐式类型错误。

内容的提问来源于stack exchange,提问作者Burak83

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:20:27