If you want to call a function in another SAP system, you can get this done by calling a Remote Function Call (RFC)-enabled function module of the target system. For example, while you are in SAP ERP Central Component (ECC), you can call a function in the SAP BW system, or vice versa. If the function in the target system is not an RFC-enabled function module, you can wrap that function, which could be a function module, a method, or a program, into an RFC-enabled function module so that you can call this wrapped RFC-enabled function module from the source system.
However, there are two things to consider:
- The generic format of this RFC-enabled function module. If you need to call 20+ different functions of the target system, you end up with calling 20+ RFC-enabled function modules, either customized or standard. It is not well managed. The question is, can you develop a generic RFC-enabled function module for all these 20+ different functions?
- Parameters. For each of these 20+ function modules, you may have different import/export/ changing/return parameters. To develop a generic function module, you have to develop a generic expression of the parameters that are of generic data types, can be understood by both source and target systems, and are fit for all function requirements for parameters.
I provide a solution on one generic RFC-enabled function module with serialized parameters for you to call different functions of another system. The simplified architecture of this RFC call is illustrated in Figure 1.
Simplified RFC call process
You call an RFC-enabled function module via an RFC connection from a caller system (e.g., an SAP BW system). The function could be FISCPER_FROM_CALMONTH_CALC, for example, to get a fiscal period from a calendar month. The callee system (e.g., the ECC system) gets the request and executes the RFC-enabled function module FISCPER_FROM_CALMONTH_CALC with the import calendar month, fiscal year variant, and exporting fiscal period to the caller system.
To make this call more generic, working for different functions, you could improve the architecture as shown in Figure 2.
Improved RFC call with a case statement
With a case statement, you can determine which RFC function module to call in the callee system.
This calling program is as shown in Figure 3.
Program to call an RFC function module
You call the function module with the destination (the RFC destination) of the callee system ECDCLNT100, indicator ‘C’, meaning you call as a client. The function to be called is FISCPER_FROM_CALMONTH_CALC, the input parameter is calendar month 201706, and the fiscal year variant is Z1. The expectation is to get the fiscal period back.
If the company starts the fiscal year in October, then fiscal year 2017 starts on calendar month 201610, so calendar month 201706 would return 2018009 as the fiscal period.
This function module needs to be implemented on both systems (i.e., the calling system and the callee system) because the intention is to make the solution bidirectional. You can call from either system to the other system without a change in the code.
See sample code for this RFC function module in Figure 4.
The RFC function module
Inside this RFC function module:
- The program starts to call with indicator ‘C’ (line 16)
- It calls the same function module but in the destination system (RFC carried by i_dest) with indicator ‘S’ (line 17)
- The callee system receives the RFC call (line 29)
- The callee system executes the function with function module name carried in the i_method (in this example FISCPER_FROM_CALMONTH_CALC) (line 30)
- The result is returned to the caller system (line 26-28)
- The calling program receives the result (line 20 of Figure 3)
Generic Function Call
There is one issue with this method. Let’s say I want to call function module RSAU_READ_MASTER_DATA to get SAP BW InfoObject master data. I call it as shown in Figure 5.
I will have more parameters and they are different from the parameters of function module FISCPER_FROM_CALMONTH_CALC. Therefore, if I want to make function module Z_TEST_RFC more generic, I need to accommodate this by adding more parameters such as those shown in Figure 6.
Add more parameters
The highlighted portions are added to accommodate the requirement for function module RSAU_READ_MASTER_DATA. This list of parameters (importing/exporting/exceptions) can grow bigger and bigger as you add more functions to this generic function call.
There is another issue with data types. An RFC function module does not allow a generic data type such as E_STRUCTURE TYPE ANY in Figure 6. I am going to cover this in another section.
For a function module, you introduce a data type abap_func_parmbind_tab to resolve this issue. See the code snippet in Figure 7.
Using generic parameters
See how you package multiple parameters into parameter-table lt_parameter. This data type abap_func_parmbind_tab is to be used for the function module call. For the method call there is a similar data type, abap_parmbind_tab, to be used.
Check the result in the debug screen to have a better understanding of how it works (Figure 8).
Before the call
Before the call, you can see you provide import parameters iv_calmonth and iv_periv, expecting a value for export parameter EV_FISCPER. The parameters are lined up in the parameter table lt_parameter (Figure 9).
After the call
After the call, you can see you get the value 2017009 as ev_fiscper for the fiscal period. There is a similar exception table with data type abap_excpbind_tab. You can insert an exception table in this way as well.
Since you are changing the parameters, this parameter table is to be put in the Changing tab of the generic RFC function module. I changed the function module in Figure 10 using abap_func_parmbind_tab. See lines 8 and 9 of Figure 10 for the Changing tab parameter CT_PARAM.
Using ABAP_FUNC_PARMBIND_TAB in the function module
As I validate the function module, there are two issues here:
- Type abap_func_parmbind_tab is not known or allowed. For an RFC call, I must use a Data Dictionary (DDIC) definition. ABAP_FUNC_PARMBIND_TAB belongs to type group ABAP and it is not a DDIC definition data type.
- In the definition of ABAP_FUNC_PARMBIND (Figure 11), upon which ABAP_FUNC_PARMBIND_TAB is defined.
Definition of abap_func_parmbind
Here element value and table_wa are defined as a reference, not a generic, type. For these two reasons I can’t pass data type abap_func_parmbind_tab to the RFC call.
I can define abap_func_parmbind/ abap_func_parmbind_tab in DDIC with a different name and use it. However, I plan to do it without an additional new DDIC definition.
The solution proposed here is to serialize the parameter into a generic string and put the string into the RFC function module. The function I used to serialize data in JSON format string is the JSON converter /UI2/CL_JSON. The solution is proposed in Figure 12.
The generic RFC call with serialized parameters
At a high level, you need to:
- Serialize the parameters into a string
- Call a generic RFC with a method name and serialized parameters
- Get back the result in a string
- De-serialize the string back into the parameter table
My program context becomes what is shown in Figure 13.
Serialize, call RFC, and de-serialize
This is how it works in the programming context.
Check the following generic RFC function in Figure 14.
Inside the generic RFC call
This generic function call at the callee system side, starting at line 23, de-serializes the data. Call the actual function with the name i_method at line 30. Serialize the result back to string C_DATA at line 40, and send it back to caller system at line 21.