ABAP Blog Posts
cancel
Showing results for 
Search instead for 
Did you mean: 

Introduction

While preparing for modern ABAP topics, I revisited one of the classic concepts we frequently use in reporting programs—control break processing. Most ABAP developers are familiar with statements such as AT NEW, AT END OF, and SUM for calculating subtotals and grand totals. 

Recently, I explored how the same requirement can be implemented using LOOP AT GROUP BY and the REDUCE operator. My goal was to understand whether modern ABAP syntax could make the code more readable and easier to maintain compared to traditional control break statements. 

After implementing both approaches on sample MARA data, I found that the modern syntax significantly reduces the amount of procedural code required for grouping and aggregation. Although the traditional approach is still widely used and perfectly valid, the modern approach felt cleaner and easier to follow, especially when working with complex grouping scenarios. 

In this blog post, I will share the example I created, explain how grouping and subtotal calculations can be achieved using modern ABAP syntax, and highlight some observations from my implementation experience.

Step 1: Define Internal Table Structure

First, create a local structure to hold the required fields from the MARA table. 

Fields used: 

  • MATNR – Material Number 
  • MATKL – Material Group 
  • MTART – Material Type 
  • NTGEW – Net Weight 

An internal table and a variable for storing the grand total are also declared. 

Step 2: Fetch Data from Database

Read the required records from the MARA table into the internal table.

The example fetches:

  • Material Number

  • Material Group

  • Material Type

  • Net Weight

For demonstration purposes, only the first 20 records are selected.

Step 3: Sort the Internal Table

Before grouping, sort the internal table by MATNR.

Sorting ensures that records belonging to the same material are processed together and improves the readability of the output.

Step 4: Group Records Using LOOP AT GROUP BY

Modern ABAP introduces the GROUP BY addition in LOOP statements.

The following grouping logic is used:

  • Each unique MATNR becomes a group.

  • All records having the same MATNR belong to that group.

  • The group object provides access to both the group key and its members.

This eliminates the need for traditional control break statements such as AT NEW and AT END OF.

Step 5: Calculate Subtotals Using REDUCE

The REDUCE operator is used to calculate the subtotal of NTGEW within each group.

Benefits of REDUCE:

  • Compact syntax

  • Improved readability

  • Functional programming approach

  • Eliminates explicit accumulator loops

The subtotal is calculated by iterating through all members of the current group and summing their NTGEW values.

Step 6: Display Group Details

For every material group:

  • Material Number is displayed.

  • Material Group is displayed.

  • Material Type is displayed.

  • Net Weight is displayed.

The LOOP AT GROUP statement is used to access each member belonging to the current group.

Step 7: Display Subtotal

After processing all members of a group:

  • The subtotal of NTGEW is displayed.

  • A separator line is printed using ULINE.

This provides a clear summary for each material group.

Step 8: Calculate Grand Total

The subtotal of each group is added to the grand total variable. 

After all groups are processed, the final accumulated value represents the overall grand total of NTGEW. 

REPORT zrp_control_brk_stt.

TYPES: BEGIN OF ty_mara,
         matnr TYPE matnr,
         matkl TYPE matkl,
         mtart TYPE mtart,
         ntgew TYPE ntgew,
       END OF ty_mara.

DATA: lt_mara        TYPE TABLE OF ty_mara,
      lv_grand_total TYPE ntgew.

SELECT matnr,
       matkl,
       mtart,
       ntgew
  FROM mara
  INTO TABLE @LT_mara
  UP TO 10 ROWS.

IF sy-subrc = 0.
  SORT  lt_mara BY matnr.
ENDIF.

LOOP AT lt_mara ASSIGNING FIELD-SYMBOL(<fs_mara>)
     GROUP BY ( matnr = <fs_mara>-matnr )
     ASSIGNING FIELD-SYMBOL(<group>).

  Data(lv_sub_total) = REDUCE ntgew(
                        INIT lv_sum TYPE ntgew
                        FOR wa IN GROUP <group>
                        NEXT lv_sum += wa-ntgew ).

  WRITE: / 'Material:' COLOR 1 , <group>-matnr.

  LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>).

    WRITE: / 'Material Group :-' COLOR 2 , <member>-matkl,
             30 'Material Type :-' COLOR 2, <member>-mtart,
             55 'Net Weight :-' COLOR 2 , <member>-ntgew.
  ENDLOOP.

  WRITE: /  'Subtotal:' COLOR 5, 70 lv_sub_total COLOR 3.

  lv_grand_total += lv_sub_total.

  ULINE.

ENDLOOP.

WRITE: / 'Grand Total:' COLOR 5, 70 lv_grand_total COLOR 5.

Output

The report displays:

  1. Material-wise grouped records

  2. Subtotal for each Material Number

  3. Overall Grand Total

This produces a clean and structured output similar to classical control break processing while using modern ABAP syntax.

subash_k871_0-1780376801992.png

subash_k871_1-1780376973647.png

Conclusion

After implementing this example, I found that LOOP AT GROUP BY and REDUCE provide a much cleaner alternative to classical control break processing. The biggest advantage for me was eliminating multiple AT NEW and AT END OF blocks while keeping the aggregation logic compact and easy to understand.

From a learning perspective, this exercise helped me better understand ABAP's expression-oriented programming model. While traditional control break statements remain useful when maintaining older applications, I would prefer the GROUP BY and REDUCE approach for new developments because it improves readability and reduces boilerplate code.

I would be interested to know how other ABAP developers are handling subtotal and aggregation requirements in modern ABAP projects and whether they have fully transitioned away from traditional control break statements.

3 Comments
Sandra_Rossi
Active Contributor

Thanks. I also don't use AT NEW/AT END anymore and I ask my fellow developers to stop using them because they are prone to errors (developers may move fields inside the structure definition -> control break is then changed) and don't mention explicitly all fields of the control break. Explicit code is important for readability.

EDIT: you're incorrect in saying "Sorting ensures that records belonging to the same material are processed together", it's the goal of GROUP BY to process them together, SORT is needed to order the records because GROUP BY doesn't sort, e.g. if the records are as below:

NS0002
NS0001
NS0002

the order during the GROUP BY loop would be:

NS0002
NS0001

 

VXLozano
Active Contributor

I'm not used to REDUCE, and I am always frustrated when trying/using grouped LOOPs, so I'm not the best one to give his humble opinion here.

(I'd approach your "problem" with internal SQL instructions, so imagine XD)

Once said that: CLEAN ABAP is the way. Inline declarations for your table (you don't need to TYPE it), field aliases to make the code easy to read and follow and, for Pete's sake, no more hungarian naming.

Your first 32 lines of code could look like

SELECT matnr as material_number,
       matkl as material_group,
       mtart as material_type,
       ntgew as net_weight "where's the unit?????
  FROM mara
  ORDER BY matnr
  INTO TABLE @DATA(material_data)
  UP TO 10 ROWS.

and you can imagine the rest of the program...

MarcoK
Participant

As 'mara-matnr' is the primary key, each of your groups always consists of only one member. Perhaps you should use matkl or mtart for grouping in your demonstration.

Labels in this area