Search code examples
abapinternal-tables

Looping through a dynamic internal table


I am trying to split internal table to smaller chunks.

In below example the internal table big_table is split into small tables.

My question is how do we get the actual data from lt_small_tables for further processing.

TYPES: BEGIN OF lty_line,
         column1 TYPE i,
         column2 TYPE c LENGTH 4,
       END OF lty_line.
CONSTANTS: lc_test_data_amount TYPE i VALUE 44,
           lc_split_at_amount  TYPE i VALUE 7, 
DATA: lt_big_table    TYPE STANDARD TABLE OF lty_line,
      lv_string       TYPE string,
      lt_small_tables TYPE STANDARD TABLE OF REF TO data,
      lr_small_table  TYPE REF TO data.
FIELD-SYMBOLS: <lg_target> TYPE STANDARD TABLE.

" Generate test data
DO lc_test_data_amount TIMES. 
  CALL FUNCTION 'GENERAL_GET_RANDOM_STRING'
    EXPORTING number_chars  = 4    " Specifies the number of generated chars
    IMPORTING random_string = lv_string.    " Generated string
  APPEND VALUE #( column1 = sy-index
                  column2 = CONV #( lv_string ) ) TO lt_big_table.
ENDDO.

" Split
DATA(lo_descr) = CAST cl_abap_tabledescr(
               cl_abap_typedescr=>describe_by_data( lt_big_table ) ).
LOOP AT lt_big_table ASSIGNING FIELD-SYMBOL(<ls_line>).
  IF ( sy-tabix - 1 ) MOD lc_split_at_amount = 0.
    CREATE DATA lr_small_table TYPE HANDLE lo_descr.
    ASSERT lr_small_table IS BOUND.
    APPEND lr_small_table TO lt_small_tables.
    ASSIGN lr_small_table->* TO <lg_target>.
    ASSERT <lg_target> IS ASSIGNED.
  ENDIF.
  APPEND <ls_line> TO <lg_target>.
ENDLOOP.

Thanks, Kris


Solution

  • There are at least a couple of ways

    Solution 1: cast internal table reference into a known type, so that you can directly access its fields.

    FIELD-SYMBOLS: <fs_table> like lt_big_table.
    
    LOOP AT lt_small_tables into lr_small_table.
    
      ASSIGN lr_small_table->* TO <fs_table>.
      ASSERT <fs_table> IS ASSIGNED.
    
      LOOP AT <fs_table> into data(ls_line).
        " do something with line
        write: / ls_line-column1, ls_line-column2.
      ENDLOOP.
    
    ENDLOOP.
    

    Solution 2: dynamic access to the tables fields

    FIELD-SYMBOLS: <generic_fs_table> TYPE ANY TABLE.
    
    LOOP AT lt_small_tables into lr_small_table.
    
      ASSIGN lr_small_table->* TO <generic_fs_table>.
      ASSERT sy-subrc = 0.
    
      LOOP AT <generic_fs_table> ASSIGNING FIELD-SYMBOL(<generic_fs_line>).
    
        " dinamically access to line fields
        ASSIGN COMPONENT 'COLUMN1' of STRUCTURE <generic_fs_line> to FIELD-SYMBOL(<generic_fs_field1>).
        ASSERT sy-subrc = 0.
    
        ASSIGN COMPONENT 'COLUMN2' of STRUCTURE <generic_fs_line> to FIELD-SYMBOL(<generic_fs_field2>).
        ASSERT sy-subrc = 0.
    
        " do something with component2
        write: / <generic_fs_field1>, <generic_fs_field2>.
    
      ENDLOOP.
    
    ENDLOOP.