javasapjco3

Read a table from a SAP system using JCo


I am trying to read a table from an SAP system and I am always getting this error:

Exception in thread "main" com.sap.conn.jco.JCoRuntimeException: (127) 
JCO_ERROR_FIELD_NOT_FOUND: Field EMPLOYEE is not a member of INPUT
at com.sap.conn.jco.rt.AbstractMetaData.indexOf(AbstractMetaData.java:404)
at com.sap.conn.jco.rt.AbstractRecord.setValue(AbstractRecord.java:4074)
at testConf.StepServer.main(StepServer.java:50)

And here is my code :

public static void main(String[] args) {

  // This will create a file called mySAPSystem.jcoDestination
  System.out.println("executing");
  String DESTINATION_NAME1 = "mySAPSystem";

  Properties connectProperties = new Properties();
  connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx.xxx.x.xxx");
  connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "xx");
  connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx");
  connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "username");
  connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "test");
  connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "en");
  createDestinationDataFile(DESTINATION_NAME1, connectProperties);

  // This will use that destination file to connect to SAP
  try {
      JCoDestination destination = JCoDestinationManager.getDestination("mySAPSystem");
      System.out.println("Attributes:");
      System.out.println(destination.getAttributes());
      System.out.println();
      destination.ping();
  } catch (JCoException e) {
      e.printStackTrace();
  }
  try{

  //here starts the problem

  JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
  JCoFunction function = destination.getRepository().getFunction("RFC_READ_TABLE");
  JCoParameterList listParam = function.getImportParameterList();

  listParam.setValue("EMPLOYEE", "EMPLOYEE"); // I have found this in an example and I don't understand exactly what should I put there
                                              // I was thinking maybe is the column name but I am not sure
  function.execute(destination);

  JCoTable table = function.getTableParameterList().getTable("ZEMPLOYEES");//name of my table from SAP

  System.out.println(table);

  }
  catch (JCoException e)
  {
      System.out.println(e.toString());
      return;
  }
 }

The error is clear when it says JCO_ERROR_FIELD_NOT_FOUND: Field EMPLOYEE is not a member of INPUT but the employee is a field in my table.

enter image description here

The documentation doesn't help too much, it only says:

Sets the object as the value for the named field.
Parameters:
    value - the value to set for the field
    name - the name of the field to set 

Witch, in my opinion, I have already done.

Should I make any additional modification in sap, in order to read this new table from java? All I have done is to create a new table following this tutorial (Create a simple table in SAP).

Maybe someone with more experience can tell me how should I configure this sample code in order to work.


Solution

  • General use of RFC_READ_TABLE

    I never used JCo, but as far as I know its interface is very similar to NCo, the .Net connector. This is basically NCo code with some guesswork added to it, but it should work.

    // get the table parameter FIELDS that should be in the parameter list
    // the parameter table has several fields, only the field FIELDNAME has to be set before calling the function module
    JCOTable inputTableParam = function.getTableParameterList().getTable("FIELDS");
    
    // add a row to the FIELDS table parameter
    inputTableParam.appendRow();
    
    // set values for the new row
    inputTableParam.setValue("FIELDNAME", "EMPLOYEE");
    // just for fun, add another field to retrieve
    inputTableParam.appendRow();
    inputTableParam.setValue("FIELDNAME", "SURNAME");
    
    // now we have to set the non-table parameters
    JCoParameterList inputParamList = function.getImportParameterList();
    // parameter QUERY_TABLE, defines which table to query
    inputParamList.setValue("QUERY_TABLE", "ZEMPLOYEES");
    // parameter DELIMITER - we get a single string as the return value, the field values within that string are delimited by this character
    inputParamList.setValue("DELIMITER", ";");
    
    // execute the function
    function.execute(destination);
    
    // the parameter table DATA contains the rows
    JCoTable table = function.getTableParameterList().getTable("DATA");
    

    in the end, your variable table will hold a table object with a single field called WA. That field contains the contents of the fields you selected in input parameter table FIELDS. You can iterate over table and get the values row by row.

    Queries with RFC_READ_TABLE

    RFC_READ_TABLE doesn't really allow queries, it only allows you to define WHERE clauses. The TABLE parameter OPTIONS has a single field TEXT, 72 characters wide, that can only take ABAP compliant WHERE clauses.

    to extend the example above, we'll add a where clause to only select entries from table ZEMPLOYEES with SURNAME = "SMITH" and FORNAME = "JOHN".

    JCOTable optionsTableParam = function.getTableParameterList().getTable("OPTIONS");
    
    // add a row to the FIELDS table parameter
    optionsTableParam.appendRow();
    optionsTableParam.setValue("TEXT", "SURNAME EQ 'SMITH' AND FORNAME EQ 'JOHN');
    

    the field TEXT is only 72 characters long, so if you want to add a longer clause, you manually have to break your conditions into several rows. RFC_READ_TABLE is a bit crude and limited.

    Complex joins between tables can be achieved by creating a view within the SAP system (transaction SE11) and then query that view with RFC_READ_TABLE.

    If you want to call function modules from JCo, it would be very helpful if you made yourself familiar with the basic function module properties. You can look at a function module definition in transaction SE37. There you can see the IMPORT, EXPORT, CHANGING and TABLE parameters. The parameters you have to fill and the parameters that contain the results depend on the function module you call - RFC_READ_TABLE has different ones from, say, BAPI_DELIVERY_GETLIST.

    Here is the documentation for JCoFunction and one of the differences between JCo and NCo, JCo has individual functions to get and set the different parameter types: https://help.hana.ondemand.com/javadoc/com/sap/conn/jco/JCoFunction.html