Selection criteria object for the reports where you can implement the MVC for decoupling. This approach is using the FM RS_REFRESH_FROM_SELECTOPTIONS.
Introduction
If you love the object oriented design in ABAP Objects, you must have read the article – ABAP Object Oriented Approach for Reports β Redesign. In that article, I have shown you how to use the Selection criteria object. This object is nothing but carry around the selection screen values.
Typically class definition would be:
Using the FM RS_REFRESH_FROM_SELECTOPTIONS
Got a hang of the select object, now? If not, I suggest you read ABAP Object Oriented Approach for Reports β Redesign.
So far, I have been using the pattern – manually setting up the values from the select options into the attributes of the selection object. Keshav and Jani80k has suggested that we also can use the FM RS_REFRESH_FROM_SELECTOPTIONS. Jani80K provided the implementation as well in the article Object Oriented Approach for Reports with multiple Datasource. Thank you much!
This code lines are modified from the code lines provided in this comment, with few changes. These are the components of the class
- Attributes – for selection criteria from screen
- CONSTRUCTOR – calls default method
- REFRESH – sets up the values again
Two small methods are added compared to the original code lines to reduce the code lines. I have left the commented lines as is, if you want to refer to it
Utility Selection class using FM RS_REFRESH_FROM_SELECTOPTIONS
* CLASS lcx_exception DEFINITION INHERITING FROM cx_static_check FINAL. PUBLIC SECTION. DATA im_message TYPE char50. METHODS constructor IMPORTING textid LIKE textid OPTIONAL previous LIKE previous OPTIONAL im_message TYPE string OPTIONAL. ENDCLASS. "lcx_exception DEFINITION * CLASS lcl_selopts DEFINITION FINAL. PUBLIC SECTION. DATA gt_selopts TYPE STANDARD TABLE OF rsparams WITH KEY selname READ-ONLY. DATA gt_banfn TYPE RANGE OF banfn read-only. DATA gt_ernam TYPE RANGE OF ernam read-only. DATA gt_badat TYPE RANGE OF badat read-only. DATA gt_erdat TYPE RANGE OF erdat read-only. DATA gt_afnam TYPE RANGE OF afnam read-only. DATA gv_frrel TYPE mmpur_bool READ-ONLY. DATA gv_frpoc TYPE mmpur_bool READ-ONLY. DATA gv_frrej TYPE mmpur_bool READ-ONLY. METHODS constructor RAISING lcx_exception. METHODS refresh RAISING lcx_exception. PRIVATE SECTION. METHODS get_selopts RAISING lcx_exception. METHODS set_defaults. " METHODS get_value_range IMPORTING iv_name TYPE char30 CHANGING ct_range TYPE STANDARD TABLE. " METHODS get_value_param IMPORTING iv_name TYPE char30 RETURNING value(rv_value) TYPE char45. ENDCLASS. "lcl_selopts DEFINITION * CLASS lcl_selopts IMPLEMENTATION. METHOD constructor. "me->get_selopts( ). me->set_defaults( ). ENDMETHOD. "constructor METHOD get_selopts. CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS' EXPORTING curr_report = sy-repid TABLES selection_table = gt_selopts EXCEPTIONS not_found = 1 no_report = 2 OTHERS = 3. IF sy-subrc NE 0. RAISE EXCEPTION TYPE lcx_exception EXPORTING im_message = 'No Select Options.'. ENDIF. me->get_value_range( EXPORTING iv_name = : 'S_BANFN' CHANGING ct_range = gt_banfn ), 'S_ERNAM' CHANGING ct_range = gt_ernam ), 'S_BADAT' CHANGING ct_range = gt_badat ), 'S_ERDAT' CHANGING ct_range = gt_erdat ), 'S_AFNAM' CHANGING ct_range = gt_afnam ). gv_frrel = me->get_value_param( 'P_FRREL' ). gv_frrej = me->get_value_param( 'P_FRREJ' ). gv_frpoc = me->get_value_param( 'P_FRPOC' ). * DATA lr_selopt TYPE REF TO rsparams. * FIELD-SYMBOLS <banfn> LIKE LINE OF gt_banfn. * FIELD-SYMBOLS <ernam> LIKE LINE OF gt_ernam. * FIELD-SYMBOLS <badat> LIKE LINE OF gt_badat. * FIELD-SYMBOLS <erdat> LIKE LINE OF gt_erdat. * FIELD-SYMBOLS <afnam> LIKE LINE OF gt_afnam. * READ TABLE gt_selopts WITH TABLE KEY selname = 'S_BANFN' REFERENCE INTO lr_selopt. * IF sy-subrc EQ 0 AND lr_selopt->option IS NOT INITIAL. * APPEND INITIAL LINE TO gt_banfn ASSIGNING <banfn>. * MOVE-CORRESPONDING lr_selopt->* TO <banfn>. * ENDIF. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'S_ERNAM' REFERENCE INTO lr_selopt. * IF sy-subrc EQ 0 AND lr_selopt->option IS NOT INITIAL. * APPEND INITIAL LINE TO gt_ernam ASSIGNING <ernam>. * MOVE-CORRESPONDING lr_selopt->* TO <ernam>. * ENDIF. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'S_BADAT' REFERENCE INTO lr_selopt. * IF sy-subrc EQ 0 AND lr_selopt->option IS NOT INITIAL. * APPEND INITIAL LINE TO gt_badat ASSIGNING <badat>. * MOVE-CORRESPONDING lr_selopt->* TO <badat>. * ENDIF. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'S_ERDAT' REFERENCE INTO lr_selopt. * IF sy-subrc EQ 0 AND lr_selopt->option IS NOT INITIAL. * APPEND INITIAL LINE TO gt_erdat ASSIGNING <erdat>. * MOVE-CORRESPONDING lr_selopt->* TO <erdat>. * ENDIF. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'S_AFNAM' REFERENCE INTO lr_selopt. * IF sy-subrc EQ 0 AND lr_selopt->option IS NOT INITIAL. * APPEND INITIAL LINE TO gt_afnam ASSIGNING <afnam>. * MOVE-CORRESPONDING lr_selopt->* TO <afnam>. * ENDIF. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'P_FRREL' REFERENCE INTO lr_selopt. * gv_frrel = lr_selopt->low. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'P_FRREJ' REFERENCE INTO lr_selopt. * gv_frrej = lr_selopt->low. * * READ TABLE gt_selopts WITH TABLE KEY selname = 'P_FRPOC' REFERENCE INTO lr_selopt. * gv_frpoc = lr_selopt->low. ENDMETHOD. "get_selopts METHOD get_value_range. DATA lr_selopt TYPE REF TO rsparams. FIELD-SYMBOLS: <fs> TYPE any. LOOP AT gt_selopts REFERENCE INTO lr_selopt WHERE selname = iv_name. IF lr_selopt->option IS NOT INITIAL. APPEND INITIAL LINE TO ct_range ASSIGNING <fs>. MOVE-CORRESPONDING lr_selopt->* TO <fs>. ENDIF. ENDLOOP. ENDMETHOD. "get_Value_range METHOD get_value_param. DATA lr_selopt TYPE REF TO rsparams. FIELD-SYMBOLS: <fs> TYPE any. READ TABLE gt_selopts WITH TABLE KEY selname = iv_name REFERENCE INTO lr_selopt. check sy-subrc eq 0. rv_value = lr_selopt->low. ENDMETHOD. "get_Value_param METHOD set_defaults. FIELD-SYMBOLS <ernam> LIKE LINE OF gt_ernam. APPEND INITIAL LINE TO gt_ernam ASSIGNING <ernam>. <ernam>-sign = 'I'. <ernam>-option = 'EQ'. <ernam>-low = sy-uname. FIELD-SYMBOLS <erdat> LIKE LINE OF gt_erdat. APPEND INITIAL LINE TO gt_erdat ASSIGNING <erdat>. <erdat>-low = sy-datum - 7. <erdat>-high = sy-datum. <erdat>-sign = 'I'. <erdat>-option = 'BT'. ENDMETHOD. "set_defaults METHOD refresh. CLEAR: gt_selopts, gt_banfn, gt_ernam, gt_badat,gt_erdat, gt_afnam, gv_frrel,gv_frpoc, gv_frrej. get_selopts( ). ENDMETHOD. "refresh ENDCLASS. "lcl_selopts IMPLEMENTATION * CLASS lcx_exception IMPLEMENTATION. METHOD constructor. CALL METHOD super->constructor EXPORTING textid = textid previous = previous. me->im_message = im_message. ENDMETHOD. "CONSTRUCTOR ENDCLASS. "lcx_exception IMPLEMENTATION
To test it:
DATA: lo_sel TYPE REF TO lcl_selopts. SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY. INITIALIZATION. TRY . CREATE OBJECT lo_sel. s_erdat[] = lo_sel->gt_erdat. CATCH lcx_exception. ENDTRY. START-OF-SELECTION. lo_sel->refresh( ).
Let me know your thoughts.
Credit
Kesavadas Thekkillath
Jani80K for Codelines (sorry don’t have the link to the profile)
Hi Naimesh,
thanks for your improvements. I will incorporate them into my code π
Cheers,
Jani
Hi Naimesh,
our class contains an error. It will only get the first line of a select option. Here is the correct code.
Best regards,
Jani
Oops π .. I think I need to write up ABAP Unit Test on the test code as well π
Thanks for pointing that out Jani. I have corrected the code.