Skip to Content
Technical Articles
Author's profile photo Stefan Schnell

How to use actual SAP NetWeaver RFC Library with Python – Call ABAP Report

I presented until now in the series “How to use actual SAP NetWeaver RFC Library with Python”:

Here now an example how to execute an ABAP report and get the result back.

At first a very easy ABAP report:

"-Begin-----------------------------------------------------------------
  Program Z_TEST.

    Write: / 'Hello World'.

"-End-------------------------------------------------------------------

 

Now we need an RFC-enabled function module, which wraps the execution of the ABAP report and delivers the result back. We call the report via SUBMIT with the addition EXPORTING LIST TO MEMORY. Therewith the result of the report is put into memory. With the function modules LIST_FROM_MEMORY we get the list and with the function module LIST_TO_ASCI we convert it into a readable format.

FUNCTION Z_TEST.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  EXPORTING
*"     VALUE(E_TAB_LISTZEILE) TYPE  Z_TAB_LISTZEILE
*"----------------------------------------------------------------------
*" Z_TAB_LISTZEILE is a Table Type with the Line Type LISTZEILE
**----------------------------------------------------------------------

  DATA lt_abaplist TYPE STANDARD TABLE OF abaplist.
  DATA lt_listzeile TYPE STANDARD TABLE OF listzeile.

  SUBMIT z_test EXPORTING LIST TO MEMORY AND RETURN.

  CALL FUNCTION 'LIST_FROM_MEMORY'
    TABLES
      listobject = lt_abaplist
    EXCEPTIONS
      not_found  = 1
      OTHERS     = 2.
  IF sy-subrc = 0.

    CALL FUNCTION 'LIST_TO_ASCI'
      TABLES
        listasci = lt_listzeile
        listobject = lt_abaplist
      EXCEPTIONS
        Others     = 1.
    IF sy-subrc = 0.
      e_tab_listzeile = lt_listzeile.
    ENDIF.

  ENDIF.

ENDFUNCTION.

On this way it is possible to call this ABAP report via RFC from Python. We set the connection parameters, open a connection, get the function description from Z_TEST function module, create a function and invoke it. Now we get the result from E_TAB_LISTZEILE and print it line by line.

# -*- coding: iso-8859-15 -*-
#-Begin-----------------------------------------------------------------

#-Include---------------------------------------------------------------
FileName = "sapnwrfc.py"
exec(compile(open(FileName).read(), FileName, "exec"))

#-Sub Main--------------------------------------------------------------
def main():

  #-Connection parameters-----------------------------------------------
  RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "ABAP"
  RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "00"
  RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "001"
  RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "BCUSER"
  RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "minisap"

  hRFC = SAP.RfcOpenConnection(RfcConnParams, 5, RfcErrInf)
  if hRFC is not None:

    charBuffer = create_unicode_buffer(256 + 1)

    hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_TEST", RfcErrInf)
    if hFuncDesc != 0:
      hFunc = SAP.RfcCreateFunction(hFuncDesc, RfcErrInf)
      if hFunc != 0:
        if SAP.RfcInvoke(hRFC, hFunc, RfcErrInf) == RFC_OK:

          hTable = c_void_p(0)
          if SAP.RfcGetTable(hFunc, "E_TAB_LISTZEILE", hTable, \
            RfcErrInf) == RFC_OK:

            RowCount = c_ulong(0)
            rc = SAP.RfcGetRowCount(hTable, RowCount, RfcErrInf)
            rc = SAP.RfcMoveToFirstRow(hTable, RfcErrInf)
            for i in range(0, RowCount.value):
              hRow = SAP.RfcGetCurrentRow(hTable, RfcErrInf)
              rc = SAP.RfcGetChars(hRow, "ZEILE", charBuffer, 256, \
                RfcErrInf)
              print(charBuffer.value.rstrip())
              if i < RowCount.value:
                rc = SAP.RfcMoveToNextRow(hTable, RfcErrInf)

        rc = SAP.RfcDestroyFunction(hFunc, RfcErrInf)

    rc = SAP.RfcCloseConnection(hRFC, RfcErrInf)

  else:
    print(RfcErrInf.key)
    print(RfcErrInf.message)

#-Main------------------------------------------------------------------
if __name__ == "__main__":
  main()

#-End-------------------------------------------------------------------

 

/wp-content/uploads/2016/02/001_891947.jpg

Now you can easily use e.g. the report RSUSR002 – swap only the report names in the function module.

/wp-content/uploads/2016/02/002_891943.jpg

Here now a tiny addendum to fill the select options of the report RSUSR002.

