Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Get summarized values based on fields. (count empty and non-empty values)

0 Kudos
280

Hello ,

My task is to summarize a field depending upon 2 primary key fields and 4 secondary fields.

e.g. 1 aa bc bb 'X'

1 aa bc bd ''

1 aa bc bb 'X'

desired o/p is

1 aa bc bb 2 0

1 aa bc bd 0 1

exactly to count the non-empty and empty fields depending on 2 primary and 4 secondary fields.

1 ACCEPTED SOLUTION

Domi
Active Contributor
173

Hi

Take this as template

TYPES: BEGIN OF ty_value,
         id   TYPE i,
         val1 TYPE char10,
         val2 TYPE char10,
         val3 TYPE char10,
         val4 TYPE char10,
       END OF ty_value,
       ty_values TYPE STANDARD TABLE OF ty_value WITH DEFAULT KEY.


TYPES: BEGIN OF ty_value_count.
        INCLUDE TYPE ty_value.
TYPES: empty  TYPE i,
       filled TYPE i,
       END OF ty_value_count,
       ty_value_counts TYPE STANDARD TABLE OF ty_value_count WITH DEFAULT KEY.
DATA: value_counts TYPE ty_value_counts.

DATA(values) = VALUE ty_values( ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_false )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true ) ).

* more classical way - easier to understand by most programmers
LOOP AT values ASSIGNING FIELD-SYMBOL(<value>) GROUP BY ( id = <value>-id val1 = <value>-val1 val2 = <value>-val2 val3 = <value>-val3 ).
  LOOP AT GROUP <value> ASSIGNING FIELD-SYMBOL(<group>).
    IF line_exists( value_counts[ id = <group>-id  val1 = <group>-val1 val2 = <group>-val2 val3 = <group>-val3 ] ).
      ASSIGN value_counts[ id = <group>-id  val1 = <group>-val1 val2 = <group>-val2 val3 = <group>-val3 ] TO FIELD-SYMBOL(<value_count>).
    ELSE.
      APPEND CORRESPONDING #( <group> EXCEPT val4 ) TO value_counts ASSIGNING <value_count>.
    ENDIF.
    IF <group>-val4 IS INITIAL.
      <value_count>-empty = <value_count>-empty + 1.
    ELSE.
      <value_count>-filled = <value_count>-filled + 1.
    ENDIF.
  ENDLOOP.
ENDLOOP.

* my preferred solution
data(rd_value_counts) = value ty_value_counts( for GROUPS <rd_group> of <rd_value> in values GROUP BY ( id = <rd_value>-id val1 = <rd_value>-val1 val2 = <rd_value>-val2 val3 = <rd_value>-val3 )
                                               ( id     = <rd_group>-id
                                                 val1   = <rd_group>-val1
                                                 val2   = <rd_group>-val2
                                                 val3   = <rd_group>-val3
                                                 empty  = REDUCE #(  INIT cnt = 0
                                                                     FOR <rd_group_value> IN GROUP <rd_group> WHERE ( val4 is initial )
                                                                     NEXT cnt = cnt + 1 )
                                                 filled = REDUCE #(  INIT cnt = 0
                                                                     FOR <rd_group_value> IN GROUP <rd_group> WHERE ( val4 is not initial )
                                                                     NEXT cnt = cnt + 1 ) ) ).

regards

Domi

2 REPLIES 2

Domi
Active Contributor
174

Hi

Take this as template

TYPES: BEGIN OF ty_value,
         id   TYPE i,
         val1 TYPE char10,
         val2 TYPE char10,
         val3 TYPE char10,
         val4 TYPE char10,
       END OF ty_value,
       ty_values TYPE STANDARD TABLE OF ty_value WITH DEFAULT KEY.


TYPES: BEGIN OF ty_value_count.
        INCLUDE TYPE ty_value.
TYPES: empty  TYPE i,
       filled TYPE i,
       END OF ty_value_count,
       ty_value_counts TYPE STANDARD TABLE OF ty_value_count WITH DEFAULT KEY.
DATA: value_counts TYPE ty_value_counts.

DATA(values) = VALUE ty_values( ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 1 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_false )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bd' val4 = abap_false )
                                ( id = 2 val1 = 'aa' val2 = 'bc' val3 = 'bb' val4 = abap_true ) ).

* more classical way - easier to understand by most programmers
LOOP AT values ASSIGNING FIELD-SYMBOL(<value>) GROUP BY ( id = <value>-id val1 = <value>-val1 val2 = <value>-val2 val3 = <value>-val3 ).
  LOOP AT GROUP <value> ASSIGNING FIELD-SYMBOL(<group>).
    IF line_exists( value_counts[ id = <group>-id  val1 = <group>-val1 val2 = <group>-val2 val3 = <group>-val3 ] ).
      ASSIGN value_counts[ id = <group>-id  val1 = <group>-val1 val2 = <group>-val2 val3 = <group>-val3 ] TO FIELD-SYMBOL(<value_count>).
    ELSE.
      APPEND CORRESPONDING #( <group> EXCEPT val4 ) TO value_counts ASSIGNING <value_count>.
    ENDIF.
    IF <group>-val4 IS INITIAL.
      <value_count>-empty = <value_count>-empty + 1.
    ELSE.
      <value_count>-filled = <value_count>-filled + 1.
    ENDIF.
  ENDLOOP.
ENDLOOP.

* my preferred solution
data(rd_value_counts) = value ty_value_counts( for GROUPS <rd_group> of <rd_value> in values GROUP BY ( id = <rd_value>-id val1 = <rd_value>-val1 val2 = <rd_value>-val2 val3 = <rd_value>-val3 )
                                               ( id     = <rd_group>-id
                                                 val1   = <rd_group>-val1
                                                 val2   = <rd_group>-val2
                                                 val3   = <rd_group>-val3
                                                 empty  = REDUCE #(  INIT cnt = 0
                                                                     FOR <rd_group_value> IN GROUP <rd_group> WHERE ( val4 is initial )
                                                                     NEXT cnt = cnt + 1 )
                                                 filled = REDUCE #(  INIT cnt = 0
                                                                     FOR <rd_group_value> IN GROUP <rd_group> WHERE ( val4 is not initial )
                                                                     NEXT cnt = cnt + 1 ) ) ).

regards

Domi

0 Kudos
173

Thanks Domi,

I got your Logic.

Regards,

Raj.