cancel
Showing results for 
Search instead for 
Did you mean: 

Calling an RFC a second time using the same data

0 Kudos

Hi,

I have a simple adaptive RFC model that accepts a small table ITAB with 2 fields Personnel Number and Name as well as two importing attributes FCODE and INDEX.

The RFC is written so that if ITAB,FCODE and INDEX are initial it will fill the table with Pernr's. The RFC will then be called a second time with the populated ITAB, a function code "TEST" in FCODE and a line number in INDEX - it will then insert the name of the Pernr located at position INDEX into the Name field of ITAB.

I call the model the first time and it shows the list of Pernr's correctly, I then have some code to populate the model attrubutes FCODE and INDEX when a line is selected and a toolbar button action is triggered. In the RFC I can see that FCODE is set to TEST and INDEX is set to the Lead Selection. But the internal table ITAB is blank even though I haven't refreshed the context model node.

I then guessed that I have to copy the table entries from the Output node to the "input" Node. I copied the entries by using

WDCopyService.copyElements(wdContext.nodeItab_Output(), wdContext.nodeItab());

after the model is called the first time. This did not work and the RFC is still passed a blank ITAB. This must be a pretty common request - to pass the output from a RFC back into the same RFC. How do you do this ?

Here is the code I am using - I use the wdDoInit to call the RFC the first time and then I use the onActionTestAction to call it the second time once the button has triggered the action:

public void wdDoInit()

{

//@@begin wdDoInit()

Z_Wd_Testlist_Input input = new Z_Wd_Testlist_Input();

wdContext.nodeTestRFC().bind(input);

try{

wdContext.currentTestRFCElement().modelObject().execute();

}catch (Exception ex){

wdComponentAPI.getMessageManager().reportException(ex.toString(),false);

}

wdContext.nodeOutput().invalidate();

WDCopyService.copyElements(wdContext.nodeItab_Output(), wdContext.nodeItab());

//@@end

}

public void onActionTestAction(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )

{

//@@begin onActionTestAction(ServerEvent)

int i = wdContext.nodeItab_Output().getLeadSelection();

wdContext.currentTestRFCElement().modelObject().setFcode("TEST");

wdContext.currentTestRFCElement().modelObject().setIndex(i);

try{

wdContext.currentTestRFCElement().modelObject().execute();

}catch (Exception ex){

wdComponentAPI.getMessageManager().reportException(ex.toString(),false);

}

wdContext.nodeOutput().invalidate();

//@@end

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Richard,

I'm pasting here few lines of code that I'd given for a some what similar query(). Hope this helps you.

Modify your 'onActionTestAction' to something similar to below.

Assume that RFC 'ZMYRFC' uses a table 'mytable' of type some type 'ZTAB' . The lines of code you need to write to invoke this RFC with the table as input are :

ZMYRFC_Input input = new ZMYRFC_Input() // create an instance of the Input class;

Iprivate<your view name>.Itab_OutputElement elmt = null;

for(int i=0;i<wdContext.nodeItab_Output.size();i++)

{

elmt = wdContext.getItab_OutputElementAt(i);

ZTAB table = new ZTAB();

//if you do not know table type of 'mytable', check the function input.addMytable(<table type>)

table.set<property>(elmt.get());.

.

table.set<property>(elmt.get());

input.addMytable(table);

}

input.setFcode("TEST");

input.setIndex(i);

wdcontext.currentZMYRFC_inputElement.bind(input);

wdContext.currentZMYRFC_inputElement().modelObject().execute();

wdContet.nodeOutput.invalidate()

// clears the old value in the output node

Best Regards,

Nibu.

Answers (4)

Answers (4)

0 Kudos

Nibu, your suggestion worked. I then replaced the code that copied each field :

table.set<property>(elmt.get<attribute_name>());

table.set<property>(elmt.get<attribute_name>());

with the following:

WDCopyService.copyCorresponding(elmt,table);

and it worked.

So now I can call each RFC as many times as I like and pass the output back in as input as long as I loop through the output table and copy each record to the input table. I still think that this should have been much simpler but I am happy that I can finaly continue with my development.

0 Kudos

Thanks everyone, I will only be able to try your suggestions on Thursday when I have access to the system again.

I really didn't think it would be much work (if any) to simply pass the output of a Bapi back to the same Bapi - it seems that there may be quite a few steps involved to copy data from the "output"table to the "input"table which to me are pointing to the same table anyway !

This test I am doing is part of a much larger solution where my Bapi will have twenty+ fields. Will I have to manually move the contents of each field of each record of each table every time I want to call the RFC ?

Former Member
0 Kudos

Hi Richard,

OnActionTestAction method should be in your View.

then onclick of the button call this method and inside that call the method like

onActionTestAction(){

wdThis.wdGetGetCustController().executeBapi();

}

//This method should be in your Custom Controller or Component Controller.

executeBapi(){

try{

wdContext.currentTestRFCElement().modelObject().execute();

}catch (Exception ex){

wdComponentAPI.getMessageManager().reportException(ex.toString(),false);

}

wdContext.nodeOutput().invalidate();

}

In your Component Controller's or Custom Controller's

init method bind your input parameters like..

public void wdDoInit()

{

//@@begin wdDoInit()

Z_Wd_Testlist_Input input = new Z_Wd_Testlist_Input();

int i = wdContext.nodeItab_Output().getLeadSelection();

wdContext.currentTestRFCElement().modelObject().setFcode("TEST");

wdContext.currentTestRFCElement().modelObject().setIndex(i);

wdContext.nodeTestRFC().bind(input);

WDCopyService.copyElements(wdContext.nodeItab_Output(), wdContext.nodeItab());

//@@end

}

Orelse

put all your code inside executeBapi method and try it.

like..

Sample code...

public void execute_GetWbs_List( java.lang.String networkNum )

{

//@@begin execute_GetWbs_List()

GetWbsModel Model = (GetWbsModel) com.sap.tc.webdynpro.progmodel.model.api.WDModelFactory.getModelInstance(

GetWbsModel.class,WDModelScopeType.APPLICATION_SCOPE);

// Create a input param object and pass model object to it

Bapi_Network_Getinfo_Input bapi_Network_Getinfo_Input =

new Bapi_Network_Getinfo_Input(Model);

//Add the structure to the bapi input object

Bapi_Network_List bapi_Network_List = new Bapi_Network_List();

if(networkNum != null){

bapi_Network_List.setAttributeValue("Network" , networkNum);

wdComponentAPI.getMessageManager().reportSuccess("Message : " + networkNum);

bapi_Network_Getinfo_Input.addI_Network_List(bapi_Network_List);

this.wdContext.nodeBapi_getWbs_List().bind(bapi_Network_Getinfo_Input);

}

try{

wdContext.currentBapi_getWbs_ListElement().modelObject().execute();

}catch(Exception e){e.printStackTrace();}

wdContext.nodeOutput().invalidate();

//@@end

}

Try this and get back to me if its not working.

Former Member
0 Kudos

hi richard,

try this

write the code

WDCopyService.copyElements(wdContext.nodeItab_Output(),wdContext.nodeItab());

before you do wdContext.nodeOutput().invalidate();

regards,

Rahul