ABAP Lesser Known Heroes Series – Value Operator : Part 2
This is a continuation of my post series,
Part 1 : https://blogs.sap.com/2021/07/09/abap-lesser-known-heroes-series-group-column-part-1/comment-page-1/#comment-580377
Part 2 : ABAP Lesser Known Heroes Series – Value Operator : Part 2
Part 3 : ABAP Lesser Known Heroes Series – TYPE RANGE OF : Part 3 | SAP Blogs
Value operator is a relatively new addition to the ABAP language and the developers already have started extensively using this feature. But here I am writing about one of its functionality which is not widely noticed .
More about value operator from ABAP documentation,
Value operator is particularly helpful in feeding internal table with values .
REPORT ZSAMPLE_VALUE. TYPES: gtt_sflight TYPE STANDARD TABLE OF SFLIGHT WITH DEFAULT KEY . DATA(lt_flights) = VALUE gtt_sflight( ( carrid = 'AA' connid = '0017' fldate = '26.11.2020' price = '422,94' ) ( carrid = 'AZ' connid = '0018' fldate = '29.12.2020' price = '100.89' ) ( carrid = 'DL' connid = '0019' fldate = '30.05.2021' price = '422,94' ) ).
And here is the utility of ‘value’ operator which I accidently found out while using ‘where used’ list of a BAPI.
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA' EXPORTING headdata = VALUE bapimathead( material_long = rv_matnr ind_sector = 'M' matl_type = 'FERT' basic_view = 'X' storage_view = 'X' account_view = 'X' purchase_view = 'X' ) clientdata = VALUE bapi_mara( matl_group = get_material_group( ) base_uom = get_unconverted_uom( ) net_weight = '10' unit_of_wt = 'KG' ) clientdatax = VALUE bapi_marax( matl_group = 'X' base_uom = 'X' net_weight = 'X' unit_of_wt = 'X' ) plantdata = VALUE bapi_marc( plant = get_plant( ) pur_group = get_purch_group( ) ) plantdatax = VALUE bapi_marcx( plant = get_plant( ) pur_group = 'X' ) valuationdata = VALUE bapi_mbew( val_area = get_valuation_area( ) price_ctrl = lv_price_ctrl std_price = '10.00' price_unit = lv_price_unit moving_pr = '10.00' val_class = get_valuation_class( iv_matl_type = 'FERT' ) ) "3300/7920 depends on system valuationdatax = VALUE bapi_mbewx( val_area = get_valuation_area( ) price_ctrl = 'X' std_price = 'X' moving_pr = 'X' price_unit = 'X' val_class = 'X' ) storagelocationdata = VALUE bapi_mard( plant = get_plant( ) stge_loc = get_storage_location( ) ) storagelocationdatax = VALUE bapi_mardx( plant = get_plant( ) stge_loc = get_storage_location( ) ) TABLES materialdescription = lt_create_material_matdscr returnmessages = lt_returnmessages.
Code from CL_API_RESERVATION_DOC_DPC_EXT – Local Test Class
We no more have to declare the input structures for a FM/BAPI separately . We could use the value statement with the corresponding structure and feed with the values for the parameters. This feature is useful particularly when used in test classes. The icing on the cake is, we could even assign a functional method to the parameter list. Easy huh ??
Footnote: But one strange thing which I noticed is that , we can only feed structures with a value to the function modules/BAPI’s but not internal tables. I wonder why. May be the list gets longer? But could have been good enough for testing classes with one or two line items?
TABLES materialdescription = value t_bapi_makt( ( langu = 'D' langu_iso = 'DE' matl_desc = 'Sample Material' del_flag = ' ' ) ) returnmessages = value cfx_bi_tt_bapi_matreturn2( ( type = 'E' ID = 'SD' number = '120' message = 'Sample' ) ).
The above code throws error when used with BAPI ‘BAPI_MATERIAL_SAVEDATA’ .
May be Horst Keller can show some light on this ?
Yup, VALUE is really an unsung hero, especially in unit tests!
However, I'm not sure I understand the limitation you mention in the footnote. To me it looks like a set of parentheses is missing.
My 2 cents: I guess this doesn't work because the parameter type TABLES is obsolete (*), there's no equivalent data type corresponding to those old variables made of a table body and a header line.
EDIT: (*) except with RFC.
But this is possible:
Sandra Rossi ,
Very good observation. Tables parameter type is obsolete and that may be the reason . Most old school BAPI's and function modules use tables parameters and it could have been nice to add the value parameter to the tables statements.
I think it's always the same thing: either it's additional work for them (like doing an additional conversion from the constructed value to the tables parameter so that it can be used by the form or function module, due to that problematic header line), or other issues like performance, too much headache for no actual interest (function modules are more and more abandoned). Who knows...
If i remember correctly, constructor operators don't work with CHANGING parameters as well. IMHO, TABLES parameters are similar to CHANGING and therefore VALUE isn't supported for them too.
Unfortunately i couldn't find any reference to this behaviour in the official ABAP documentation.
The RFC warning isn't always applicable.
The parameter contains a data type that, in the external system, can lead to a high memory consumption and poorer performance.
I've never encountered such an issue. So perhaps the RFC warning is even just covering a rare case.
Uwe Schieferstein points out here: https://answers.sap.com/questions/5671452/using-table-types-in-rfc.html
Since TABLES parameters are obsolete you should always use table types for "itab" parameters.
The system will always show you a warning about possible performance problems which you can ignore.
I think I even saw a semi-official declaration from SAP once that this RFC warning was no longer accurate, but of course, that was several years ago and I have no idea where I saw it anymore. In any case, my experience has been the same, that I have never seen an actual performance issue from using table types with IMPORTING/EXPORTING parameters.
I vaguely remember such a thing as well.
The really "unsung" hero(es) are the OPTIONAL & DEFAULT additions of VALUE operator.
The former is really useful to avoid handling the CX_SY_ITAB_LINE_NOT_FOUND exception.
we need inline declartion for importing params in FMs like we do in methods. S U C K S!!
wanna declare importing variable inline in FMs CONVERSION_EXIT_***UGLY_STUFF.
for partner fns it kills me to call an FM to convert the thingy from DE to EN and vice versa, ANNOYING AF!