Skip to Content

Hello community,

I presented until now in the series “How to use actual SAPNetWeaver RFC Library with Pyhton” :

Here now an example how to read a table with the function module (FM) RFC_READ_TABLE. You need the file sapnwrfc.py from here – look at the end of the posting.

After the connection we get the function description of the FM, in our case RFC_READ_TABLE. We set the arguments QUERY_TABLE, in our case USR01, and the DELIMITER. We invoke the FM and print the result line by line. The result is in the DATA table, in the field WA.

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

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

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

TableName = "USR01"

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

  charBuffer = create_unicode_buffer(512 + 1)

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

      rc = SAP.RfcSetChars(hFunc, "QUERY_TABLE", TableName, \
        len(TableName), RfcErrInf)
      rc = SAP.RfcSetChars(hFunc, "DELIMITER", "~", 1, RfcErrInf)

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

        hTable = c_void_p(0)
        if SAP.RfcGetTable(hFunc, "DATA", 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, "WA", charBuffer, 512, RfcErrInf)
            print(charBuffer.value)
            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)

del SAP

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

2017/04/24: I check the method above with Python release 3.6.1 x64 and with the SAP NetWeaver RFC library 721 PL42 x64 and it works perfect.

Cheers
Stefan

To report this post you need to login first.

7 Comments

