ABAP 740 – Table Expressions to Read & Modify ITAB line

By | March 3, 2015 | Concepts | 27,914 | 9

Read and Modify the ITAB records without using the temporary work area or variables. It is possible with using the ABAP Table Expressions. Lets see more about them.

Preface

Let me start with begging your apologies for not publishing any article in long time. I had to take a pause :) . I would try to publish as many as I can now.

ABAP 740 has many new features. This new feature Table Expressions are also powerful and reduce the “code clutter”.

ABAP_740_Table_Expressions_to_READ_and_MODIFY

There are two type of them:

  • For Reading the data – These are known as Reader Positions. This would do the same job as you do with the READ statement, but without using the local variables. You can access the row in question directly by specifying the key.
  • For Writing the data – This has same effect as the MODIFY statement on the table entry. With using the Write Positions, you can read the data change the value directly.

How to use Table Expressions

To use the table expression,

  • You need use the square bracket [ ]. Within the bracket, you would need to specify the component you want to use as the key.
  • Don’t get confused with the table specification when you were using the HEADER LINE, e.g. ITAB[]. If you are still using the HEADER LINE, you would need to stop doing that and upgrade to more newer forms of Table definitions
  • When table entry doesn’t exist, a catchable exception CX_SY_ITAB_LINE_NOT_FOUND is raised. There are few exceptions when you don’t need to catch it. But lets discuss that in the next article.
  • You can have multiple table expression chained together like [ ]-[ ]. You must enjoy this when using the Deep structure reading. See example 5 here.

Read More at SAP Help –

Lets see few examples.

Example 1 – Reading table entry using the Key TABLE_LINE

In here, the table has only one component TABLE_LINE. Check out both Old and New way of reading the data.

 
DATA: t_data TYPE STANDARD TABLE OF i.
 
DO 10 TIMES.
  APPEND sy-index TO t_data.
ENDDO.
 
*Old way
DATA: lv_data TYPE i.
DO 12 TIMES.
  READ TABLE t_data INTO lv_data WITH KEY table_line = sy-index.
  IF sy-subrc EQ 0.
    WRITE: / lv_data.
  ELSE.
    WRITE: / 'Not Found', sy-index.
  ENDIF.
ENDDO.
 
* New Way using Table Expressions
DO 12 TIMES.
  TRY .
      WRITE: / t_data[ table_line = sy-index ].
    CATCH cx_sy_itab_line_not_found.
      WRITE: / 'Not found', sy-index.
  ENDTRY.
ENDDO.
 

Example 2 – Modify the Table Entry using the Key

Same table as the previous example, but now modifying the entry.

 
* Modify
 
* Old Way
FIELD-SYMBOLS: <lfs_data> LIKE LINE OF t_data.
READ TABLE t_data ASSIGNING <lfs_data> WITH KEY table_line = 10.
IF sy-subrc EQ 0.
  <lfs_data> = 20.
ENDIF.
 
* New Way
t_data[ table_line = 20 ] = 10.
 

In Debug, Before the Modify statement

ABAP_740_Table_Expressions_MODIFY_before

After executing the statement

ABAP_740_Table_Expressions_MODIFY_after

Example 3 – Modify the Table Entry using the Key which doesn’t exist

Demo of the exception handling CX_SY_ITAB_LINE_NOT_FOUND

 
* Modify when entry doesn't exist
 
* OLD
READ TABLE t_data ASSIGNING <lfs_data> WITH KEY table_line = 11.
IF sy-subrc EQ 0.
  <lfs_data> = 20.
ENDIF.
 
* New Way
TRY .
    t_data[ table_line = 11 ] = 10.
  CATCH cx_sy_itab_line_not_found.
ENDTRY.
 
 

Example 4 – Reading table entry with components

As you see here, you can read the entry and access the component of the result workarea directly, no need of temporary work area.

 
* Multiple Components
TYPES:
  BEGIN OF ty_data,
    kunnr TYPE kunnr,
    name1 TYPE name1,
    ort01 TYPE ort01,
    land1 TYPE land1,
  END   OF ty_data.
TYPES: tt_data TYPE STANDARD TABLE OF ty_data
                                        WITH DEFAULT KEY.
*
DATA(itab_multi_comp) =
  VALUE tt_data( ( kunnr = '123' name1 = 'ABCD' ort01 = 'LV' land1 = 'NV' )
                 ( kunnr = '456' name1 = 'XYZ'  ort01 = 'LA' land1 = 'CA' )
              ).
 
* Old way to access
DATA ls_comp TYPE ty_data.
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
 
* NEW way to access
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
 

Example 5 – Reading and Modifying Table entry in Deep Table

