‎2019 Aug 07 4:49 PM
I am new to ABAP 740, and I am currently working on converting my existing ABAP code in ABAP 740 standards. I do have some understanding of the basic syntax of ABAP 740 and I have converted some of my existing ABAP code to 740. I am struggling to convert the below code as it has loop with where clause, two reads and based on the filter call FM and then modify the internal table. Need some guidance, please...
LOOP AT gt_vmcfa WHERE selkz = gc_charx.
READ TABLE it_vbrk WITH KEY vbeln = gt_vmcfa-vbeln BINARY SEARCH.
IF sy-subrc IS INITIAL. IF it_vbrk-rfbsk <> 'C'.
READ TABLE lt_vbfs INTO DATA(ls_vbfs) WITH KEY vbeln = gt_vmcfa-vbeln BINARY SEARCH.
IF sy-subrc IS INITIAL.
CLEAR: ld_shorttext.
ld_msgno = ls_vbfs-msgno.
CALL FUNCTION 'RPY_MESSAGE_COMPOSE'
EXPORTING message_id = ls_vbfs-msgid
message_number = ld_msgno
message_var1 = ls_vbfs-msgv1
message_var2 = ls_vbfs-msgv2
message_var3 = ls_vbfs-msgv3
message_var4 = ls_vbfs-msgv4
IMPORTING message_text = ld_shorttext
EXCEPTIONS message_not_found = 1 OTHERS = 2.
gt_vmcfa-zzerror = ld_shorttext.
ENDIF.
ENDIF.
MODIFY gt_vmcfa.
ENDIF.
ENDLOOP.
‎2019 Aug 07 6:10 PM
I guess you are talking about Constructor Expressions. "construct" means the initialization of a variable from scratch. Constructor expressions cannot update existing data (except adding lines to internal tables). Period.
But what you can do is using sorted or hashed tables (available since 1998), and please stop using header lines (obsolete since at least 2005).
‎2019 Aug 07 5:55 PM
Hi flowers.candys,
To achieve it you need to read the documentation of FOR or REDUCE and internal table function statements. We have a lot of blogs and questions telling how to do it, I put some relevant links to you read bellow. Now, about the function inside of your demo code, it not will run using inline declarations, as solution you need to create a local class and call it inside the inline loop (as I mentioned above) or find another global one already created on your SAP system.
Links:
ABAP Language News for Release 7.40
Tips:
1 - If you always had a doubt about a statement or functionality, first search and read the DEMO programs on your system, accessing it on SE38 or SE80 TCodes (Search using the string DEMO*);
2 - Check the version of your system, some instructions may not work correctly and you need to read the ABAP Document to check it;
3 - Continue to study ;).
BR,
Raphael Pacheco.
‎2019 Aug 07 7:00 PM
Hi Raphael - yes, thanks for the shared links. Regarding tip # 1, are there any specific DEMO programs intended for latest ABAP standards that I cAn leverage?
‎2019 Aug 07 7:23 PM
E.g.: If you want to see the FOR demo programs, search for DEMO_FOR*, if you want to know about MESHES, search for DEMO_MESH*. 😉
‎2019 Aug 07 7:27 PM
‎2019 Aug 07 7:38 PM
Based on the links shared, I implemented FOR for some of the loops that I have had in the program and it works as expected.
" populate the output table
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( mandt = ls_vmcfa-mandt vkorg = ls_vmcfa-vkorg kunrg = ls_vmcfa-kunrg fktyp = ls_vmcfa-fktyp fkdat = ls_vmcfa-fkdat fkart = ls_vmcfa-fkart ernam = ls_vmcfa-ernam
erdat = ls_vmcfa-erdat kunag = ls_vmcfa-kunag vbeln = ls_vmcfa-vbeln rfbsk = ls_vmcfa-rfbsk selkz = ls_vmcfa-selkz fktyp_text = ls_vmcfa-fktyp_text fkart_text = ls_vmcfa-fkart_text
name1 = ls_vmcfa-name1 name2 = ls_vmcfa-name2 vfuvgr = ls_vmcfa-vfuvgr statf = ls_vmcfa-statf zzvbeln = ls_vbrp-aubel zzposnr = ls_vbrp-aupos zzmatnr = ls_vbrp-matnr )
).
However, in the above code, do I need to assign field by field? Meaning mandt = ls_vmcfa-mandt vkorg = ls_vmcfa-vkorg kunrg = ls_vmcfa-kunrg and so on....?
Am I missing anything?
‎2019 Aug 07 8:06 PM
You can use the CORRESPONDING statement, this is the same as MOVE-CORRESPONDING.
P.S.: I'm glad to see you solving your problem.
#KeepLearning.
‎2019 Aug 07 8:54 PM
yes, I tried using corresponding, but I encountered below problems -
option # 1
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( CORRESPONDING #( ls_vmcfa ) ) ).
Above statement does not copy data from another work area ls_vbrp but only from ls_vmcfa.
option # 2
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( CORRESPONDING #( ls_vmcfa ) ) ( zzvbeln = ls_vbrp-aubel zzposnr = ls_vbrp-aupos zzmatnr = ls_vbrp-matnr ) ).
Above statement copies data two times - first from work area ls_vmcfa and then from work area ls_vbrp. So entries get doubled.
Hence, I did field by field assignment. Can you guide, please?
‎2019 Aug 07 6:06 PM
Hi,
if I were you I would start with non-ABAP-7.4 related adjustments - you seem to use tables with header lines ("LOOP AT gt_vmcfa WHERE selkz = gc_charx". or "READ TABLE it_vbrk WITH KEY vbeln = gt_vmcfa-vbeln BINARY SEARCH.") which is obsolete.
Modifying data in a loop is rather to be done using field symbols (better performance) than MODIFY statement.
You should check subrc after calling the FM.
Please use meaningful names of variables and also keep their namig convension proper (ld should be rather lv or l_v)
In terms of ABAP 7.4 you can use dynamic conversion when calling FM instead of saving data in a separate variable.
After changes your code could look like this (still change the names of variabls / fields symbols to more meaningful data):
LOOP AT gt_vmcfa ASSIGNING FIELD-SYMBOL(<l_s_vmcfa>) WHERE selkz = gc_charx.
IF NOT line_exists( it_vbrk[ vbeln = <l_s_vmcfa-vbeln rfbsk = 'C' ] ).
READ TABLE lt_vbfs ASSIGNING FIELD-SYMBOL(<l_s_vbfs>) WITH KEY vbeln = <l_s_vmcfa>-vbeln BINARY SEARCH.
IF sy-subrc EQ 0.
CLEAR l_s_shorttext.
CALL FUNCTION 'RPY_MESSAGE_COMPOSE'
EXPORTING
message_id = <l_s_vbfs>-msgid
message_number = CONV sy-msgno( <l_s_vbfs>-msgno )
message_var1 = <l_s_vbfs>-msgv1
message_var2 = <l_s_vbfs>-msgv2
message_var3 = <l_s_vbfs>-msgv3
message_var4 = <l_s_vbfs>-msgv4
IMPORTING
message_text = l_s_shorttext
EXCEPTIONS
message_not_found = 1
OTHERS = 2.
IF sy-subrc EQ 0.
<l_s_vmcfa>-zzerror = l_s_shorttext.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
Cheers,
Marek
‎2019 Aug 07 7:05 PM
Hi Marek - sure thing, the custom code that I shared was a copy of standard code that I intended to enhance, appreciate the improvements - I learnt a few new things. I was not sure how to call function module inside the new FOR syntax. I will go through the documentation shared previously.
‎2019 Aug 07 7:19 PM
Hi Marek - I have a question on the revised code..
READ TABLE lt_vbfs ASSIGNINGFIELD-SYMBOL(<l_s_vbfs>)WITHKEY vbeln =<l_s_vmcfa>-vbeln BINARYSEARCH.
can the above read statement be converted to IF line_exists(). ENDIF.? how can we move the work area into the field symbol <l_s_vbfs> in IF line_exists() syntax.
‎2019 Aug 07 7:22 PM
Aah, I think IF line_exists() can only be used if there ain't any work area?!?
‎2019 Aug 07 7:30 PM
Exactly, line_exists is not filling any work area - it is a simple check if line exists in a table or not returning a proper subrc.
You need to have a field symbol assigned becase you want to use the variables (MSGNO / MSGID etc.) in calling an FM.
FOR operation on the global internal table is not useful in this case because you do not need to build a new table but only modify a field of main table.
Cheers,
Marek
‎2019 Aug 08 7:53 AM
LOOP AT gt_vmcfa ASSIGNING FIELD-SYMBOL(<l_s_vmcfa>) WHERE selkz = abap_true.
IF NOT line_exists( it_vbrk[ vbeln = <l_s_vmcfa>-vbeln rfbsk = 'C' ] ).
ASSIGN lt_vbfs[ vbeln = <l_s_vmcfa>-vbeln ] TO FIELD-SYMBOL(<l_s_vbfs>).
IF sy-subrc EQ 0.
MESSAGE ID <l_s_vbfs>-msgid TYPE 'S' NUMBER <l_s_vbfs>-msgno
V1 = <l_s_vbfs>-msgv1 V2 = <l_s_vbfs>-msgv2 V3 = <l_s_vbfs>-msgv3 V4 = <l_s_vbfs>-msgv4
INTO <l_s_vmcfa>-zzerror.
ENDIF.
ENDIF.
ENDLOOP.
‎2019 Aug 08 8:26 AM
That MESSAGE ID xyz INTO is a really nice abbreviation. Thanks for the hint.
‎2019 Aug 08 5:32 PM
As stated in one of the comments, I read through some blog posts for ABAP 740 changes, I replaced loop/read statements with FOR and it works as expected. But I ended up in doing assignment field by field, I experimented with CORRESPONDING but had challenges using two work areas (stated below). IS there any efficient way to achieve this?
" populate the output table
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( mandt = ls_vmcfa-mandt vkorg = ls_vmcfa-vkorg kunrg = ls_vmcfa-kunrg fktyp = ls_vmcfa-fktyp fkdat = ls_vmcfa-fkdat fkart = ls_vmcfa-fkart ernam = ls_vmcfa-ernam
erdat = ls_vmcfa-erdat kunag = ls_vmcfa-kunag vbeln = ls_vmcfa-vbeln rfbsk = ls_vmcfa-rfbsk selkz = ls_vmcfa-selkz fktyp_text = ls_vmcfa-fktyp_text fkart_text = ls_vmcfa-fkart_text
name1 = ls_vmcfa-name1 name2 = ls_vmcfa-name2 vfuvgr = ls_vmcfa-vfuvgr statf = ls_vmcfa-statf zzvbeln = ls_vbrp-aubel zzposnr = ls_vbrp-aupos zzmatnr = ls_vbrp-matnr )
).
option # 1
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( CORRESPONDING #( ls_vmcfa ) ) ).
Above statement does not copy data from another work area ls_vbrp but only from ls_vmcfa.
option # 2
DATA(lt_vmcfa) =
VALUE ltt_vmcfa(
FOR ls_vbrp IN lt_vbrp
FOR ls_vmcfa IN c_vmcfa WHERE ( vbeln = ls_vbrp-vbeln )
( CORRESPONDING #( ls_vmcfa ) ) ( zzvbeln = ls_vbrp-aubel zzposnr = ls_vbrp-aupos zzmatnr = ls_vbrp-matnr ) ).
Above statement copies data two times - first from work area ls_vmcfa and then from work area ls_vbrp. So entries get doubled in lt_vmcfa.
‎2019 Aug 07 6:10 PM
I guess you are talking about Constructor Expressions. "construct" means the initialization of a variable from scratch. Constructor expressions cannot update existing data (except adding lines to internal tables). Period.
But what you can do is using sorted or hashed tables (available since 1998), and please stop using header lines (obsolete since at least 2005).
‎2019 Aug 07 6:25 PM
I think he want to translate all the his code to ABAP 7.4, no?
‎2019 Aug 07 7:06 PM
‎2019 Aug 07 8:48 PM
As sandra.rossi said, use sorted or hashed table, and avoid BINARY SEARCH.
‎2019 Aug 08 7:26 AM
Why losing time to translate legacy code? What gain? Why not learning 7.40 syntax on new code instead?
By the way, RPY_MESSAGE_COMPOSE is obsolete too. Use MESSAGE statement instead.
‎2019 Aug 08 3:13 AM
You cant call function module inside FOR...loop, but you could try to create a function method and call it. My pseudo code (not guaranty it work 🙂 😞
lt_vmcfa = VALUE #( FOR ls_vmcfa IN gt_vmcfa WHERE ( selkz = gc_charx )
LET ls_vbrk = VALUE #( it_vbrk[ vbeln = ls_vmcfa-vbeln ] OPTIONAL )
ls_vbfs = VALUE #( lt_vbfs[ vbeln = gt_vmcfa-vbeln ] OPTIONAL )
IN ( COND #( WHEN ls_vbrk IS NOT INITIAL AND
ls_vbrk-rfbsk <> 'C' AND
ls_vbfs IS NOT INITIAL
THEN ( VALUE #( BASE ls_vmcfa zzerror = cl_msg=>get_msg( ls_vbfs-msgno ) ) ) ) ) ).
‎2019 Aug 08 7:48 AM
That's exactly what shouldn't be done. You use a syntax for the wrong use case, because the performance is worse. In the current example given by the OP, you must keep LOOP AT ... ASSIGNING ... and just update the concerned field.
‎2019 Aug 08 11:40 AM
May I ask which part would be "performance is worse" as you said? the LET inside FOR.. or the function method call or the construction of lt_vmcfa? I can make it to LET line_exist(...) too if it make any difference...
‎2019 Aug 08 12:25 PM
Recreating a whole internal table takes longer than just updating one field.
Just made a test to update FLDATE of 1000 lines of standard itab with line type SFLIGHT : UPDATE: 37.83 < CONSTRUCTION: 117.28 (ABAP 7.52 SP01):
itab2 = value #(
for <line> in itab1
( VALUE #( BASE <line> fldate = '20190808' ) ) ).
" itab1 = itab2 is minor
versus
LOOP AT itab1 ASSIGNING FIELD-SYMBOL(<line>).
<line>-fldate = '20190808'.
ENDLOOP.<br>
‎2019 Aug 09 12:48 AM
‎2019 Aug 08 7:41 AM
Generally speaking, if one wants to learn what has changed in newest versions, there is the chapter "ABAP Release-Specific Changes" of the official ABAP documentation. It's very interesting to read because you can read only the changes that concern you, if you know syntax 7.02 then you just have to read the changes of 7.31, 7.40 and above, up to the version which is of some interest for you. To better understand some of those syntaxes, there are often some blog posts by Horst Keller or by other people.
‎2019 Aug 08 5:33 PM
Thanks for the link, it's helpful to see changes per release.