04-17-2017 10:42 AM
Hello All,
I was wondering if there's a new way to modify same internal table with new syntax. The old way would be looping thru and modify it.
For condition based, MODIFY internal_table FROM work_area WHERE (condition) would do the trick, however, doing it unconditionally would require a LOOP.
LOOP AT internal_table ASSIGNING FIELD-SYMBOL(<field_symbol>).
<field_symbol>-field = value.
ENDLOOP.
Since ABAP lang has evolved - right from 740, 750 and now 751; and it still is evolving, is there a new way to do it which I probably missed?
If no, then can we have something like
internal_table[ 1..lines( internal_table ) ]-field = value.
I know it's like always asking for more which raises some eye-brows because there are a few, (who I know), are still averse to using the new syntax.
But, as they say - When the storm has swept by, the wicked are gone, but the righteous stand firm forever! 😉
Cheers!
04-18-2017 10:04 AM
Look up the documentation and examples for the constructor operators VALUE, REDUCE, FILTER, CORRESPONDING, COND, ....
You can combine them and use the same table at LHS and RHS.
itab = operator #( ... FOR wa IN itab ... )
04-17-2017 1:05 PM
DATA lt TYPE some_table.
DATA ls TYPE LINE OF some_table.
ls-field = some_value.
MODIFY lt FROM ls WHERE field <> some_value TRANSPORTING field.
That will change whole table.
02-07-2018 7:02 AM
Could be re-written as
DATA lt TYPE some_table.
MODIFY lt FROM VALUE #( field = some_value ) WHERE field <> some_value TRANSPORTING field.
04-18-2017 10:04 AM
Look up the documentation and examples for the constructor operators VALUE, REDUCE, FILTER, CORRESPONDING, COND, ....
You can combine them and use the same table at LHS and RHS.
itab = operator #( ... FOR wa IN itab ... )
04-18-2017 1:50 PM
Duh! It came out to be very simple. Thanks Horst, your blogs always help me!
internal_table = VALUE #( FOR <field_symbol> IN internal_table
LET lv_value = value IN
( VALUE #( BASE CORRESPONDING #( <field_symbol> ) field = lv_value ) )
).
05-04-2018 6:10 AM
There is a solution using an auxiliary table with a LET expression inside the VALUE constructor operator. See following code:
TYPES:
BEGIN OF lst_struct,
field1 TYPE i,
field2 TYPE char10,
field3 TYPE char10,
END OF lst_struct,
ltt_table TYPE STANDARD TABLE OF lst_struct WITH DEFAULT KEY.
CONSTANTS: lc_done TYPE char4 VALUE 'Done'.
DATA(lt_table) = VALUE ltt_table( ( field1 = 1 field2 = 'Test1' field3 = 'Warnigs' )
( field1 = 4 field2 = 'Test2' field3 = 'Failed' ) ).
lt_table = VALUE #( LET lt_temp = lt_table IN FOR ls_temp IN lt_temp
( field1 = ls_temp-field1
field2 = ls_temp-field2
field3 = lc_done ) ).
You cannot use the same table because the VALUE operator creates a new table (deletes all existing data) and if you try it with the addition BASE, it will enter in an infinite loop 😉
07-22-2020 12:38 PM
05-04-2018 7:09 AM
But... is that better than a loop at? Is it more readable? Does it give a performance gain?
05-30-2019 9:16 AM
Hello, Aasim Kahn,
Very usefully post,
Congrats.
I have used you code, but i had to use 2 internal tables. Can i improve that?
Look at my code:
data: lt_outsys_orderx type table of zsd_outsys_order.
select * from zsd_outsys_order into table @data(lt_outsys_order).
lt_outsys_order = value #( for <field_symbol> in lt_outsys_order let lv_value = abap_true in( value #( base corresponding #( <field_symbol> ) inproc = lv_value ) )).
Thank you.
09-18-2019 2:43 PM
Somehow this didn't work for me (resets table). So I used an auxiliary table.
data(aux_table) = VALUE #( FOR <field_symbol> IN internal_table
LET lv_value = value IN ( VALUE # ( BASE CORRESPONDING #(<field_symbol>) field = lv_value ) ) ).
internal_table = aux_table.
09-18-2019 3:21 PM
Akysh Baymuhammedov Well seen, the code posted above by Aasim Khan (more than 2 years ago) cannot work because the target is always cleared before the construction.
itab = VALUE #( FOR <field_symbol> IN itab ... " <== can't work if itab is both source & target!
11-04-2020 2:05 PM
matthew.billingham: Nope, nothing. Just some shenanigans with ABAP when new syntax was introduced!
sandra.rossi: Yeah, you're right. It doesn't work if the source and target tables are same. My bad, didn't update the post.
03-17-2021 8:17 PM
Hi sandra.rossi and horst.keller ,
the question was about how to set a field with a value for all rows of the internal table as we do with the database UPDATE SET command.
What about the old-fashioned MODIFY itab - itab_lines?
MODIFY itab FROM VALUE <itab line type>( field> = <value> ) TRANSFORTING <FIELD>.
The angle brackets (<>) are not used as field-symbols here but should be replaced by a component of the itab line for <field> and a matchimg value for <value>.
Best regards
Clemens
P.S.: My solution is the most simple one, isn't it?
PPS Late, but came over it when searching for a way to REDUCE a table to the record with the maximum value in a certain field- did not find a smart solution
03-17-2021 10:06 PM
Yes, you're right.
(NB: of course it's valid only in the form MODIFY ... FROM ... TRANSPORTING ... WHERE ..., WHERE being mandatory even if you want to update all lines, in your case you can do WHERE field NE <value>)
For REDUCE, I guess it could be something like below, but this one is really not optimum (I hope the compiler ignores max_line2 = max_line2 due to the ELSE, would be nice to check the byte code !), if it's optimized it will become more complex, so better use a classic and optimized LOOP AT.
max_line = REDUCE #(
INIT max_line2 TYPE ty_line_itab
FOR <line> IN itab
NEXT max_line2 = COND #( WHEN <line>-field > max_line2-field THEN <line>-field ) ELSE max_line2 ) .
03-17-2021 11:06 PM
Thank you Sandra. You are right about the WHERE clause. MANDT = sy-mandt or table_line is not initial?
But I think it may be easier with SELECT FROM @itab as we can use the db MAX function here... (just came into my mind)
Good night,
Clemens
07-05-2023 5:29 PM
Horst Keller, I have a doubt! I used a method to convert just one field of a table. But the other one fields stay at blanks.
The syntax that I am using is like it:
DEFINITION:
TYPES:
ty_mkal_s TYPE mkal,
ty_mkal_t TYPE TABLE OF ty_mkal_s WITH DEFAULT KEY.
METHODS:
conv_matnr_to_main
IMPORTING
VALUE(i_mkal) TYPE ty_mkal_t
RETURNING
VALUE(r_mkal) TYPE ty_mkal_t.
IMPLEMENTATION:
METHOD conv_matnr_to_main.
r_mkal = i_mkal.
r_mkal = VALUE #(
LET lt_mkal = r_mkal IN
FOR ls_mkal IN lt_mkal (
matnr = COND #( WHEN ls_mkal-matnr+11(1) NE 'A'
THEN |{ ls_mkal-matnr(11) }A| )
werks = ls_mkal-werks
)
) .
ENDMETHOD.
Main ABAP Program
DATA(lt_mkal) = me->conv_matnr_to_main( i_mkal ).
The result is all the fields in blank and the fields WERKS and MATNR are filled.Could you say how can I do it? Changing just the values of MATNR and all fields keep as before!
07-06-2023 11:40 AM
carloseduardo.santanna
Hello, While we're happy that you've come to SAP Community to get an answer to your question, you posted your question as an answer in an old thread. I've converted your answer to a comment, but even so -- posting in older threads is not the best way to get guidance. If you're looking for help, you should ask a new question: https://answers.sap.com/questions/ask.html. Here are some tips to help you craft an effective question for our community: https://community.sap.com/resources/questions-and-answers, https://developers.sap.com/tutorials/community-qa.html, https://groups.community.sap.com/t5/welcome-corner-discussions/advice-from-sap-champions-questions-a.... I encourage you to follow this guidance, as I'd really like to see you get a solution to your problem. I hope you find this advice useful!