Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a new syntax (740, 750, 751) to MODIFY same internal table?

aasim_khan
Participant

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!

1 ACCEPTED SOLUTION

horst_keller
Product and Topic Expert
Product and Topic Expert

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 ... )

16 REPLIES 16

former_member210008
Active Participant
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.

Could be re-written as

DATA lt TYPE some_table.
MODIFY lt FROM VALUE #( field = some_value ) WHERE field <> some_value TRANSPORTING field.

horst_keller
Product and Topic Expert
Product and Topic Expert

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 ... )

aasim_khan
Participant

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 ) )
                 ).                 

martona
Discoverer

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 😉

0 Kudos

+1 for mentioning the infinte loop caveat 🙂

matt
Active Contributor

But... is that better than a loop at? Is it more readable? Does it give a performance gain?

bruno_silva2
Explorer
0 Kudos

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.

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.

Sandra_Rossi
Active Contributor

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!

aasim_khan
Participant
0 Kudos

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.

Clemenss
Active Contributor

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

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 ) .

Clemenss
Active Contributor
0 Kudos

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

0 Kudos

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!

moshenaveh
Community Manager
Community Manager

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!