cancel
Showing results for 
Search instead for 
Did you mean: 

code logic to get number of rows of particular document in internal table

eg: if a internal table (it_example ) has documents numbers

AB001 (row 1)

AB001(row 2)

AB001(row 3)

AB002(row 4)

AB002(row 5)

AB003(row 6)

then the output should display number of rows

AB001 = 3

AB002 = 2

AB003 = 1

Accepted Solutions (1)

Accepted Solutions (1)

matt
Active Contributor

Use the COLLECT statement to summarise into a HASHED table. See documentation for details.

Answers (2)

Answers (2)

former_member184158
Active Contributor

Hello Aishwarya NA,

you can try with loop at group as Quynh said, it is new statement but I like it so much.

Just try this code.

TYPES: BEGIN OF ts_cols,
         col1 TYPE char5,
         col2 TYPE char5,
         col3 TYPE char5,
       END OF ts_cols.


TYPES: BEGIN OF ts_group_cols,
         col1 TYPE char5,
         size TYPE i,
       END OF ts_group_cols.


DATA wa TYPE ts_group_cols.
DATA tab TYPE TABLE OF ts_group_cols.


TYPES tt_cols TYPE STANDARD TABLE OF ts_cols WITH DEFAULT KEY.
DATA(lt_tab) = VALUE tt_cols(
  ( col1 = 'AB001 ' col2 = 'Test2' col3 = 'Hap' )
  ( col1 = 'AB001 ' col2 = 'Test2' col3 = 'Morg' )
  ( col1 = 'AB001 ' col2 = 'Aishw' col3 = 'Tag' )
  ( col1 = 'AB002 ' col2 = 'Ibo' col3 = 'Sund' )
  ( col1 = 'AB002 ' col2 = 'Ibrah' col3 = 'Frei' )
  ( col1 = 'AB003 ' col2 = 'Sad' col3 = 'Nix' ) ).


LOOP AT lt_tab INTO DATA(ls_col)
GROUP BY ( id = ls_col-col1
           size = GROUP SIZE )
ASCENDING REFERENCE INTO DATA(group_ref).


  wa-col1 = group_ref->*-id.
  wa-size = group_ref->*-size.
  APPEND wa TO tab.
ENDLOOP.
BREAK-POINT.


Best regards

Ebrahim

0 Kudos

thank you for the response

DoanManhQuynh
Active Contributor

one more option: LOOP AT GROUP of document with addition: SIZE to get the number of rows.

Sandra_Rossi
Active Contributor

Better say "LOOP AT ... GROUP BY", just to not confuse with "LOOP AT GROUP"

matt
Active Contributor
0 Kudos

That could well be slower than using a hashed table with collect. (Though I do like it).

Sandra_Rossi
Active Contributor

Matthew Billingham Not obvious at all. I got this measure with the following unit test: LOOP_GROUP_BY: 3596.71 < COLLECT: 4190.58. Probably that GROUP BY also uses an internal hashed table. The difference is maybe due to the fact that COLLECT fills an internal table.

INTERFACE lif_perf.
  METHODS before_measure.
  METHODS measure.
  METHODS after_measure.
  DATA title TYPE string.
ENDINTERFACE.

CLASS lcl_perf DEFINITION FOR TESTING.
  PUBLIC SECTION.
    METHODS run IMPORTING cut TYPE REF TO lif_perf.
    METHODS message.
    METHODS set_runtime_base.
    TYPES : BEGIN OF ty_measure,
              title TYPE string,
              diff  TYPE p LENGTH 8 DECIMALS 2,
            END OF ty_measure,
            ty_measures TYPE STANDARD TABLE OF ty_measure.
    DATA :
      runtime_base TYPE i,
      i1           TYPE i,
      i2           TYPE i,
      diff         TYPE i,
      diff2        TYPE p DECIMALS 2,
      measures     TYPE ty_measures.
    CONSTANTS :
      nr_of_measures      TYPE i VALUE 10,
      coeff_for_fast_code TYPE i VALUE 100.
ENDCLASS.

