Search code examples
abapinternal-tables

Adding the values of a field using FOR loop


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.


Solution

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