I know it is very wide question. We all use System fields like SY-SUBRC to check last statement was successful or not, SY-DBCNT for Database access count, SY-INDEX for row, SY-TABIX for current processed row in Loops, etc.
Demo code
Check out this code.
System Field behavior
TYPES: BEGIN OF lty_data, num TYPE i, fld2 TYPE i, END OF lty_data. DATA: li_data TYPE STANDARD TABLE OF lty_data. DATA: lwa_data LIKE LINE OF li_data. * 5 entries in table DO 5 TIMES. lwa_data-num = sy-index * 2. APPEND lwa_data TO li_data. ENDDO. DO 5 TIMES. READ TABLE li_data INTO lwa_data WITH KEY num = sy-index. IF sy-subrc EQ 0. WRITE: /(12) 'Entry Found,', sy-index, 'subrc', sy-subrc, 'tabix', sy-tabix. lwa_data-fld2 = sy-index * 2. ELSE. WRITE: /(12) 'Not Found,', sy-index, 'subrc', sy-subrc, 'tabix', sy-tabix. ENDIF. MODIFY li_data FROM lwa_data INDEX sy-tabix. ENDDO.
At first it looks ok except the Modify statement outside the IF..ENDIF. Since the MODIFY statement is outside the IF, it would try to update the entry even when it is not found (SY-SUBRC = 4). MODIFY statement is using the SY-TABIX to update the entry in the ITAB. If you run this code it would end up in short-dump.
Why it ended in Short-Dump?
The reason is behind the SY-TABIX value. Whenever SY-SUBRC gets set to 4, SY-TABIX gets cleared – means set to 0. In other words, system make the TABIX to zero as it couldn’t found the entry (SUBRC = 0). Since it would try to update the table with zero index, it would end up in short dump. To check the content of the SY-TABIX, comment out the MODIFY statement and try the program again. You would see the output similar to this.
In above sample code, it is required to move the MODIFY statement to avoid the short dump withing the IF .. ELSE part.
Helper Variable
If you need to use the TABIX value for any other purpose within the LOOP, it would be a better idea to save that into a local variable and use it for the purpose. Something similar to this would help you to keep SY-TABIX value even after any other failed READ.
LOOP AT li_vbak INTO lwa_data. v_tabix = sy-tabix. READ TABLE li_data_2 INTO lwa_data_2 WITH KEY fld = lwa_data-fld2. IF sy-subrc = 0. ENDIF. * by the time it reaches here, SY-TABIX would be initial * so, use to V_TABIX if it is required to access TABIX again. ENDLOOP.
Thanks for the post, I always use a variable to save the SY-TABIX value just because once I saw somewhere that it was a good practice, now I understand, you have a really good blog, thanks again π
Hello Karina,
I’m glad that it helped you have more clarity and understanding.
Regards,
Naimesh Patel
Hello Naimesh,
Although using helper variables are justified in certain cases i.e. the one you mentioned, I can’t forgive ABAP designers they force developers to overuse them. Method chaining seems to fix this a bit but working on new SAP NW is something not everyone can do at his work.IMHO – a pitty. Anyhow, as usual thanks to your curiosity and willing to share the knowledge developers can svoid sticky situations.
Regards
marcin
Hello Marcin,
Nice to hear from you after long time.
I know the pain of using the helper variables as not all systems I work are 702. Looks like the core designers were in hurry to “deliver” the ABAP compiler and didn’t pay much attention on code cleanliness. Whatever the reason may be, but most of us now would be too much used to use the helper variables that, we may not even try to not use them.
Thanks,
Naimesh Patel
I have found that in most cases you can avoid using SY-TABIX if you use field symbols.
If you used READ TABLE li_data_2 ASSIGNING you wouldn’t need the modify statement or SY-TABIX.
Hello Johan,
I totally agree with you that we should not use MODIFY anymore as we can work better with Field-Symbols. But we can avoid SY-TABIX all the time, like Parallel Cursor. You need to use SY-TABIX with help of helper variable to keep track of the current index so, you can start from there on wards.
Regards,
Naimesh Patel
Thank you for the blog. Yes indeed, using SY-TABIX not directly after the statement where it is set (read table or loop at) is always dangerous. For instance if you call a subroutine or method or function before using SY-TABIX, it may have been set in your FORM or METHOD or FUNCTION if internal table access is involved.
Well, the sample code shows that it is a good habit NEVER to LOOP INTO work area but ALWAYS LOOP ASSIGNING .
Not only the code is faster (at least never slower) but also you work directly with the table line. MODIFY is an obsolete statement once you have got used to use field-symbols.
By the way: Could I include nicely formatted code lines in my comment?
Regards,
Clemens
Hello Clemens,
Glad to hear from you.
Yes, we should use field-symbols to access data from the internal table. I used it in the code here, to show the problem. If I had used the field-symbol, it would be little difficult to demonstrate the problem.
We have to pay extra care while relying on the System variables, in general. Like if we introduce another statement between SELECT and SY-SUBRC, SUBRC would be set from the latest statement.
PS – I tried to develop a plugin which can be used for code formatting. Please find the instruction next to Submit button. I’ll try to make a small guide on its usage. The live preview box below is not able to interpret the code formatting shortcode, yet.
Regards,
Naimesh Patel
Hi Naimesh,
Thanks for sharing the point – “Whenever SY-SUBRC gets set to 4, SY-TABIX gets cleared”.
Keshav π
Actually this is not completely true. Read the online documentation on READ TABLE to see how the values of SY-SUBRC & SY-TABIX are related π
Hello Suhas,
It completely slipped out of my mind to look for the behavior documentation if there is any. Thanks for pointing it out. I would try to check if that explanation still stands true.
Regards,
Naimesh Patel
Thanks Suhas for sharing it. Let me go thorough the documentation.
Kesav