使用BAPI_XBP_GET_SPOOL_AS_DAT从SAP假脱机提取数据至Excel遇阻求助
从SAP假脱机作业提取数据的VBA代码问题
问题场景
我正在构建交互式Excel模板,通过BAPI从SAP假脱机作业提取数据,执行流程如下:
- 调用
RFC_CALL_TRANSACTION_USING执行事务码,将结果输出至假脱机并获取作业编号; - 通过
BAPI_XMI_LOGON登录XBP接口,已成功获取有效SESSION_ID; - 基于步骤1的编号调用
BAPI_XBP_GET_SPOOL_AS_DAT提取假脱机内容,调用成功但无法获取内容,.Tables("SPOOL_LIST").RowCount报“438对象不支持该属性或方法”错误; - 通过
BAPI_XMI_LOGOFF注销XBP接口,已成功; - 通过
RSPO_R_RDELETE_SPOOLREQ删除假脱机作业,已成功。
已测试RFC_Excel和SAP用户ID两种外部用户名,确认无权限问题,调整后的VBA代码如下:
Sub SAP_Spool_Job_Read_From_SAP(sSpoolJobNo As String) CallResult = False If sSpoolJobNo = "0" Then Exit Sub Dim sExternalUserName As String Dim ObjR3_RFC_Spool_LogOn As Object Dim ObjR3_RFC_Spool_LogOff As Object Dim ObjR3_RFC_Spool_GetData As Object Dim sFilePath As String Dim lSpoolJobNo As Long Dim oSpoolOutput As Object Dim oSpoolErrors As Object Dim sXBP_SessionID As String Dim sXBP_Message As String Dim oXBP_Status As Object sExternalUserName = "RFC_Excel" lSpoolJobNo = sSpoolJobNo * 1 ObjR3_Connection.RFCWithDialog = 1 Set ObjR3_RFC_Spool_LogOn = ObjR3.Add("BAPI_XMI_LOGON") 'Log onto the XBP interface With ObjR3_RFC_Spool_LogOn .Exports("EXTCOMPANY") = sExternalUserName .Exports("EXTPRODUCT") = sExternalUserName .Exports("INTERFACE") = "XBP" .Exports("VERSION") = "3.0" End With CallResult = False sXBP_SessionID = "?" sXBP_Message = "Pending..." CallResult = ObjR3_RFC_Spool_LogOn.Call 'Check if XBP logon was successful If CallResult = True Then sXBP_SessionID = ObjR3_RFC_Spool_LogOn.Imports("SESSIONID").Value Debug.Print "ObjR3_RFC_Spool_LogOn: " & CallResult Debug.Print "ObjR3_RFC_Spool_LogOn: " & ObjR3_RFC_Spool_LogOn Debug.Print "Session ID: " & sXBP_SessionID Debug.Print ObjR3_RFC_Spool_LogOn.Imports("RETURN").Value Else Exit Sub End If 'Get Data from Spool content from SAP Set ObjR3_RFC_Spool_GetData = ObjR3.Add("BAPI_XBP_GET_SPOOL_AS_DAT") Debug.Print lSpoolJobNo With ObjR3_RFC_Spool_GetData .Exports("SPOOL_REQUEST") = lSpoolJobNo .Exports("EXTERNAL_USER_NAME") = sExternalUserName .Exports("FIRST_PAGE") = 0 .Exports("LAST_PAGE") = 0 Set oSpoolOutput = .Imports("SPOOL_LIST") Set oSpoolErrors = .Imports("RETURN") End With CallResult = False 'Call Request in SAP CallResult = ObjR3_RFC_Spool_GetData.Call If CallResult = True Then Debug.Print ObjR3_RFC_Spool_GetData.Exports("SPOOL_REQUEST") Debug.Print "ObjR3_RFC_Spool_GetData: " & CallResult Debug.Print oSpoolErrors.Value Debug.Print "Content: " & vbNewLine & oSpoolOutput Else GoTo LogOffXMI End If LogOffXMI: Set ObjR3_RFC_Spool_LogOff = ObjR3.Add("BAPI_XMI_LOGOFF") With ObjR3_RFC_Spool_LogOff .Exports("INTERFACE") = "XBP" End With CallResult = ObjR3_RFC_Spool_LogOff.Call If CallResult = True Then Debug.Print "ObjR3_RFC_Spool_LogOff: " & CallResult Debug.Print ObjR3_RFC_Spool_LogOff.Imports("RETURN").Value Else Exit Sub End If End Sub
问题原因与解决方案
核心问题
BAPI_XBP_GET_SPOOL_AS_DAT中的SPOOL_LIST是Tables类型参数,而非Imports参数,你当前代码错误地将其当作Imports引用,触发属性不支持的438错误;同时调用该BAPI和注销接口时,遗漏了XBP登录后获取的SESSION_ID,这是权限验证和数据返回的必要参数。
修改后的代码
Sub SAP_Spool_Job_Read_From_SAP(sSpoolJobNo As String) Dim CallResult As Boolean CallResult = False If sSpoolJobNo = "0" Then Exit Sub Dim sExternalUserName As String Dim ObjR3_RFC_Spool_LogOn As Object Dim ObjR3_RFC_Spool_LogOff As Object Dim ObjR3_RFC_Spool_GetData As Object Dim lSpoolJobNo As Long Dim oSpoolTable As Object Dim oReturn As Object Dim rowCount As Long Dim i As Long Dim sXBP_SessionID As String sExternalUserName = "RFC_Excel" lSpoolJobNo = CLng(sSpoolJobNo) ObjR3_Connection.RFCWithDialog = 1 ' XBP登录 Set ObjR3_RFC_Spool_LogOn = ObjR3.Add("BAPI_XMI_LOGON") With ObjR3_RFC_Spool_LogOn .Exports("EXTCOMPANY") = sExternalUserName .Exports("EXTPRODUCT") = sExternalUserName .Exports("INTERFACE") = "XBP" .Exports("VERSION") = "3.0" End With CallResult = ObjR3_RFC_Spool_LogOn.Call If CallResult = True Then sXBP_SessionID = ObjR3_RFC_Spool_LogOn.Imports("SESSIONID").Value Debug.Print "XBP登录成功,Session ID: " & sXBP_SessionID Debug.Print "登录返回信息: " & ObjR3_RFC_Spool_LogOn.Imports("RETURN").Value Else Debug.Print "XBP登录失败" Exit Sub End If ' 提取假脱机数据 Set ObjR3_RFC_Spool_GetData = ObjR3.Add("BAPI_XBP_GET_SPOOL_AS_DAT") With ObjR3_RFC_Spool_GetData .Exports("SPOOL_REQUEST") = lSpoolJobNo .Exports("EXTERNAL_USER_NAME") = sExternalUserName .Exports("SESSION_ID") = sXBP_SessionID ' 新增:传入Session ID .Exports("FIRST_PAGE") = 0 .Exports("LAST_PAGE") = 0 Set oSpoolTable = .Tables("SPOOL_LIST") ' 改为引用Tables参数 Set oReturn = .Imports("RETURN") End With CallResult = ObjR3_RFC_Spool_GetData.Call If CallResult = True Then Debug.Print "假脱机数据提取成功" Debug.Print "返回信息: " & oReturn.Value ' 获取行数并遍历内容 rowCount = oSpoolTable.RowCount Debug.Print "假脱机内容行数: " & rowCount If rowCount > 0 Then Debug.Print "假脱机内容:" For i = 1 To rowCount Debug.Print oSpoolTable(i, "LINE").Value ' 读取每行的LINE字段 Next i End If Else Debug.Print "假脱机数据提取失败" GoTo LogOffXMI End If LogOffXMI: ' XBP注销 Set ObjR3_RFC_Spool_LogOff = ObjR3.Add("BAPI_XMI_LOGOFF") With ObjR3_RFC_Spool_LogOff .Exports("INTERFACE") = "XBP" .Exports("SESSION_ID") = sXBP_SessionID ' 注销需传入Session ID End With CallResult = ObjR3_RFC_Spool_LogOff.Call If CallResult = True Then Debug.Print "XBP注销成功" Debug.Print "注销返回信息: " & ObjR3_RFC_Spool_LogOff.Imports("RETURN").Value Else Debug.Print "XBP注销失败" End If End Sub
关键修改点
- 修正参数类型:将
SPOOL_LIST从.Imports改为.Tables引用,匹配BAPI的参数定义; - 补充SESSION_ID:调用
BAPI_XBP_GET_SPOOL_AS_DAT和BAPI_XMI_LOGOFF时传入登录获取的SESSION_ID,确保权限验证通过; - 安全类型转换:用
CLng()替代*1完成字符串转长整型,避免潜在的类型错误; - 正确遍历数据:通过
RowCount获取内容行数,按字段名LINE读取每行假脱机数据。
内容的提问来源于stack exchange,提问作者Tyro
相关产品推荐
相关产品推荐

