excelvbaui-automationsap-guisaprfc

RFC_CALL_TRANSACTION_USING to print to spool using VBA


I'm trying to use RFC_CALL_TRANSACTION_USING to get the SAP ERP software to run the transaction code FTE_BSM and print the result of the report to spool.

The transaction I am trying to use is FTE_BSM, but in the end I want to use it with any transaction code that can print output to spool.

I connect to SAP using the following code:

    If iConnectionStatus <> 1 Then
        
            Set ObjR3 = CreateObject("SAP.Functions")
            Set ObjR3_Connection = ObjR3.Connection
            
            With ObjR3_Connection
                .System = SAP_SystemID 
                .SystemNumber = SAP_SystemNumber 
                .ApplicationServer = SAP_ApplicationServer
                .Client = SAP_Client 
                .USER = Environ("Username") 
                .password = UserPassword_Temp '
                .Language = SAP_Language 
            End With

            If ObjR3.Connection.Logon(1, False) <> True Then
                GoTo LogInFailed
                Exit Sub
            End If

            ObjR3_Connection.RFCWithDialog = 1
            Call GetIDFromSAP
        
        End If

In a separate routine, I call the RFC Function Module:

    Dim aExecutionMap As Variant

    aExecutionMap = ws_map_FTE_BSM.Range("mask_FTE_BSM").Value

    Set ObjR3_Call_RFC_Transaction = ObjR3.Add("RFC_CALL_TRANSACTION_USING")

        'Define SAP interal Tables
        With ObjR3_Call_RFC_Transaction
            .Exports("TCODE") = sReportName
            .Exports("MODE") = sMode
            Set ObjR3_Call_RFC_Para = .Tables("BT_DATA")
            Set ObjR3_Call_RFC_Errors = .Tables("L_ERRORS")
            
        End With
        
        'Load Map
        r = 0
        For i = LBound(aExecutionMap, 1) To UBound(aExecutionMap, 1)
            r = r + 1
            ObjR3_Call_RFC_Para.AppendRow
            
            c = 0
            For f = LBound(aExecutionMap, 2) To UBound(aExecutionMap, 2)
                c = c + 1
                ObjR3_Call_RFC_Para(r, c) = aExecutionMap(i, f)
            
            Next f
        Next i
        
        
        CallResult = False
        
        CallResult = ObjR3_Call_RFC_Transaction.Call

The aExecutionMap is an Array that is loaded from a named table range containing the rows of the BT_DATA table parameter as recorded using SAP's transaction SHDB. I recorded the transaction twice, once with "Simulate Background Mode" switched on, once with it switched off. This did not seem to make a difference.

In the "Simulate Background Mode" switched ON, the table is:

enter image description here

Note that an empty cell means that the field is left blank. Also, the date is in the same format as the dialog user would input it. For debugging, I looped through the BT_DATA table to double-check the parameters. The parameters are as follows:

Program Dynpro DynBegin FNam FVal
RFEBKAMON01 1000 X
0000 BDC_OKCODE =/BDA
0000 S_BUKRS-LOW 0105
0000 P_STDAT 2020.11.30
0000 P_VARI /STATMONI
SAPMSSY0 0120 X
0000 BDC_OKCODE =&RNT

In the "Simulate Background Mode" switched OFF, the table is:

enter image description here

The parameters sent to build the BT_DATA table:

Program Dynpro DynBegin FNam FVal
RFEBKAMON01 1000 X
0000 BDC_OKCODE =/BDA
0000 S_BUKRS-LOW 0105
0000 P_STDAT 2020.11.30
0000 P_VARI /STATMONI
SAPLSPRI 0100 X
0000 BDC_OKCODE =PRIN
0000 RADIO0500_1 X
0000 PRI_PARAMS-PRCOP 1
0000 BDC_SUBSCR SAPLSPRI 0600SUBSCREEN

I get a True result on the CallResult, so I do get Excel to communicate with SAP, however, I get errors as well and the spooljob is never created.

I get errors regardless of whether I run the transaction using .Exports("MODE") = "N" or .Exports("MODE") = "E" or .Exports("MODE") = "A":

TCODE DYNAME DYNUMB MSGTYP MSGSPRA MSGID MSGNR MSGV1
FTE_BSM RFEBKAMON01 1010 A E 00 341 RAISE_EXCEPTION