Demo of chaining table expressions when working with the Deep Table. Also notice, how the ASSIGN is used to directly the needed component instead of the other helpers. This example also shows on how to use VALUE operator.

 
* Itab Deep
TYPES:
  BEGIN OF ty_alv_data,
    kunnr   TYPE kunnr,
    name1   TYPE name1,
    ort01   TYPE ort01,
    land1   TYPE land1,
    t_color TYPE lvc_t_scol,
  END   OF ty_alv_data.
TYPES: tt_alv_data TYPE STANDARD TABLE OF ty_alv_data
                                        WITH DEFAULT KEY.
 
DATA(itab_alv) =
  VALUE tt_alv_data(
                    "First Row
                    ( kunnr = '123' name1 = 'ABCD'
                        ort01 = 'LV' land1 = 'NV'
                        " color table
                        t_color = VALUE #(
                                          " Color table - First Row
                                           ( fname = 'KUNNR'
                                             color-col = col_negative
                                             color-int = 0
                                             color-inv = 0
                                            )
                                          " Color Table - 2nd Row
                                           ( fname = 'ORT01'
                                             color-col = col_total
                                             color-int = 1
                                             color-inv = 1
                                            )
                                          )
                    )
                    "Second row
                   ( kunnr = '456' name1 = 'XYZ'
                        ort01 = 'LA' land1 = 'CA'
                    )
                 ).
 
 
* Old Way
FIELD-SYMBOLS: <fs_data> LIKE LINE OF itab_alv,
               <fs_col>  LIKE LINE OF <fs_data>-t_color.
READ TABLE itab_alv ASSIGNING <fs_data> WITH KEY kunnr = '123'.
IF sy-subrc EQ 0.
  READ TABLE <fs_data>-t_color ASSIGNING <fs_col> WITH KEY fname = 'ORT01'.
  IF sy-subrc EQ 0.
    <fs_col>-color-col = col_group.
    <fs_col>-color-int = 0.
    <fs_col>-color-inv = 1.
  ENDIF.
ENDIF.
 
* Table Expressions - New Way
TRY .
    itab_alv[ kunnr = '123' ]-t_color[ fname = 'ORT01' ]-color-col = col_background.
    ASSIGN itab_alv[ kunnr = '123' ]-t_color[ fname = 'KUNNR' ]-color
      TO FIELD-SYMBOL(<col>).
    <col>-col = col_positive.
    <col>-int = 1.
    <col>-inv = 1.
  CATCH cx_sy_itab_line_not_found.
 
ENDTRY.
 

In Debug, before the Direct modify (1st update in this example)

ABAP_740_Table_Expressions_MODIFY_DEEP_1

After the update

ABAP_740_Table_Expressions_MODIFY_DEEP_2

In Debug, ASSIGN statement creates the FS and assigns the values of the specific structure COLOR from T_COLOR from ALV table direclty

ABAP_740_Table_Expressions_MODIFY_DEEP_Assign_1

What do you think?

I think I would use more often than READ and MODIFY. Do you see, if you are gonna use it?

Table of Content – ABAP 740 Concepts

Like It? Share!!

Don't miss an Update

Get notified of the new post, right into your inbox

Naimesh Patel{273 articles}

I'm SAP ABAP Consultant for more than a decade. I like to experiment with ABAP especially OO. I have been SDN Top Contributor.
Follow :

Explore all of his 273 articles.

Load comments

