VBA调用SAP GUI Scripting运行时新建会话异常问题
问题背景
- 目标需求:编写可在当前SAP会话处于事务运行状态时,正常打开同连接下新SAP会话的VBA宏脚本
- 现存缺陷:原有宏仅能在SAP会话处于空闲状态下成功新建会话,当当前会话正在执行事务(如点击执行按钮后的事务处理阶段),新建会话逻辑失效
- 原有实现代码:
Private Sub nextSession() Dim nSessions As Integer Set SapGuiAuto = GetObject("SAPGUI") Set SAPApp = SapGuiAuto.GetScriptingEngine Set sapCon = SAPApp.Children(0) Set session = sapCon.Children(0) nSessions = sapCon.Sessions.Count session.CreateSession Do Application.Wait (Now() + 500 * ms) If sapCon.Sessions.Count > nSessions Then Exit Do Loop Set sapSession = sapCon.Sessions.Item(CInt(sapCon.Sessions.Count - 1)) End Sub
失效原因
原有代码调用的是GuiSession对象的CreateSession方法,该方法会进入当前会话的执行队列:当会话处于事务运行的忙状态时,所有对该会话对象的脚本调用都会被阻塞,直到当前事务执行完毕才会触发新建会话逻辑,因此无法在事务运行过程中创建新会话。
同时原有代码存在两个隐性问题:
- 时间变量
ms未定义,实际等待时长参数无效,容易出现循环判断逻辑异常 - 未校验新会话的加载状态,可能拿到未完成初始化的无效会话对象
修正后代码
直接调用GuiConnection对象层面的CreateSession方法,该方法属于连接层接口,不依赖单个会话的空闲状态,不会被运行中的事务阻塞,同时补全等待逻辑和状态校验:
Option Explicit ' 等待时间常量,1秒对应的VBA时间序列值 Const WAIT_INTERVAL As Double = 1 / 24 / 60 / 60 Const MAX_WAIT_SECONDS As Integer = 10 Private Sub nextSession() Dim SapGuiAuto As Object Dim SAPApp As Object Dim sapCon As Object Dim sapSession As Object Dim nSessions As Integer Dim waitCount As Integer ' 绑定SAP GUI基础对象 Set SapGuiAuto = GetObject("SAPGUI") Set SAPApp = SapGuiAuto.GetScriptingEngine Set sapCon = SAPApp.Children(0) ' 记录操作前的会话总数 nSessions = sapCon.Sessions.Count ' 调用连接层方法创建新会话,绕开单会话的事务阻塞 sapCon.CreateSession ' 等待新会话条目生成 waitCount = 0 Do Application.Wait Now + WAIT_INTERVAL waitCount = waitCount + 1 ' 超时判断,避免死循环 If waitCount > MAX_WAIT_SECONDS Then Err.Raise vbObjectError + 1001, , "新建SAP会话超时,请检查SAP连接状态" End If Loop Until sapCon.Sessions.Count > nSessions ' 绑定新会话并等待初始化完成 Set sapSession = sapCon.Sessions(sapCon.Sessions.Count - 1) waitCount = 0 Do Application.Wait Now + WAIT_INTERVAL waitCount = waitCount + 1 If waitCount > MAX_WAIT_SECONDS Then Err.Raise vbObjectError + 1002, , "新SAP会话初始化超时" End If Loop Until sapSession.Busy = False And sapSession.Children.Count > 0 ' 后续逻辑可直接操作sapSession对象控制新会话 End Sub
关键修改说明
- 替换新建会话的调用主体:从原有的忙会话对象
sapCon.Children(0).CreateSession改为连接对象sapCon.CreateSession,绕开单会话的执行队列阻塞 - 移除未定义的
ms变量,使用明确的时间常量控制等待间隔,同时增加超时判断,避免无限循环 - 增加新会话初始化校验逻辑,等新会话完全加载、退出忙状态后再完成绑定,避免后续脚本操作报错
内容的提问来源于stack exchange,提问作者Grzegorz
相关产品推荐
相关产品推荐

