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

使用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

关键修改点

  1. 修正参数类型:将SPOOL_LIST从.Imports改为.Tables引用,匹配BAPI的参数定义;
  2. 补充SESSION_ID:调用BAPI_XBP_GET_SPOOL_AS_DAT和BAPI_XMI_LOGOFF时传入登录获取的SESSION_ID,确保权限验证通过;
  3. 安全类型转换:用CLng()替代*1完成字符串转长整型,避免潜在的类型错误;
  4. 正确遍历数据:通过RowCount获取内容行数,按字段名LINE读取每行假脱机数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:01:00