Skip to Content
What is this all about…

While sifting through SDN posts, I have had a feeling that when it comes to ARFC and model nodes, quite a few of us (myself included!!!) are not very comfortable.

For example, you have imported an ARFC model, bound it to the model node of the controller’s context and everything is working fine. But then, one fine day, the structure of the BAPI changes and you have to do a model reimport.

So you delete your model node, create them afresh and do the mapping and pray that everything still works fine. This is a scenario that I have faced a couple of times in the last one year and trust me, it isn’t a nice feeling.

One more example that I can cite is the scenario where we bind model nodes to UI elements. Many a times you find UI elements bound to model nodes to be disabled. Then you go through the whole process of trying to figure out the cardinality stuff properly.
And who can forget struggling with deep structures?

What I have tried to do in this post is show you a way to execute RFCs/BAPIs, absolutely without using model nodes. All you need are value nodes and value nodes make us feel good :).
Here’s the scenario: I am trying to get a list of materials from the R/3 to a dropdown box in the UI. The BAPI that I’m using is “Bapi_Material_Getlist”
I will be selecting the materials for the Planning Plant “0001”, for all material numbers and I will select only 10 materials.
I have imported a ARFC model from “Bapi_Material_Getlist” and named the model “FetchListOfMaterials”

Outline of the basic steps

Here are the steps:

  • Crate a Custom Controller. The context looks like:
    • Context (Root node)
      • MaterialNumberList (value node, default properties)
        • Material (value attribute, String, default properties)
        • Material_Desc (value attribute, String, default properties)
        • Material_External (value attribute, String, default properties)
        • Material_Guid (value attribute, String, default properties)
        • Material_Version (value attribute, String, default properties)
  • Create an exactly similar structure in the view and map this to the Custom Controller’s context.
  • Create a DropDownByIndex UI element for the view.
  • Bind the “texts” property to view context’s “MatrialNumberList.Material”
  • Create a method public void selectListOfMaterials() for the Custom Controller.
  • From your view’s wdDoInit() method, call the Custom Controller’s method.

Source code for method selectListOfMaterials
public void selectListOfMaterials( )
{
//@@begin selectListOfMaterials()
//I have used hard-coded Strings. Sorry about that. FetchListOfMaterials getModel = (FetchListOfMaterials)WDModelFactory.getModelInstance(FetchListOfMaterials.class,WDModelScopeType.TASK_SCOPE);
Bapi_Material_Getlist_Input input = new Bapi_Material_Getlist_Input();
Bapimatram matNumberSel = new Bapimatram();
matNumberSel.setOption("CP");
matNumberSel.setSign("I");
matNumberSel.setMatnr_Low("*");
input.addMatnrselection(matNumberSel);
Bapimatras matDescSel = new Bapimatras();
matDescSel.setDescr_Low("Z*");
matDescSel.setOption("CP");
matDescSel.setSign("I");
input.addMaterialshortdescsel(matDescSel);
Bapimatraw plntSel = new Bapimatraw();
plntSel.setPlant_Low("0001");
plntSel.setOption("EQ");
plntSel.setSign("I");
input.addPlantselection(plntSel);
input.setMaxrows(10);
try {
input.execute();
} catch (WDDynamicRFCExecuteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
wdComponentAPI.getMessageManager().reportSuccess(e.getMessage());
}
IWDNodeElement elemSrc;
IWDNodeElement elemDest;
wdContext.nodeMaterialNumberList().invalidate();
Bapi_Material_Getlist_Output output = input.getOutput();
List matList = output.getMatnrlist();
wdComponentAPI.getMessageManager().reportSuccess(String.valueOf(matList.size()));
try{
if(matList != null){
for(int i = 0; i < matList.size(); i++){
elemDest = wdContext.nodeMaterialNumberList().createElement();
Bapimatlst matListObj = (Bapimatlst)matList.get(i);
elemDest.setAttributeValue("Material",matListObj.getMaterial());
wdContext.nodeMaterialNumberList().addElement(elemDest);
}
}
}
catch(ClassCastException cEx){
}
//@@end
}

Now when this is run, 10 material numbers will be populated in the dropdown.

What just happened?

Let’s strike up a comparison to using a model node. When we create a model node it has a corrsponding java class and every subnode also has a corrsponding java class. We look to
make use of these classes instead of the node structure. For example, the line input.getOutput() returns an instance of the BAPI output class,
Bapi_Material_Getlist_Output in this case.
So what about the subnodes of the output node. Well, the instance of the BAPI output class will have instances of the classes which correspond to each of the subnodes. The line List matList = output.getMatnrlist() will return a java.util.List of “Bapimatlst” instances. Here Bapimatlst is the class which corresponds to the Matnrlist node of the model output
node(if you had created one, that is).
How many entries will there be in the List? Well, we all know about node elements. Similarly, the number of instances can be compared to the number of node elements.
In this case only 10 materials were selected. So if you had used model nodes, the node Matnrlist would have had 10 node elements. So in this case, the list will contain 10 Bapimatlst
instances.
The rest is just accessing the getters of this class and copying them to your value node.

And that’s it! You are done.

Caveat Developer
  • This post doesn’t aim at discouraging the use of model nodes.
  • This is just another approach to ARFC programming.
  • This post provides a basic idea. It should be moulded to fit your needs.

To report this post you need to login first.

2 Comments

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

  1. Valery Silaev
    Satyajit,

    Also the post points to very useful option, the example used completely discards the value of such option. Really, what is the benefit to use non-model node and create elements / copy attributes manually??? I’d rather prefer to use wdContext.nodeOutput().invalidate()…

    Where is option could be really useful is situation when you need both RFMs with visual results and RFMs with non-visual results. For example, I faced scenarios when it was necessary to:
    1. Get some part of user input and execute RFM_A
    2. Get other data entered by user, combine it with output of RFM_A and execute RFM_B
    3. Display result of RFM_B

    In this scenario RFM_A was not mapped to context, but both input and output of RFM_B has corresponding model nodes.

    Valery

    (0) 
    1. Anonymous
      Valery,
         I agree with what you had to say about the example. But I guess that was a result of a bit of bias towards value nodes. 😛

      Regards,
      Satyajit.

      (0) 

Leave a Reply