9 Comments

  • Patrick

    Hello,

    thank you for you post. We missed your articles at our site.

    I’m confused about the second example. Shouldn’t it be like this?

     
    t_data[ table_line = 10 ] = 20.
     

    So we can use the new statements to read/modify a special column. But what about performance? I think especially if you want to modify more than just one field, the performance may be better if using field symbols.
    As I understood by your 5th example, the code would look like this if you want to modify more columns (without using field symbols):

     
    itab_alv[ kunnr = '123' ]-t_color[ fname = 'ORT01' ]-color-col = col_background.
    itab_alv[ kunnr = '123' ]-t_color[ fname = 'ORT01' ]-color-int = 1.
    itab_alv[ kunnr = '123' ]-t_color[ fname = 'ORT01' ]-color-inv = 1.
     

    This will may result in three times searching for the row of customer 123.

  • Patrick

    Hello,

    I’ve written a small report to check the performance. If you want to access more than one column, you should use table expressions only to assign the row to field-symbol (like you did in 5th example for color).

    The report updates two columns of a table. The first run uses read statement with assigning to field symbol. The second uses table expressions without field symbols. The third run uses table expressions to assign the row to field symbol.

    The difference between 1 and 3 is less than 0,05 seconds, so it doesn’t affect the runtime that much. But the 2nd way nearly takes the double time than the 1st one.

     
    REPORT z_test_table_expressions.
     
     
    TYPES: BEGIN OF ty_data,
             name  TYPE char20,
             ort01 TYPE ort01,
             count TYPE i,
           END OF ty_data.
     
    TYPES tyt_data TYPE STANDARD TABLE OF ty_data.
     
    DATA: lt_data        TYPE tyt_data,
          lv_sta_time    TYPE timestampl,
          lv_end_time    TYPE timestampl,
          lv_diff_old    TYPE p DECIMALS 5,
          lv_diff_new    TYPE p DECIMALS 5,
          lv_diff_new_fs TYPE p DECIMALS 5,
          lv_save        TYPE p DECIMALS 5.
     
     
    FIELD-SYMBOLS :  TYPE ty_data.
     
    " Prepare data
    DO 10000 TIMES.
      APPEND INITIAL LINE TO lt_data ASSIGNING .
      -count = sy-index.
    ENDDO.
     
     
    " Modify old way with field-symbols
    GET TIME STAMP FIELD lv_sta_time.
     
    DO 10000 TIMES.
      READ TABLE lt_data ASSIGNING  WITH KEY count = sy-index.
      IF sy-subrc = 0.
        -name = 'Name_' &amp;&amp; sy-index.
        -ort01 = 'Ort_' &amp;&amp; sy-index.
      ENDIF.
    ENDDO.
     
    GET TIME STAMP FIELD lv_end_time.
    lv_diff_old = lv_end_time - lv_sta_time.
     
     
    " Modify new way with table expressions
    TRY.
        GET TIME STAMP FIELD lv_sta_time.
     
        DO 10000 TIMES.
          lt_data[ count = sy-index ]-name = 'Name_' &amp;&amp; sy-index.
          lt_data[ count = sy-index ]-ort01 = 'Ort_' &amp;&amp; sy-index.
        ENDDO.
     
        GET TIME STAMP FIELD lv_end_time.
        lv_diff_new = lv_end_time - lv_sta_time.
     
      CATCH cx_sy_itab_line_not_found.
    ENDTRY.
     
    " Modify new way table expressions and field-symbols
    TRY.
        GET TIME STAMP FIELD lv_sta_time.
     
        DO 10000 TIMES.
          ASSIGN lt_data[ count = sy-index ] TO .
          -name = 'Name_' &amp;&amp; sy-index.
          -ort01 = 'Ort_' &amp;&amp; sy-index.
        ENDDO.
     
        GET TIME STAMP FIELD lv_end_time.
        lv_diff_new_fs = lv_end_time - lv_sta_time.
     
      CATCH cx_sy_itab_line_not_found.
    ENDTRY.
     
    " Output difference
    WRITE: /(45) 'Access type',
             50 'Time',
             70 'Difference to old way'.
    ULINE.
    WRITE: /(45) 'Update with field-symbol (old way)',
             50  lv_diff_old.
     
    lv_save = lv_diff_old - lv_diff_new.
    WRITE: /(45) 'Update with table expression',
             50  lv_diff_new,
             70  lv_save.
     
    lv_save = lv_diff_old - lv_diff_new_fs.
    WRITE: /(45) 'Update with table expr. using field-symbol',
             50  lv_diff_new_fs,
             70  lv_save.
     
  • Steve

    Very helpful!! Thanks.

    Now just need to wait until we get 7.4. :(

  • Oren

    Hey,

    There is another opotion to check if line exist:

    IF line_exists( flight_tab[ carrid = 'LH'
    connid = '0400' ] ).

    ENDIF.

  • Mohinder

    Hi,
    Nice as always from Naimesh.

    Thanks
    Mohinder

  • Hello Patrick,

    Thanks for the code snippet. I will test it out. If you agree, I will wrap the code in another article and post it again.

    Regards,
    Naimesh Patel

  • Steve – Nice to hear ya after a long time ;)

    Mohinder – Glad that you like it.

    Thanks.

  • Hello Oren,

    Yes, we have LINE_EXISTS syntax. I will mention that in the followup article on this. Btw, what do you prefer, catching the exception or the LINE_EXISTS? I think the later one, but wanted to check anyways.

    Thanks Much.

  • Oren

    Hey Naimech,
    I’m using in LINE_EXISTS instead of { LOOP AT / READ TABLE } TRANSPORTING NO FIELD,
    If i want the row data i’m catching the exception (instead of checking the sy-subrc after the LOOP / READ TABLE).

    Regards,
    Oren.

Comments on this Post are now closed. If you have something important to share, you can always contact me.

You seem to be new here. Subscribe to stay connected.