At first the function module. I changed the interface, I add I_TAB_RSPARAMS and I add WITH SELECTION-TABLE to the SUBMIT command:

FUNCTION Z_TEST.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(I_TAB_RSPARAMS) TYPE  RSPARAMS_TT OPTIONAL
*"  EXPORTING
*"     VALUE(E_TAB_LISTZEILE) TYPE  Z_TAB_LISTZEILE
*"----------------------------------------------------------------------

  DATA lt_abaplist TYPE STANDARD TABLE OF abaplist.
  DATA lt_listzeile TYPE STANDARD TABLE OF listzeile.

  SUBMIT rsusr002 WITH SELECTION-TABLE i_tab_rsparams
    EXPORTING LIST TO MEMORY AND RETURN.

  CALL FUNCTION 'LIST_FROM_MEMORY'
    TABLES
      listobject = lt_abaplist
    EXCEPTIONS
      not_found  = 1
      OTHERS     = 2.
  IF sy-subrc = 0.

    CALL FUNCTION 'LIST_TO_ASCI'
      TABLES
        listasci   = lt_listzeile
        listobject = lt_abaplist
      EXCEPTIONS
        Others     = 1.
    IF sy-subrc = 0.
      e_tab_listzeile = lt_listzeile.
    ENDIF.

  ENDIF.

ENDFUNCTION.

Here now the changed Python program, with the new import parameter I_TAB_RSPARAMS.

# -*- coding: iso-8859-15 -*-
#-Begin-----------------------------------------------------------------

#-Imports---------------------------------------------------------------
import os, platform

#-Include---------------------------------------------------------------
FileName = "sapnwrfc.py"
exec(compile(open(FileName).read(), FileName, "exec"))

#-Sub Main--------------------------------------------------------------
def main():

  #-Connection parameters-----------------------------------------------
  RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "ABAP"
  RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "00"
  RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "001"
  RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "BCUSER"
  RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "minisap"

  hRFC = SAP.RfcOpenConnection(RfcConnParams, 5, RfcErrInf)
  if hRFC is not None:

    charBuffer = create_unicode_buffer(256 + 1)

    hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_TEST", RfcErrInf)
    if hFuncDesc != 0:
      hFunc = SAP.RfcCreateFunction(hFuncDesc, RfcErrInf)
      if hFunc != 0:

        hTable = c_void_p(0)
        if SAP.RfcGetTable(hFunc, "I_TAB_RSPARAMS", hTable, RfcErrInf) == RFC_OK:
          hRow = SAP.RfcAppendNewRow(hTable, RfcErrInf)
          rc = SAP.RfcSetChars(hRow, "SELNAME", "USER", 4, RfcErrInf)
          rc = SAP.RfcSetChars(hRow, "KIND", "S", 1, RfcErrInf)
          rc = SAP.RfcSetChars(hRow, "SIGN", "I", 1, RfcErrInf)
          rc = SAP.RfcSetChars(hRow, "OPTION", "EQ", 2, RfcErrInf)
          rc = SAP.RfcSetChars(hRow, "LOW", "BCUSER", 6, RfcErrInf)

        if SAP.RfcInvoke(hRFC, hFunc, RfcErrInf) == RFC_OK:

          if SAP.RfcGetTable(hFunc, "E_TAB_LISTZEILE", hTable, \
            RfcErrInf) == RFC_OK:

            RowCount = c_ulong(0)
            rc = SAP.RfcGetRowCount(hTable, RowCount, RfcErrInf)
            rc = SAP.RfcMoveToFirstRow(hTable, RfcErrInf)
            for i in range(0, RowCount.value):
              hRow = SAP.RfcGetCurrentRow(hTable, RfcErrInf)
              rc = SAP.RfcGetChars(hRow, "ZEILE", charBuffer, 256, \
                RfcErrInf)
              print(charBuffer.value.rstrip())
              if i < RowCount.value:
                rc = SAP.RfcMoveToNextRow(hTable, RfcErrInf)

        rc = SAP.RfcDestroyFunction(hFunc, RfcErrInf)

    rc = SAP.RfcCloseConnection(hRFC, RfcErrInf)

  else:
    print(RfcErrInf.key)
    print(RfcErrInf.message)

#-Main------------------------------------------------------------------
if __name__ == "__main__":
  print("Python", platform.python_version(), "on",
    platform.system(), "(" + platform.architecture()[0] + ")",
    end="\n\n")
  main()
  print("\n")
  os.system('pause')

#-End-------------------------------------------------------------------

And here the expecting result.

003.JPG

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.