You must be Logged on to comment or reply to a post.

  1. Davis Han

    Hi Stefan,

    It’s nice meet another pythoner in this community(recently I’m studaying PyRFC from Srdjan Boskovi).

    As new comer,would you please explain more detail in your RFC_READ_TABLE,especially how to define fields that I want to load.I have try to FIELDS=[‘fields1′,’fields2′,’fields2’] and FIELDS=[[‘fields1’],[‘fields2’],[‘fields2’]],neither successe.

    Best regards.

    Davis Han

    (0) 
    1. Stefan Schnell Post author

      Hello Davis,

      thanks for your reply. I am a newbie in Python, this is my really first Project – except this.

      The FM RFC_READ_TABLE has the following Interface:

      FUNCTION RFC_READ_TABLE.
      *"----------------------------------------------------------------------
      *"*"Local Interface:
      *"  IMPORTING
      *"     VALUE(QUERY_TABLE) LIKE  DD02L-TABNAME
      *"     VALUE(DELIMITER) LIKE  SONV-FLAG DEFAULT SPACE
      *"     VALUE(NO_DATA) LIKE  SONV-FLAG DEFAULT SPACE
      *"     VALUE(ROWSKIPS) LIKE  SOID-ACCNT DEFAULT 0
      *"     VALUE(ROWCOUNT) LIKE  SOID-ACCNT DEFAULT 0
      *"  TABLES
      *"      OPTIONS STRUCTURE  RFC_DB_OPT
      *"      FIELDS STRUCTURE  RFC_DB_FLD
      *"      DATA STRUCTURE  TAB512
      *"  EXCEPTIONS
      *"      TABLE_NOT_AVAILABLE
      *"      TABLE_WITHOUT_DATA
      *"      OPTION_NOT_VALID
      *"      FIELD_NOT_VALID
      *"      NOT_AUTHORIZED
      *"      DATA_BUFFER_EXCEEDED
      *"----------------------------------------------------------------------
      

      With RfcGetFunctionDesc you get the handle to the function description. Now you create with the RfcCreateFunction a data container. So you have access to the fields and tables of the interface. E.g. you can set the import parameter direct via RfcSetChars or you can get via RfcGetTable a data container to a table of the interface. With RfcAppendRow you can add an empty line and with RfcSetChars you can set the fields. On this way you can set each part of the interface of a FM. If you have a definite FM, we can explicate this example.

      Cheers

      Stefan

      (0) 
      1. Davis Han

        Hi Stefan,

        Thanks for so prompt response.

        I think I’v found what I want in PyRFC:

        connecton.call(‘RFC_READ_TABLE’,QUERY_TABLE=’LFA1′,FIELDS=[{‘FIELDNAME’:’MANDT’},{‘FIELDNAME’:’LAND1′}]) .

        Thanks again for you work.

        Regards

        Davis Han

        (0) 
  2. RAMESH BABU A

    Hi Stefan,

    Hope you are doing well 🙂

    Thank you for this post and I perceived that you have used the table – “USR01” which holds number of fields in single digit. If I am using the tables like “BUT000” which holds 50+ fields, the script is not extracting the data. I believe that we need to adjust the memory buffer value in “RfcGetChars” function, but this is not helping me. Could you please recommend a way to grip more records.

    Regards

    Ramesh

    (0) 
    1. Stefan Schnell Post author

      Hello Ramesh,

      thanks for your reply.

      The table BUT000 has 86 fields with a length of 1131. The function module RFC_READ_TABLE allows a maximum of 512 characters. If you call the function module with the table BUT000 you must get an DATA_BUFFER_EXCEEDED exception. You can find here a solution with an extended function module how to get 8192 characters – search for Z_RFC_READ_TABLE. The solution is over six years old, but it still works.

      Cheers

      Stefan

      (0) 
      1. RAMESH BABU A

        Good Day Stefan,

        Thank you for the clarification and its awesome.


        Now I got a condition, where I need to extract few fields like BPEXT, PARTNER, PERSNUMBER from BUT000, but the field BPEXT(Datatype – CHAR20) is passing null value and other fields are populating the values well.

        Even I tried to do the data type conversion in SAP and tried to import using RfcGetChars command, but no luck. Could you please suggest a solution for this.

        Below is the statement which I am using:

        hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, “MY Function Module”, RfcErrInf)

        if hFuncDesc != 0:

        hFunc = SAP.RfcCreateFunction(hFuncDesc, RfcErrInf)

        if hFunc != 0:

        rc = SAP.RfcSetChars(hFunc, “IV_ACCOUNT”, acc_num, len(acc_num), RfcErrInf)

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

        rc = SAP.RfcGetChars(hFunc, “EV_ACCOUNT”, Export, 256, RfcErrInf) # This line is passing the values well

        rc = SAP.RfcGetChars(hFunc, “EV_IBT”, Export1, 256, RfcErrInf) # This line is passing the null values

        rc = SAP.RfcGetChars(hFunc, “EV_SALES_PROD”, Export, 256, RfcErrInf) # This line is passing the values well


        Regards

        Ramesh

        (0) 
        1. Stefan Schnell Post author

          Hello Ramesh,

          I tried it with the following RFC-enabled function module:

          FUNCTION Z_BUT000
            IMPORTING
              VALUE(I_PARTNER) TYPE BU_PARTNER
            EXPORTING
              VALUE(E_BPEXT) TYPE BU_BPEXT.
          
          SELECT SINGLE BPEXT FROM BUT000 INTO e_bpext WHERE partner = i_partner.
          
          ENDFUNCTION.

          and the following VBScript:

          '-Begin-----------------------------------------------------------------
          
            '-Directives----------------------------------------------------------
              Option Explicit
          
            '-Constants-----------------------------------------------------------
              Const RFC_OK = 0
          
            '-Variables-----------------------------------------------------------
              Dim SAP, hRFC, rc, hFuncDesc, hFunc, charBuffer
          
            '-Sub Main------------------------------------------------------------
              Sub Main()
          
                Set SAP = CreateObject("COMNWRFC")
                If Not IsObject(SAP) Then
                 Exit Sub
                End If
          
                hRFC = SAP.RfcOpenConnection("ASHOST=NSP, SYSNR=00, " & _
                  "CLIENT=001, USER=BCUSER")
                If hRFC = 0 Then
                  Set SAP = Nothing
                  Exit Sub
                End If
          
                hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_BUT000")
                If hFuncDesc = 0 Then
                  SAP.RfcCloseConnection(hRFC)
                  Set SAP = Nothing
                  Exit Sub
                End If
          
                hFunc = SAP.RfcCreateFunction(hFuncDesc)
                If hFunc = 0 Then
                  SAP.RfcCloseConnection(hRFC)
                  Set SAP = Nothing
                  Exit Sub
                End If
          
                rc = SAP.RfcSetChars(hFunc, "I_PARTNER", "4711004711")
          
                If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then
          
                  rc = SAP.RfcGetChars(hFunc, "E_BPEXT", charBuffer, 20)
                  MsgBox charBuffer
          
                End If
          
                rc = SAP.RfcDestroyFunction(hFunc)
                rc = SAP.RfcCloseConnection(hRFC)
                Set SAP = Nothing
          
              End Sub
          
            '-Main----------------------------------------------------------------
              Main
          
          '-End-------------------------------------------------------------------
          

          All works well and expected. I don’t what is wrong in your case.

          What delivers RfcGetChars as return code? Delivers the error info structure information?

          Let us know your results.

          Cheers

          Stefan

          (0) 

Leave a Reply