SAP ABAP count lines in internal table with where condition
In SAP ABAP, counting lines in an internal table with a condition can be done using the REDUCE expression starting from version 7.40. Before this, developers used a LOOP to iterate over the table and increment a counter for each matching condition. An example of REDUCE for counting lines looks like this: DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab WHERE( F1 = ‘XYZ’ ) NEXT x = x + 1 ).

Ex1 REDUCE
Definition REDUCE
... REDUCE type( [let_exp] INIT {x1 = rhs1}|{ = wrexpr1}|{x1| TYPE dtype1} {x2 = rhs2}|{ = wrexpr2}|{x2| TYPE dtype2} ... FOR for_exp1 FOR for_exp2 ... NEXT ... {x1 = rhs1}|{ = wrexpr1} {x2 = rhs2}|{ = wrexpr2} ... ) ...
While VALUE
and NEW
expressions can include FOR
expressions, REDUCE
must include at least one FOR
expression. You can use all kinds of FOR
expressions in REDUCE
:
- with
IN
for iterating internal tables - with
UNTIL
orWHILE
for conditional iterations
Source: https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abenconstructor_expression_reduce.htm
Before 7.40
DATA: lv_lines TYPE i. LOOP AT gt_itab INTO ls_itab where F1 = ‘XYZ’. lv_lines = lv_lines + 1. ENDLOOP.
After 7.40
DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab WHERE( F1 = ‘XYZ’ ) NEXT x = x + 1 ).
Source: https://blogs.sap.com/2015/10/25/abap-740-quick-reference/
Example
SELECT * FROM mara INTO TABLE @DATA(lt_mara) UP TO 10 ROWS. DATA(lv_count) = REDUCE i( INIT i = 0 FOR wa IN lt_mara WHERE ( aenam EQ 'MARSLAN' ) NEXT i = i + 1 ). TYPES: BEGIN OF ty_material, matnr TYPE char40, maktx TYPE char40, matkl TYPE char9, END OF ty_material. DATA: lt_materials TYPE STANDARD TABLE OF ty_material. lt_materials = VALUE #( ( matnr = '000000000051000298' maktx = 'Description 1' matkl = 'A' ) ( matnr = '000000000051003780' maktx = 'Description 2' matkl = 'A' ) ( matnr = '000000000051008389' maktx = 'Description 3' matkl = 'B') ( matnr = '000000000051008390' maktx = 'Description 4' matkl = 'C' ) ( matnr = '000000000051008394' maktx = 'Description 5' matkl = 'B' ) ). * Simply get the unique material groups, use WITHOUT MEMBERS LOOP AT lt_materials INTO DATA(ls_materials) GROUP BY ( matkl = ls_materials-matkl size = GROUP SIZE ) ASCENDING WITHOUT MEMBERS REFERENCE INTO DATA(matkl_group). WRITE: / matkl_group->matkl, matkl_group->size. ENDLOOP.
Ex2 describe table
append lines of itab to itab1. delete itab1[] where field1 ne 'XXXX'. describe table itab1 lines w_lines. free itab1.
Ex3 LOOP AT
TYPES: BEGIN OF x_count, matnr TYPE matnr, count TYPE i, BEGIN OF x_count. DATA: i_marc TYPE STANDARD TABLE OF marc, i_count TYPE STANDARD TABLE OF x_count, wa_count TYPE x_count. FIELD-SYMBOLS: TYPE marc. SELECT * UP TO 1000 ROWS FROM marc INTO TABLE i_marc. IF sy-subrc = 0. SORT i_marc BY matnr. LOOP AT i_marc ASSIGNING . wa_count-count = wa_count-count + 1. AT END OF matnr. wa_count-matnr = -matnr. APPEND wa_count TO i_count. ENDAT. ENDLOOP. ENDIF.
Ex4 Lines (VALUE…)
TYPES: tt_mara TYPE TABLE OF mara WITH EMPTY KEY. DATA(count) = lines( VALUE tt_mara( FOR line IN lt_mara WHERE ( matnr = 'XXX' ) ( line ) ) ).
Not internal tables for comparison
Ex1n COLLECT
DATA: BEGIN OF seats, carrid TYPE sflight-carrid, connid TYPE sflight-connid, seatsocc TYPE sflight-seatsocc, END OF seats. DATA seats_tab LIKE HASHED TABLE OF seats WITH UNIQUE KEY carrid connid. SELECT carrid, connid, seatsocc FROM sflight INTO @seats. COLLECT seats INTO seats_tab. ENDSELECT.
Ex2n SELECT
select count(*) into l_count from user_master where username = l_username and process_type = processtype and password = oldpassword group by username.