The hassle with function module calls
Do you know this? You use a function module from SAP (let’s say, the very useful START_TIME_DETERMINE), and you use it often. But every time you insert it, half a page of coding is generated, the parameters do not get syntax checked and inline data declarations are not supported.
It would be much more convenient having the same functionality in a method, wouldn’t it?
So I create a wrapper method. But where to put it? After a year, I want to find it easily, and I want my colleagues to be able to find it either. Here’s my approach:
I created a package dedicated to OO wrappers for SAP function calls.Then, I created classes that put together wrappers of a similar kind. One criterium for “similar” could be the function pool where the SAP function is in.
Actually, my package looks like this:
The coding of the wrapper itself is quite easy:
Just create a coherent interface (with non-generic typed parameters) and call the function.
I hope you get the idea! I would like to read your comments about this. Do you have a different approach?
We did something similar, for various reasons:
- it's easier to find the FMs, which are often used
- for unit testing it's easier to have a mock object
- syntax is nicer with methods.
I would also recommend to add ERROR_MESSAGE, sometimes no exception is raised in FM only some messages (CALL FUNCTION - parameter_list - ABAP Keyword Documentation).
- one can clarify the interface (the intended use of TABLES statements: input, output, changing), introduce returning parameter where feasible and code the parameters in own preferred naming convention...
- map the classic exceptions to own OO exceptions
- have a peace of mind that if SAP changes or deprecates the thing, the immediate changes you would need to do would most likely be in wrapper method rather that x places in the application
Building wrapper classes for SAP functions is should (not must) in our guideline; we do one class per function group.
What would be a proper way to map FM exceptions to class bassed ones without having to declare hundrets of ZCX-classes, one for each exception of each FM? I already tried to find a good solution, but still haven't found a real suitful way...
You can create an exception class for the whole function group and create text-IDs for each classical exception.
We just create ZCX per function group with many text ids, with or without passing the original message text to them - haven't put much thought into it. It's not very "clean" or elegant and too many text ids make ZCX "chaotic", but one can at least add some useful information for classical exceptions raised without message.
I didn't know ERROR_MESSAGE - thanks for highlighting it, this will be very useful!
how do you deal with those sometimes extreme long parameter lists of function modules? Do you create a structure for it or even an object? Otherwise method call has also these long parameter lists, of course with advantages Jänis already mentioned.
Depends if the SAP FM has optional parameters or not. If they are optional, they don't have to be mentioned. If they are not optional ... well, you don't have really a choice, you will have also a long list of parameters. 🙁
Anyway, with the shorter form of method calls, it still looks shorter & more compact:
zcl_util=>method1( i_par1 = lv_par1
i_par2 = lv_par2
i_par3 = lv_par3 ).
You also have to look at how the module is used in most cases in your system. For instance, we often read texts in logon language, so I created a READ_TEXT wrapper that uses SY-LANGU as default for TDSPRAS so this parameter can be omitted in most cases. Often, optional parameters are not needed, so I do not include them in the wrapper interface.
I do not like grouping those parameters together in structures or objects ore something. It makes the coding less legible
well the typical consulting answer is, it depends! 😀
If you have function module like BAPI_ACC_DOCUMENT_POST which has a long parameter list, but all together form an accounting document, I think it is even more legible to form an object or structure accounting_document, e.g.
What do you think?
That's right. But BAPI calls are not the scope of my approach. I was writing about frequently used utilities like START_TIME_DETERMINE or KNA1_SINGLE_READ that you use every now and then.
Complicated modules as BAPIs require more dedication, here you are absolutely right.
There is also the initial pain of writing the classes in the first place, but I think that could be reduced by using function module RFC_GET_FUNCTION_INTERFACE to get the function modules interface and then write the class and method definitions using an ABAP program which would also apply consistent rules. You could then upload that using SE24 ??
So you mean a kind of wrapper generator? THAT would be sophisticated. Let me know, when you are ready to share the coding... 😎
Hmmm..... I don't think it would be that sophisticated. You have TfDir for the function modules, derive the function group from the function module name - you can then group all the FM's using that.
Get the function module interface using the function module I outlined, create two tables containing the text for the method definitions derived from the FM interface, the other containing the FM Call. For the definitions you could massage the parameter names according to some rules.
Then a third table that contains the class staement. Append the first definition table to it and the end class, then the implementation statement followed by the second table and spit the whole lot out to a text file.
The only manual bit would be getting them back into SAP. I think SE24 or SE80 has a module mode rather than a visual mode. Cut from the text file and paste into the created class file.
You can then concentrate on the 'Special;' cases like the Read_Text mentioned above.
As for writing it.... My spare time at the moment is taken up writing an interface for an IBM S370 with MVS and JES2 outputting PTR and PUN on Sockets and accepting RDR on other sockets so that it can interface to a windows laptop alongside a 3270 Terminal Emulator. I also occasionally poke SAP to try and get them to give me an 'IDES' version of R/2 so I can load that and give people web access to show them what they are missing......(last time they told me to see my psychologist.... 😕 )
>The only manual bit would be getting them back into SAP.
Using FM 'SEO_CLASS_CREATE_COMPLETE' could be also an option as it was implemented for SAPLink for example (code is in ZSAPLINK_CLASS->CREATEOBJECTFROMIXMLDOC( ) ).
Here are my deep thoughts on the matter:-