CLASS lcl_perf IMPLEMENTATION.
  METHOD run.
    cut->before_measure( ).
    set_runtime_base( ).
    diff = 0.
    DO nr_of_measures TIMES.
      GET RUN TIME FIELD i1.
      DO coeff_for_fast_code TIMES.
        cut->measure( ).
      ENDDO.
      GET RUN TIME FIELD i2.
      diff = diff + ( i2 - i1 ) - runtime_base.
    ENDDO.
    diff2 = diff / nr_of_measures / coeff_for_fast_code.
    cut->after_measure( ).
    APPEND VALUE ty_measure( title = cut->title diff = diff2 ) TO measures.
  ENDMETHOD.
  METHOD message.
    DATA messages TYPE string_table.
    SORT measures BY diff.
    LOOP AT measures ASSIGNING FIELD-SYMBOL(<measure>).
      APPEND |{ <measure>-title }: { <measure>-diff }| TO messages.
    ENDLOOP.
    cl_abap_unit_assert=>fail( msg = concat_lines_of( table = messages sep = | < | ) level = if_aunit_constants=>tolerable ).
  ENDMETHOD.
  METHOD set_runtime_base.
    DATA: i1 TYPE i, i2 TYPE i.
    runtime_base = 999999.
    DO 10 TIMES.
      GET RUN TIME FIELD i1.
      GET RUN TIME FIELD i2.
      i2 = i2 - i1.
      IF i2 LT runtime_base.
        runtime_base = i2.
      ENDIF.
    ENDDO.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_mycommoncode DEFINITION ABSTRACT FOR TESTING.
  PUBLIC SECTION.
    METHODS before_measure.
    TYPES : BEGIN OF ty_line1,
              value TYPE string,
            END OF ty_line1,
            ty_line1s TYPE STANDARD TABLE OF ty_line1.
    TYPES : BEGIN OF ty_line2,
              value TYPE string,
              count TYPE i,
            END OF ty_line2,
            ty_line2s TYPE STANDARD TABLE OF ty_line2.
    DATA itab1 TYPE ty_line1s.
    DATA itab2 TYPE ty_line2s.
ENDCLASS.

CLASS lcl_mycode1 DEFINITION FOR TESTING INHERITING FROM lcl_mycommoncode.
  PUBLIC SECTION.
    INTERFACES lif_perf  DATA VALUES title = 'COLLECT' .
ENDCLASS.

CLASS lcl_mycode2 DEFINITION FOR TESTING INHERITING FROM lcl_mycommoncode.
  PUBLIC SECTION.
    INTERFACES lif_perf DATA VALUES title = 'LOOP_GROUP_BY' .
ENDCLASS.

CLASS lcl_mycommoncode IMPLEMENTATION.
  METHOD before_measure.
    CLEAR itab1.
    DO 10000 TIMES.
      APPEND VALUE ty_line1( value = CONV #( sy-index MOD 50 ) ) TO itab1.
    ENDDO.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_mycode1 IMPLEMENTATION.
  METHOD lif_perf~before_measure.
    before_measure( ).
  ENDMETHOD.
  METHOD lif_perf~measure.
    CLEAR itab2.
    LOOP AT itab1 ASSIGNING FIELD-SYMBOL(<line1>).
      COLLECT VALUE ty_line2( value = <line1>-value count = 1 ) INTO itab2.
    ENDLOOP.
  ENDMETHOD.
  METHOD lif_perf~after_measure.
    ASSERT lines( itab2 ) = 50.
    LOOP AT itab2 TRANSPORTING NO FIELDS WHERE count <> 200.
      cl_abap_unit_assert=>fail( ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

CLASS lcl_mycode2 IMPLEMENTATION.
  METHOD lif_perf~before_measure.
    before_measure( ).
  ENDMETHOD.
  METHOD lif_perf~measure.
    DATA groups TYPE i.
    LOOP AT itab1 ASSIGNING FIELD-SYMBOL(<line1>)
    GROUP BY ( value = <line1>-value size = GROUP SIZE ) ASSIGNING FIELD-SYMBOL(<group1>).
      ASSERT <group1>-size = 200.
      ADD 1 TO groups.
    ENDLOOP.
    ASSERT groups = 50.
  ENDMETHOD.
  METHOD lif_perf~after_measure.
  ENDMETHOD.
ENDCLASS.

CLASS ltc_main DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS test FOR TESTING.
ENDCLASS.
CLASS ltc_main IMPLEMENTATION.
  METHOD test.
    DATA(perf) = NEW lcl_perf( ).
    perf->run( NEW lcl_mycode1( ) ).
    perf->run( NEW lcl_mycode2( ) ).
    perf->message( ).
  ENDMETHOD.
ENDCLASS.
DoanManhQuynh
Active Contributor

I used to use COLLECT in my coding but since there is new LOOP AT...GROUP BY i really enjoy it. there are some advantages like i can control the key in group, also i can "colect" not just numeric field but other things too.anw, its depend on what we working on.