Dynamically read an internal table with more than one key field

3.7k Views Asked by At

Let us say I have the following code:

iob_typedescr ?= cl_abap_typedescr=>describe_by_name( 'HOUSES' ).
iob_structdescr_table ?= iob_typedescr.
it_ddic_all  = iob_structdescr_table->get_ddic_field_list( ).

LOOP AT it_ddic_all INTO is_ddic WHERE keyflag EQ 'X'.

  APPEND is_ddic TO it_keyfields.
ENDLOOP.

So basically, in the above code I know all of the key fields in the table HOUSES and they are in the table it_keyfields. Now if I had an internal table which had the same structure as HOUSES and wanted to select data from it how would I be able to do this dynamically? If I knew I had only one key then I could do a READ TABLE as follows:

READ TABLE it_internal_table WITH KEY (key_name) = provided_value TRANSPORTING NO FIELDS.

But in this case I may have more than one key in it_keyfields so I am not sure how I could write the READ TABLE statement for this.

2

There are 2 best solutions below

2
Gert Beukema On

If you want to handle different numbers of key fields dynamically at runtime then you won't be able to do that with a READ command. However, you can now also read data from an internal table using SELECT and there you can dynamically create a WHERE condition that selects on fields only known during runtime.

From the documentation: Use of SELECT to access an internal table using as an alternative to the statement READ TABLE. Unlike READ TABLE, the statement SELECT offers a (dynamic) WHERE condition and evaluates the field list for the inline declaration. The statement is executed on the AS ABAP and the data in the internal table is not transported to the database.

0
Stefan On

You could create a dynamic where condition and use it with LOOP WHERE. Here is a snippet using table SPFLI as an example.

" variable that contains dynamic where condition later
DATA lv_where TYPE string.
" field-symbol that can contain any data
FIELD-SYMBOLS: <f_field_value> TYPE any.
" define it_internal_table (can be dynamic)
DATA it_internal_table TYPE TABLE OF spfli.
it_internal_table = VALUE #(
    ( mandt = '001' carrid = '002' connid = '0003' cityfrom = 'PARIS' )
    ( mandt = '001' carrid = '004' connid = '0005' cityfrom = 'BERLIN' )
).

" define provided values that need to be searched in it_internal_table
DATA(ls_provided_entry) = VALUE spfli( mandt = '001' carrid = '002' connid = '0003' cityfrom = 'PARIS' ).

" create dynamic where condition
LOOP AT it_keyfields ASSIGNING FIELD-SYMBOL(<f_key>).
    ASSIGN COMPONENT <f_key>-fieldname OF STRUCTURE ls_provided_entry TO <f_field_value>. 
    IF sy-subrc = 0.
        IF lv_where IS INITIAL.
            lv_where = |{ <f_key>-fieldname } = `{ <f_field_value> }`|.
        ELSE.
            DATA(lv_where_and) = |AND { <f_key>-fieldname } = `{ <f_field_value> }`|.
            CONCATENATE lv_where lv_where_and INTO lv_where SEPARATED BY space.
        ENDIF.
    ENDIF.
ENDLOOP.

" now check with LOOP WHERE if the provided entry exists in it_internal_table
LOOP AT it_internal_table ASSIGNING FIELD-SYMBOL(<f_internal_table_line>) WHERE (lv_where).
    " if this point is reached, the entry exists;
    " <f_internal_table_line> contains the complete line
    WRITE 'The entry exists'.
    EXIT.
ENDLOOP.