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”.
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.
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
After executing the statement
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)
After the update
In Debug, ASSIGN statement creates the FS and assigns the values of the specific structure COLOR from T_COLOR from ALV table direclty
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
- ABAP 740 – NEW Operator to instantiate the objects
- ABAP 740 – NEW Operator to create ITAB entries
- ABAP 740 – VALUE Operator to create ITAB entries
- ABAP 740 – Table Expressions to Read & Modify ITAB line
- ABAP 740 – LINE_EXISTS to check record in ITAB
- ABAP 740 – Meshes – A new complex type of Structures
- ABAP 740 – Mesh Path – Forward and Inverse Association
- ABAP 740 – FOR Iteration Expression
- ABAP 740 SWITCH – Conditional Operator
- ABAP 740 – LOOP AT with GROUP BY
- ABAP 740 – Is CONSTANT not a Static Attribute anymore?
- SALV IDA (Integrated Data Access) – Introduction
- SALV IDA – Selection Conditions
- SALV IDA – New Calculated Fields
- SALV IDA – Column Settings
- SALV IDA – Add and Handle Hotspot (Hyperlink)
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?
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):
This will may result in three times searching for the row of customer 123.
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.
Very helpful!! Thanks.
Now just need to wait until we get 7.4. 🙁
Hey,
There is another opotion to check if line exist:
IF line_exists( flight_tab[ carrid = ‘LH’
connid = ‘0400’ ] ).
…
ENDIF.
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.
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.