1

I have internal table lt_stock with following rows:

WERKS
LGORT
MATNR
QUANTITY

I want to group WERKS LGORT and MATNR and add the QUANTITY.

I have done this using 2 loops:

LOOP AT lt_stock INTO ls_stock.

  MOVE-CORRESPONDING ls_stock TO ls_stock_key.
  CONCATENATE ls_stock-werks ls_stock-lgort ls_stock-matnr INTO ls_stock_key-key.
  APPEND ls_stock_key TO lt_stock_key.

ENDLOOP.

LOOP AT lt_stock_key INTO ls_stock_key.

  AT END OF key.
    SUM.
    APPEND ls_stock_key TO lt_stock_calculated.
  ENDAT.

 ENDLOOP.

Is it possible to do this using a single LOOP? (Example: AT END OF werks, lgort, matnr)

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Ovidiu Pocnet
  • 579
  • 12
  • 32
  • 2
    `SUM` is obsolete, and concerning `AT END OF`, SAP [says](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapat_itab.htm) (since 7.40): "If possible, the use of the addition GROUP BY is recommended, since the grouping does not depend on the structure of the lines and the processing order in this case." – Sandra Rossi Oct 20 '20 at 04:58
  • Why just not use COLLECT statement since you have only key and quantity fields? Here is the same question and some examples with alternatives to it with new group processing: https://stackoverflow.com/questions/57920458/new-abap-syntax-instead-of-collect – astentx Oct 20 '20 at 06:41
  • @astentx but I used a LOOP just to create the key and that was actually the problem. I wanted to see if it is possible to only use one LOOP. – Ovidiu Pocnet Oct 20 '20 at 06:53
  • @OvidiuPocnet You've used a loop to generate a key, but why? Just collect or group by in that loop, I've provided a link. – astentx Oct 20 '20 at 07:09

2 Answers2

2

Simple example based on LOOP...GROUP BY:

TYPES: BEGIN OF ty_stock,
        werks TYPE werks_d,
        lgort TYPE lgort_d,
        matnr TYPE matnr,
        qty  TYPE volum,
       END OF ty_stock,
       tty_stock TYPE STANDARD TABLE OF ty_stock WITH NON-UNIQUE KEY primary_key COMPONENTS werks lgort matnr.

DATA: lt_input TYPE tty_stock.
DATA(out) = cl_demo_output=>new( ).

lt_input = VALUE #( ( werks = 1000 lgort = 100 matnr = '10130101'  qty = 40 )
                    ( werks = 1000 lgort = 120 matnr = '10140101'  qty = 150 )
                    ( werks = 1000 lgort = 130 matnr = '10150101'  qty = 300 )
                    ( werks = 1000 lgort = 130 matnr = '10150101'  qty = 100 )
                    ( werks = 1000 lgort = 140 matnr = '10140101'  qty = 200 )
                    ( werks = 1000 lgort = 140 matnr = '10140101'  qty = 180 )
                    ( werks = 1000 lgort = 150 matnr = '10190101'  qty = 120 )
                    ( werks = 1000 lgort = 130 matnr = '10190101'  qty = 200 )
                    ( werks = 1000 lgort = 120 matnr = '10140101'  qty = 300 )
                    ( werks = 1000 lgort = 200 matnr = '10170101'  qty = 500 )
                  ).

DATA: qty TYPE volum.
LOOP AT lt_input ASSIGNING FIELD-SYMBOL(<fs_inp>) USING KEY primary_key GROUP BY ( werks = <fs_inp>-werks lgort = <fs_inp>-lgort matnr = <fs_inp>-matnr ) REFERENCE INTO DATA(stock).
  LOOP AT GROUP stock ASSIGNING FIELD-SYMBOL(<fs_member>).
    qty =  qty + <fs_member>-qty.
  ENDLOOP.
  out->write( stock->lgort && '/' && stock->matnr && ` qty:  ` && qty ).
  CLEAR qty.
ENDLOOP.

out->display( ).

By replacing out->write( ) with APPEND you can construct the new totals internal table instead of displaying it.

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
0

It is actually possible, but the standard way it to use the three fields (from your example) directly:

AT END OF matnr.
    SUM.
...
ENDAT.

The prerequisite is that werks, lgort and matnr are the three first fields of the internal table and the table is SORTed.

If you want to do it with a separate field (like in your example), the newly defined field (key) has to be the very first field in the internal table (this is a prerequisite for LOOP ... AT ... ENDAT actions) and the table also has to be SORTed.

József Szikszai
  • 4,791
  • 3
  • 14
  • 24