Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor


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

 



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



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.