FUNCTION {{P}}DON_SUM IMPORTING iv_donations TYPE string EXPORTING ev_donor_count TYPE i CHANGING cv_totals TYPE string EXCEPTIONS invalid_units. TYPES: BEGIN OF ty_total, donor_id TYPE string, group_code TYPE string, total_units TYPE i, END OF ty_total. DATA lt_lines TYPE STANDARD TABLE OF string WITH EMPTY KEY. DATA lt_totals TYPE SORTED TABLE OF ty_total WITH UNIQUE KEY donor_id group_code. DATA lv_line TYPE string. DATA lv_donor TYPE string. DATA lv_group TYPE string. DATA lv_units TYPE string. DATA lv_units_int TYPE i. DATA lv_result TYPE string. DATA lv_prev TYPE string. IF iv_donations IS NOT INITIAL. SPLIT iv_donations AT cl_abap_char_utilities=>newline INTO TABLE lt_lines. ENDIF. LOOP AT lt_lines INTO lv_line. SPLIT lv_line AT ';' INTO lv_donor lv_group lv_units. lv_units_int = lv_units. IF lv_units_int < 1. RAISE invalid_units. ENDIF. lv_group = to_upper( lv_group ). READ TABLE lt_totals ASSIGNING FIELD-SYMBOL() WITH TABLE KEY donor_id = lv_donor group_code = lv_group. IF sy-subrc <> 0. INSERT VALUE #( donor_id = lv_donor group_code = lv_group total_units = 0 ) INTO TABLE lt_totals ASSIGNING . ENDIF. -total_units = -total_units + lv_units_int. ENDLOOP. LOOP AT lt_totals INTO DATA(ls_total). IF ls_total-donor_id <> lv_prev. ev_donor_count = ev_donor_count + 1. lv_prev = ls_total-donor_id. ENDIF. DATA(lv_out) = |{ ls_total-donor_id };{ ls_total-group_code };{ ls_total-total_units }|. IF lv_result IS INITIAL. lv_result = lv_out. ELSE. lv_result = lv_result && cl_abap_char_utilities=>newline && lv_out. ENDIF. ENDLOOP. cv_totals = lv_result. ENDFUNCTION.