32位Excel VBA上传SAP销售订单代码在64位SAP GUI7.70报对象断开错误
报错信息:运行时错误 '-2147417848 (80010108)':自动化错误 被调用的对象已与其客户端断开连接
报错行:sap_sales_order = boOrder.SalesDocument
该错误本质是SAP COM对象在调用CreateFromDat2方法后被提前释放,或属性读取时对象指针异常,按以下步骤排查:
第一步:优先校验BAPI执行返回值,拦截执行错误
你当前的代码是调用完BAPI后直接读取返回的销售订单号,若BAPI执行过程中抛出E/A类错误,SAP会直接释放boOrder对象,导致后续读取属性报错。需在调用完CreateFromDat2后立刻遍历返回参数oReturn,先拦截业务错误:' 调用CreateFromDat2后新增以下逻辑 Dim retItem As Object bError = False For Each retItem In oReturn If retItem.Type = "E" Or retItem.Type = "A" Then Debug.Print "BAPI执行错误:" & retItem.Message bError = True Exit For End If Next If bError Then GoTo ErrHandler ' 直接跳转到错误处理,不要继续读取属性第二步:补全BAPI事务提交逻辑
64位SAP GUI的BAPI运行机制和32位有差异,创建类BAPI执行完成后如果没有显式提交事务,SAP会在方法调用结束后自动释放业务对象,导致无法读取返回的订单号。需在确认BAPI无返回错误后,先调用BAPI_TRANSACTION_COMMIT提交事务,再读取SalesDocument属性:' 无错误时先提交事务 Dim oBapiCommit As Object Set oBapiCommit = sapFunc.Add("BAPI_TRANSACTION_COMMIT") oBapiCommit.Exports("WAIT") = "X" oBapiCommit.Call ' 提交完成后再读取订单号 sap_sales_order = boOrder.SalesDocument第三步:检查64位VBA兼容配置
- 确认所有VBA中的API声明已添加
PtrSafe关键字,所有指针类型、句柄类型的变量从Long改为LongPtr,避免32位遗留代码导致指针截断 - 确认VBA引用的4个SAP DLL均为64位版本,路径为
C:\Program Files\SAP\FrontEnd\SAPgui下的文件,未引用C:\Program Files (x86)下的32位遗留DLL,可先取消所有SAP相关引用后重新添加,避免缓存错误 - 检查SAP GUI安装时是否勾选了「Scripting」组件,7.70 64位默认不安装该组件,会导致COM对象调用异常,可重新运行SAP GUI安装包补装该组件
- 确认所有VBA中的API声明已添加
第四步:调整属性读取逻辑适配异步调用
64位COM调用存在异步延迟,部分场景下CreateFromDat2执行完成后,SalesDocument属性还未完成赋值,此时读取会触发对象断连错误,可添加重试+延迟逻辑解决:Dim retryTimes As Integer retryTimes = 0 On Error Resume Next Do Err.Clear DoEvents ' 释放控制权给SAP完成属性赋值 sap_sales_order = boOrder.SalesDocument retryTimes = retryTimes + 1 Loop Until Err.Number = 0 Or retryTimes >= 3 On Error GoTo 0 If Err.Number <> 0 Then bError = True Debug.Print "读取销售订单号失败:" & Err.Description End If第五步:检查SAP GUI安全配置
打开SAP GUI选项->安全->安全设置,将安全级别调整为「低」,或将当前Excel文件路径加入信任列表,避免SAP GUI的脚本拦截机制主动断开COM对象连接。
内容的提问来源于stack exchange,提问作者Tim

