Skip to Content

Consider the below code for educational purposes only. Avoid using RFC_READ_TABLE as it’s not released by SAP – see note 382318 – FAQ|Function module RFC_READ_TABLE.

Find below a simple RFC_READ_TABLE call using the SAP .net connector 3.x

ReadTable(“PR1”, “MARA”, “MATNR,MTART,MATKL”, “MTART EQ ‘HAWA'”, rows);

where “PR1” – destination system

     “MARA” – string, table to query

     “MATNR,xxx” – string, coma separated column names. If empty “”, then all table fields are retrieved.

     “MTART EQ ‘HAWA'” – string, WHERE clause in ABAP SQL syntax

     rows – output variable, list of strings to hold the result table rows. Columns delimited by “~”

Current limitation: in the below version of the code, the filter can be only upto 72 characters long. If you need longer, I suggest to involve a word wrapping function like this one: http://bryan.reynoldslive.com/post/Wrapping-string-data.aspx


        public bool ReadTable(string dest, string table, string fields, string filter, out List<string> rows) {
            string[] field_names = fields.Split(",".ToCharArray());
          
            RfcDestination destination = RfcDestinationManager.GetDestination(dest);
            IRfcFunction readTable;
            try {
                readTable = destination.Repository.CreateFunction("BBP_RFC_READ_TABLE");
            } catch (RfcBaseException ex) {
                //Log.Error(String.Format("\nError in function module RFC_READ_TABLE ({0})", ex.Message));
                rows = null;
                return false;
            }
            readTable.SetValue("query_table", table);
            readTable.SetValue("delimiter", "~");
            IRfcTable t = readTable.GetTable("DATA");
            t.Clear();
            t = readTable.GetTable("FIELDS");
            t.Clear();
            if (field_names.Length > 0) {
                t.Append(field_names.Length);
                int i = 0;
                foreach (string n in field_names) {
                    t.CurrentIndex = i++;
                    t.SetValue(0, n);
                }
            }
            t = readTable.GetTable("OPTIONS");
            t.Clear();
            t.Append(1);
            t.CurrentIndex = 0;
            t.SetValue(0, filter);
            //Log.Debug(string.Format("SELECT {0} FROM {1} WHERE {2}",
            //    fields, table, filter));
            readTable.Invoke(destination);
            t = readTable.GetTable("DATA");
            int a = t.Count;
            rows = new List<string>();
            for (int i = 0; i < t.RowCount; i++) {
                t.CurrentIndex = i;
                rows.Add(t.GetString(0));
            }
            return true;
        }

To report this post you need to login first.

9 Comments

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

  1. Hynek Petrak Post author

    I have updated the above function for the possibility to retrieve all the table fields. For that call the function with fields = “”:

    ReadTable(“PR1”, “MARA”, “”, “MTART EQ ‘HAWA'”, rows);

    (0) 
  2. T. Slijpen

    Hi Hynek,


    Referring to RFC_READ_TABLES


    When I try to download a table from DD03M tabname = “PA0001” (selecting no fields so all fields selected then I get an error


    DATA_BUFFER_EXCEEDED


    I think that the returned string will be more than 512 char.

    How can I solve this?


    Thanks

    Ton

    (0) 
    1. T. Slijpen

      Hi Hynek

      Here is my code

      Dim QUERY_TABLE As Object

                  Dim DELIMITER As Object

                  Dim NO_DATA As Object

                  Dim ROWSKIPS As Object

                  Dim ROWCOUNT As Object

                  ‘Dim COLUMNCOUNT As Object

                  ‘ Where clause

                  Dim OPTIONS As Object

                  ‘ Fill with fields to return.  After function call will hold

                  ‘ detailed information about the columns of data (start position

                  ‘ of each field, length, etc.

                  Dim FIELDS As Object

                  ‘ Holds the data returned by the function

                  Dim DATA As Object

                  ‘ Use to write out results

                  Dim ROW As Object

                  Dim Result As Boolean

                  Dim i As Long, j As Long, iRow As Long

                  Dim iColumn As Long, iStart As Long, iStartRow As Long, iField As Long, iLength As Long

                  Dim outArray, vArray, vField

                  Dim iLine As Long

                  Dim noOfElements As Long

                  ‘**********************************************

                  ‘Create Server object and Setup the connection

                  ‘use same credentials as SAP GUI login

                  ‘ On Error GoTo abend

                  R3 = CreateObject(“SAP.Functions”)

                  R3.Connection.SYSTEM = rtdetails.SapSystem

                  R3.Connection.Client = rtdetails.SapClient

                  R3.Connection.User = rtdetails.SapUser

                  R3.Connection.Password = rtdetails.SapPassword

                  R3.Connection.Language = “EN”

                  If R3.connection.logon(0, True) <> True Then

                      MessageBox.Show(“ERROR – logon to SAP failed”)

                      Exit Function

                  End If

                  MyFunc = R3.add(“BBP_RFC_READ_TABLE”)

                  QUERY_TABLE = MyFunc.exports(“QUERY_TABLE”)

                  DELIMITER = MyFunc.exports(“DELIMITER”)

                  NO_DATA = MyFunc.exports(“NO_DATA”)

                  ROWSKIPS = MyFunc.exports(“ROWSKIPS”)

                  ROWCOUNT = MyFunc.exports(“ROWCOUNT”)

                  OPTIONS = MyFunc.tables(“OPTIONS”)

               

                  QUERY_TABLE.Value = TABLE

                  DELIMITER.value = “”

                  NO_DATA = “”

                  ROWSKIPS = “0”

                  ROWCOUNT = “0”

                  OPTIONS.Rows.add()

                  OPTIONS.value(1, “TEXT”) = FILTER

                  Result = MyFunc.call

                  If Result = True Then

                      DATA = MyFunc.tables(“DATA”)

                      FIELDS = MyFunc.tables(“FIELDS”)

                      OPTIONS = MyFunc.tables(“OPTIONS”)

                      R3.Connection.LOGOFF()

                  Else

                      R3.Connection.LOGOFF()

                      MessageBox.Show(MyFunc.EXCEPTION)

                      Exit Function

                  End If

                  noOfElements = FIELDS.ROWCOUNT

                  iRow = 2

                  iColumn = 1

                  ReDim outArray(0 To DATA.ROWCOUNT, 0 To noOfElements – 1)

                  For Each ROW In FIELDS.Rows

                      xlsSheetTables.Cells(iRow, iColumn).value = ROW(“FIELDNAME”)

                      ‘outArray(iRow, iColumn) = ROW(“FIELDNAME”)

                      iColumn += 1

                  Next

                  Dim ColLetB As String = Replace(xlsSheetTables.Cells(2, noOfElements).Address(False, False), _

                                                xlsSheetTables.Cells(2, 2).Row, “”)

                  ColLetB = ColLetB & 2.ToString

                  rng = xlsSheetTables.Range(“A2:” & ColLetB)

                  rng.Font.Color = System.Drawing.Color.Blue

                  rng.Font.Size = 14

                  rng.Font.Bold = True

                  rng.EntireColumn.AutoFit()

                  ‘ Display Contents of the table 

                  ROW = 3

                  iColumn = 0

                  For Each ROW In FIELDS.rows

                      outArray(iRow, iColumn) = ROW(“FIELDNAME”)

                      iColumn += 1

                  Next

                  Dim map As String = “”

                  Dim okmap As Boolean = False

                  iRow = 3

                  iColumn = 1

                  Dim resultaat As String = “”

                  For iLine = 1 To DATA.ROWCOUNT

                      For iColumn = 1 To FIELDS.ROWCOUNT

                          iStart = FIELDS(iColumn, “OFFSET”) + 1

                          If iColumn = FIELDS.ROWCOUNT Then

                              iLength = (DATA(iLine, “WA”)).Length – iStart + 1

                          Else

                              iLength = FIELDS(iColumn + 1, “OFFSET”) – FIELDS(iColumn, “OFFSET”)

                          End If

                          If iStart > (DATA(iLine, “WA”)).Length Then

                              ‘outArray(iRow, iColumn – 1) = Nothing

                          Else

                              resultaat = Strings.Mid(DATA(iLine, “WA”), iStart, iLength)

                              ‘outArray(iRow, iColumn – 1) = Strings.Mid(DATA(iLine, “WA”), iStart, iLength)

                              xlsSheetTables.Cells(iRow, iColumn).value = “‘” & resultaat.ToString

                          End If

                      Next

                      iRow += 1

                  Next

      (0) 
    2. Hynek Petrak Post author

      Hi,

      yes apparently the length of a single row (sum of length of each column, including separator?) shall not exceed 512 characters. Just the field length itself for DD03M is 587. So you have to name your fields explicitly and exclude some of them, not to exceed the row size.

      Hynek

      (0) 
      1. T. Slijpen

        Hi Hynek

        Thanks for the info.

        My problem is that I want to retrieve some info of info types in T588M

        SM30 T588M.png

        SM30 T588M_1.png

        SM30 T588M_3.png

        And this info I need

        But I don’t know how to get it.

        Could you please advise

        Thanks

        Ton

        (0) 
        1. Hynek Petrak Post author

          Hi Ton,

          I suggest you to check SCN or open another Discussion thread. This discussion shall be related to the above article and I’m afraid we are drifting away.

          Regards, Hynek

          (0) 

Leave a Reply