Search code examples
oopabaprtts

Creating a range for a field from internal table using RTTS


I want to create a function/custom class method that takes in 2 parameters:

1) IM_ITAB type ANY TABLE

2) IM_COMPONENT type STRING

and returns 1 parameter:

1) EX_RANGE type PIQ_SELOPT_T

So, algorithm is like this:

  • First of all, we check if the column with a component name at all exists
  • Then, we check that internal table is not empty.
  • Then, we loop through internal table assigning component and filling range table. Code is below.
METHODS compose_range_from_itab
    IMPORTING 
      IM_ITAB      type ANY TABLE
      IM_COMPONENT type STRING
    EXPORTING
      EX_RANGE     type PIQ_SELOPT_T.
...
METHOD compose_range_from_itab.

  DATA: lo_obj   TYPE REF TO cl_abap_tabledescr,
        wa_range TYPE selopt,
        lt_range TYPE piq_selopt_t.

  FIELD-SYMBOLS: <fs_line> TYPE ANY,
                 <fs_component> TYPE ANY.

  lo_obj ?= cl_abap_typedescr=>describe_by_data( p_data = im_itab ).

  READ TABLE lo_obj->key TRANSPORTING NO FIELDS WITH KEY name = im_component.

  IF sy-subrc IS INITIAL.

    IF LINES( im_itab ) GT 0.

      LOOP AT im_itab ASSIGNING <fs_line>.

        ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO <fs_component>.

        wa_range-sign = 'I'.
        wa_range-option = 'EQ'.
        wa_range-low = <fs_component>.

        APPEND wa_range TO lt_range.

      ENDLOOP.

      SORT lt_range BY low.
      DELETE ADJACENT DUPLICATES FROM lt_range COMPARING low.

      ex_range[] = lt_range[].

    ENDIF.

  ENDIF.

ENDMETHOD.

But I want to improve the method further. If the imported internal table has, let's say, 255 columns, then it will take longer to loop through such table. But I need only one column to compose the range.

So I want to get components of internal table, then choose only one component, create a new line type containing only that component, then create internal table with that line type and copy.

Here is the pseudo code corresponding to what I want to achieve:

append corresponding fields of im_itab into new_line_type_internal_table.

How can I "cut out" one component and create a new line type using RTTS?


Solution

  • You are overcomplicating everything, you don't need RTTS for that.

    DEFINE make_range.
      ex_range = VALUE #( BASE ex_range ( sign = 'I' option = 'EQ' low = &1 ) ).
    END-OF-DEFINITION.
    
    LOOP AT im_itab ASSIGNING FIELD-SYMBOL(<fs_line>).
      ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_field>).
      CHECK sy-subrc = 0 AND <fs_field> IS NOT INITIAL.
      make_range <fs_field>.
    ENDLOOP.
    

    And yes, as Sandra said, you won't gain any performance with RTTS, just the opposite.