4

How do I add the values in a field based on the same values in another field using FOR loop?

Types:
Begin of ty_final,
  doctype type char5,
  posnr   type char5,
  total   type quan5,
End of ty_final.

DATA(lt_final) = VALUE ty_final( 
                     FOR line IN lt_history
                     WHERE ( hist_type = 'U' )
                     ( doctype = line-hist_type 
                       total   = line-quantity
                       posnr   = line-po_item  ) ). 

What I have in LT_HISTORY:

HIST_TYPE POSNR QUANTITY
   U       10    5
   U       10    2
   U       20    3
   U       20   -3

What I need in LT_FINAL:

DOCTYPE POSNR QUANTITY
   U    10    7
   U    20    0

I am trying to use GROUP BY to get the sum of the values in TOTAL field based on POSNR and DOCTYPE fields. It's just that I am not sure where exactly I need to add GROUP BY in my FOR loop. REDUCE makes my head spin. So I was trying out as simple as possible.

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
isekaid_maou
  • 273
  • 1
  • 9
  • 19
  • Do you insist to do this with a `VALUE` expression? It might be easier to do with a `LOOP AT ... GROUP` loop. – Philipp Jan 21 '22 at 13:14
  • Does this answer your question? [Sum Using Reduce Syntax ABAP](https://stackoverflow.com/questions/67259392/sum-using-reduce-syntax-abap) – Jonas Wilms Jan 21 '22 at 15:22
  • @JonasWilms Yes, the first thing I tried out was using `LOOP AT ... GROUP BY`. I was just wondering if the same can be done while using `FOR`. – isekaid_maou Jan 21 '22 at 15:27
  • Not really, cause you need to traverse the group twice, once to sum up and then to insert. – Jonas Wilms Jan 21 '22 at 17:58
  • 3
    If I understand well your question, simply use `VALUE tt_vbfa( FOR GROUPS ... GROUP BY ... FOR ... IN GROUP ... )`. – Sandra Rossi Jan 21 '22 at 20:00
  • @SandraRossi Can you post an answer with an example? – Philipp Jan 21 '22 at 23:47
  • I'd prefer that the OP posts first a reproducible example, so that I don't have so much work to write it myself. But well, if you challenge me. But maybe I didn't understand well the question. Let's see. – Sandra Rossi Jan 22 '22 at 09:20
  • @SandraRossi Yes, I was looking for `FOR GROUPS` only. Will it have to be a separate `FOR` or can be incorporated into the existing code? – isekaid_maou Jan 22 '22 at 09:28
  • Could you post a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) with types, data and expected result please? – Sandra Rossi Jan 22 '22 at 09:57
  • 2
    Please check now. – isekaid_maou Jan 22 '22 at 10:25

1 Answers1

6

Below is minimal reproducible example, which uses ABAP Unit (Ctrl+Shift+F10 to run it). I commented your code and replaced it with the solution:

CLASS ltc_test DEFINITION FOR TESTING
      DURATION SHORT RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS test FOR TESTING.
ENDCLASS.
CLASS ltc_test IMPLEMENTATION.
  METHOD test.
    TYPES: BEGIN OF ty_line,
             doctype  TYPE c LENGTH 1,
             posnr    TYPE i,
             quantity TYPE i,
           END OF ty_line,
           ty_table TYPE STANDARD TABLE OF ty_line WITH DEFAULT KEY.
    DATA(lt_history) = VALUE ty_table(
        ( doctype = 'U' posnr = 10 quantity = 5 )
        ( doctype = 'U' posnr = 10 quantity = 2 )
        ( doctype = 'U' posnr = 20 quantity = 3 )
        ( doctype = 'U' posnr = 20 quantity = -3 ) ).
    DATA(lt_final) = VALUE ty_table(
*                         FOR line IN lt_history
*                         WHERE ( doctype = 'U' )
*                         ( doctype  = line-doctype
*                           quantity = line-quantity
*                           posnr    = line-posnr  ) ).
                         FOR GROUPS grp_line OF line IN lt_history
                         WHERE ( doctype = 'U' )
                         GROUP BY ( doctype = line-doctype posnr = line-posnr )
                         ( doctype  = grp_line-doctype
                           quantity = REDUCE #( INIT t = 0 FOR <line> IN GROUP grp_line 
                                                NEXT t = t + <line>-quantity )
                           posnr    = grp_line-posnr  ) ).
    cl_abap_unit_assert=>assert_equals( act = lt_final exp = VALUE ty_table(
        ( doctype = 'U' posnr = 10 quantity = 7 )
        ( doctype = 'U' posnr = 20 quantity = 0 ) ) ).
  ENDMETHOD.
ENDCLASS.
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48