or:

TCODE DYNAME DYNUMB MSGTYP MSGSPRA MSGID MSGNR MSGV1
FTE_BSM SAPMSSY0 1000 A E 00 341 DYNPRO_SEND_IN_BACKGROUND

Examining the errors in ST22 gives me

If run in "N" mode

RAISE_EXCEPTION CL_GUI_CUSTOM_CONTAINER=======CP

or

If run in "E" or "A" mode

DYNPRO_SEND_IN_BACKGROUND CX_SY_SEND_DYNPRO_NO_RECEIVER RFEBKAMON01

How do I run an SAP transaction with RFC_CALL_TRANSACTION_USING and save the results to spool?


Solution

  • There are 3 big questions here which would each deserve a separate question so that to benefit detailed answers:

    I explain more about how FTE_BSM works and how to run it via Batch Input. I can't go in depth how Batch Input works and how to extract spool data by RFC, if you need more help on one of these two, please ask another question.

    You are running the function module RFC_CALL_TRANSACTION_USING through Excel VBA and the RFC Client included in SAP GUI for Windows (used to display the Dynpro screens), but your issue is only due to the automation data passed to the parameter BT_DATA, that is specific to the transaction code FTE_BSM.

    The so-called Transaction Codes all run (99%) in Dynpro technology / ABAP, and consequently the user actions can usually be recorded using the Transaction Recorder (Transaction Code SHDB) and played using the function module RFC_CALL_TRANSACTION_USING and more specifically the underlying ABAP statement CALL TRANSACTION ... USING .... This UI automation is officially called Batch Input. There are lots of limitations depending on the exact Dynpro and ABAP logic in each Transaction Code. You need good knowledge of Dynpro and ABAP to understand all subtleties.

    In the Transaction Recorder, the option "Simulate background mode" is to simulate a Transaction Code running in background, technically speaking it sets the System Field (kind of environment variable) sy-batch = 'X', the ABAP code may or may not consider this field to display screens so that to permit Batch Input. If a recording is done while using the "Simulate background mode", this recording must be played using an adequate mode which also simulates the background mode:

    Mode sy-batch = ' ' sy-batch = 'X' ("Simulate background")
    No screen N Q
    Show screens starting from error E H
    Show all screens A D

    When a user runs FTE_BSM without automation, there are the following screens:

    If the user actions are recorded via the Transaction Recorder, I obtain these values for BT_DATA:

    Batch input will work if you use:

    You need to run other RFC-enabled function modules to extract the spool data. I advise using XBP because BAPI are officially-supported API = function modules BAPI_XMI_LOGON with parameter INTERFACE = 'XBP', BAPI_XBP_JOB_SPOOLLIST_READ if the spool request is generated from a background job or BAPI_XBP_GET_SPOOL_AS_DAT if you have only the spool request number, and BAPI_XMI_LOGOFF.

    Although your question is not about ABAP, I provide here an example which works for me in ABAP:

    REPORT.
    DATA(tbl) = VALUE bdcdata_tab(
      ( program = 'RFEBKAMON01' dynpro = '1000' dynbegin = 'X' fnam = '' fval = '' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'BDC_OKCODE' fval = 'ONLI' )
      ( program = 'SAPMSSY0' dynpro = '0120' dynbegin = 'X' fnam = '' fval = '' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'BDC_OKCODE' fval = '=%PRI' )
      ( program = 'SAPLSPRI' dynpro = '0100' dynbegin = 'X' fnam = '' fval = '' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'BDC_OKCODE' fval = '=PRIN' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'PRI_PARAMS-PDEST' fval = 'LP01' )
      ( program = 'SAPMSSY0' dynpro = '0120' dynbegin = 'X' fnam = '' fval = '' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'BDC_OKCODE' fval = '=&F03' )
      ( program = 'RFEBKAMON01' dynpro = '1000' dynbegin = 'X' fnam = '' fval = '' )
      ( program = '' dynpro = '0000' dynbegin = '' fnam = 'BDC_OKCODE' fval = '/EE' )
        ).
    DATA(bdcmsgcoll_tab) = VALUE tab_bdcmsgcoll( ).
    CALL TRANSACTION 'FTE_BSM' USING tbl MODE 'Q' MESSAGES INTO bdcmsgcoll_tab.