I would like to share my experience on how to create range table to be used in database selection on where clause.
Before we start how to create the dynamic range table, let's see the usual way to create the range table.
Example:
DATA : ra_ebeln TYPA RANGE OF ebeln,
rs_ebeln LIKELINE OF ra_ebeln.
rs_ebeln-sign = 'I'.
rs_ebeln-option = 'EQ'.
rs_ebeln-low = <po number>
APPEND rs_ebeln TO ra_ebeln.
CLEAR rs_ebeln.
Now let's see how we going to create the dynamic range table.
1. Create a class ZCL_UTIL
2. Create constant values on Attributes.
3. Create 2 methods GET_CLASS_CONSTANT and PREPARE_CONSTANT_RANGE.
4. Here is the coding for method GET_CLASS_CONSTANT
METHOD get_class_constant.
SELECT * FROM seocompodf
INTO TABLE et_seocompodf
WHERE clsname = i_clsname
AND attdecltyp = '2'
AND type = i_type.
ENDMETHOD. "GET_CLASS_CONSTANT
5. Here is the coding for method PREPARE_CONSTANT_RANGE
METHOD prepare_constant_range.
DATA : lv_clsname TYPE seoclsname,
lv_off TYPE i.
DATA : lt_seocompodf TYPE STANDARD TABLE OF seocompodf,
lt_abap_stack TYPE abap_callstack,
ls_seocompodf TYPE seocompodf,
ls_abap_stack TYPE abap_callstack_line,
ls_component TYPE abap_compdescr.
DATA : lr_table TYPE REF TO data,
lr_struc TYPE REF TO data.
DATA: lobj_table_descr TYPE REF TO cl_abap_tabledescr,
lobj_struc_descr TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS : <lfs_table> TYPE STANDARD TABLE,
<lfs_struc> TYPE any,
<lfs_value> TYPE any.
*-> Assign the range table in field symbol
GET REFERENCE OF et_range_table INTO lr_table.
ASSIGN lr_table->* TO <lfs_table>.
*-> Assign the range structure in field symbol
CREATE DATA lr_struc LIKE LINE OF <lfs_table>.
ASSIGN lr_struc->* TO <lfs_struc>.
*-> Get component from the range structure
lobj_table_descr ?= cl_abap_typedescr=>describe_by_data_ref( lr_table ).
lobj_struc_descr ?= lobj_table_descr->get_table_line_type( ).
*-> If class name is not pass in from import parameter, get the class name from abap stack
IF i_clsname IS NOT INITIAL.
lv_clsname = i_clsname.
ELSE.
*-> Get Classname from abap stack
CALL FUNCTION 'SYSTEM_CALLSTACK'
IMPORTING
callstack = lt_abap_stack.
READ TABLE lt_abap_stack INTO ls_abap_stack INDEX 1.
IF sy-subrc = 0 AND
ls_abap_stack-blocktype = 'METHOD'.
FIND FIRST OCCURRENCE OF '='
IN ls_abap_stack-mainprogram
MATCH OFFSET lv_off.
IF sy-subrc = 0.
lv_clsname = ls_abap_stack-mainprogram(lv_off).
ELSE.
lv_off = strlen( ls_abap_stack-mainprogram ).
lv_off = lv_off - 2.
lv_clsname = ls_abap_stack-mainprogram(lv_off).
ENDIF.
ENDIF.
ENDIF.
*-> Get Field Type Constant Value
CALL METHOD zcl_util=>get_class_constant
EXPORTING
i_clsname = lv_clsname
i_type = i_type
IMPORTING
et_seocompodf = lt_seocompodf.
*-> Assign the constant values into range table
LOOP AT lt_seocompodf INTO ls_seocompodf.
REPLACE ALL OCCURRENCES OF '''' IN ls_seocompodf-attvalue WITH space.
CONDENSE ls_seocompodf-attvalue.
LOOP AT lobj_struc_descr->components INTO ls_component.
ASSIGN COMPONENT ls_component-name OF STRUCTURE <lfs_struc> TO <lfs_value>.
IF sy-subrc = 0.
CASE sy-tabix.
WHEN '1'. "SIGN
<lfs_value> = 'I'.
WHEN '2'. "OPTION
<lfs_value> = 'EQ'.
WHEN '3'. "LOW
<lfs_value> = ls_seocompodf-attvalue.
WHEN '4'. "HIGH
APPEND <lfs_struc> TO <lfs_table>.
ENDCASE.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
6. Create a program ZTEST_DYNAMIC_RANGE.
REPORT ztest_dynamic_range.
TABLES mseg.
CONSTANTS : gc_bwart TYPE rs38l_typ VALUE 'BWART'.
DATA : ra_bwart TYPE RANGE OF bwart.
START-OF-SELECTION.
CALL METHOD zcl_util=>prepare_constant_range
EXPORTING
* i_clsname =
i_type = gc_bwart
IMPORTING
et_range_table = ra_bwart.
7. Below is the attach screen for debug mode