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: 

How to count the per group-entries and put them in the new table

Former Member
0 Kudos

Hello Guru,

I want to sort the table cdhdr.

for example :

SELECT objectclas objectid changenr *******

INTO TABLE cdhdr_data

FROM cdhdr

WHERE ( ********) AND

objectclas = i_objectclas

*******.

The problem that I need to order the table by objectclas and objectid.

Let say objectclas is always MATERIAL.

Let's assume our key is changenr. May be our key will change to "objectclas objectid".

So, my problem that I need to get the number of the same "objectid" with different "changenr".

And also I need to put the count number of each object id with different changenr in the table cdhdr_data.

For example

objectclas objectid changenr count

MATERIAL 00***001 1 3

MATERIAL 00***001 4 3

MATERIAL 00***001 7 3

MATERIAL 00***005 2 2

MATERIAL 00***005 6 2

MATERIAL 00***003 5 2

MATERIAL 00***003 3 2

So later I'm going to use it.

LOOP AT cdhdr_data FROM sy-tabix TO ( sy-tabix + cdhdr_dat ( sy-tabix ) + count - 1 )

***

some optimized cdpos processing

**

IF entry found.

*don't loose time

*change the boundery

  • sy-tabix = count

ENDIF.

ENDLOOP.

Best Regards,

Kais

6 REPLIES 6

Former Member
0 Kudos

Hi,

Your code is a bit difficult to understand, but you can go like this....

Since Objectid is constant ...you can use at new for Objectclas & Changenr ..and Count for the CDHDR records wihch are having same Objectid but different Changenr....

0 Kudos

Hi Ajay,

Thanks for replying.

The problem that I will loose the changenr and later I need the changenr for the cdpos table.

Another idea will be

o_objectid = 0**00.

LOOP AT cdhdr_data TO l_cdhdr.

IF l_cdhdr-object NE o_objectid.

***

cdpos processing

****

IF entry found.

keep in your mind the objectid in o_objectid.

ENDIF.

ENDIF.

ENDLOOP.

So, I will process only one of the same objectid having different changenr.

Therefore I'll gain huge performance.

The problem that I need to select an objectid from cdhdr.

select entries in the cdpos with the objectid and the changenr.

Then see there if the tabname and fieldname is corresponding to some entries in an external table x_table.

**this also is optimized.

If I found the entry I don't need to see any more.

I need to ignore the hole coming same objectid.

And continue.

The table muss be sorted by objectclas and objectid.

Regards,

Kais

0 Kudos

Hi,

This is how it looks like.

Hints : It's not optimal because I save everytime the last o_objectid which will be ignored.

I rather prefer to use the previous original solution proposed by me.

How can I then implement it ?


FORM find_cdpos_data_new_modified
  TABLES
    i_otf_objcs TYPE STANDARD TABLE
  USING
    i_cdhdr_data TYPE SORTED TABLE
    i_objcl TYPE j_objnr
    i_option TYPE c
  CHANGING
    i_global TYPE STANDARD TABLE.

  " Hint: cdpos is a cluster-table

  CONSTANTS : objectid TYPE string VALUE 'objectid = <i_obj_lst>-objectid',
              changenr TYPE string VALUE 'changenr = <i_obj_lst>-changenr',
              tabname TYPE string VALUE 'tabname = i_otf_objcs-tablename',
              tabnameo1 TYPE string VALUE 'tabname NE ''''',
              tabnameo2 TYPE string VALUE 'tabname NE ''DRAD''',
              fname TYPE string VALUE 'fname = i_otf_objcs-fieldname'.

  DATA : BEGIN OF i_object_list OCCURS 0,
            objectclas LIKE cdpos-objectclas,
            objectid LIKE cdpos-objectid,
            changenr LIKE cdpos-changenr,
            tabname LIKE cdpos-tabname,
            fname LIKE cdpos-fname,
         END OF i_object_list.

  DATA : i_cdpos LIKE TABLE OF i_object_list WITH HEADER LINE.

  DATA : tabnamev2 TYPE string.

  DATA : st_flag_entry TYPE c.
  DATA : o_objectid TYPE cdhdr-objectid.

  FIELD-SYMBOLS : <otf> TYPE ANY,
                  <otf_field_tabname>,
                  <otf_field_fname>,
                  <o_objectid>,
                  <i_obj_lst> TYPE ANY.

  IF i_option EQ 'X'.
    MOVE tabnameo2 TO tabnamev2.
  ELSE.
    MOVE tabnameo1 TO tabnamev2.
  ENDIF.

  o_objectid = 0.

  LOOP AT i_cdhdr_data ASSIGNING <i_obj_lst>.
    st_flag_entry = ''.

    ASSIGN COMPONENT 'OBJECTID' OF STRUCTURE <i_obj_lst> TO <o_objectid>.
    IF <o_objectid> NE o_objectid.

      SELECT objectid tabname fname
          INTO CORRESPONDING FIELDS OF TABLE i_cdpos
          FROM cdpos
          WHERE objectclas = i_objcl AND
                (objectid) AND
                (changenr) AND
                (tabnamev2).

      ASSIGN LOCAL COPY OF i_otf_objcs TO <otf>.

      LOOP AT i_cdpos.

        LOOP AT i_otf_objcs INTO <otf>.
        
          ASSIGN COMPONENT 'TABLENAME' OF STRUCTURE <otf> TO <otf_field_tabname>.
          ASSIGN COMPONENT 'FIELDNAME' OF STRUCTURE <otf> TO <otf_field_fname>.
          
          IF ( <otf_field_tabname>  EQ i_cdpos-tabname ) AND ( <otf_field_fname> EQ i_cdpos-fname ).
            APPEND i_cdpos-objectid TO i_global.
            st_flag_entry = 'X'.
            MOVE i_cdpos-objectid TO o_objectid.
            EXIT.
          ENDIF.

        ENDLOOP.

        IF st_flag_entry EQ 'X'.
          EXIT.
        ENDIF.

      ENDLOOP.
      
    ENDIF.
    
  ENDLOOP.


ENDFORM.                    "find_cdpos_data_new_modified

MarcinPciak
Active Contributor
0 Kudos

If I get you right you want to count entries per group. Instead of this complicated code you can easily achieve it by this logic:

So, my problem that I need to get the number of the same "objectid" with different "changenr".

And also I need to put the count number of each object id with different changenr in the table cdhdr_data.

- define your table like this

types: begin of t_cdhdr_data,
            objectclas type ...
            objectid type ...
            changenr type... 
            count type ...
      end of t_cdhdr_data.
data: cdhdr_data type table of t_cdhdr_data with key objectclas objectid changenr with header line.  "your key is important,use this one as suggested

- now use select


select objectclas objectid changenr from ... into cdhdr_data cdhdr_data where .... "don't such condition here objectclas = i_objectclas
insert into cdhdr_data from cdhdr_data. "insert only unique key entries
endselect.

- now you will have similar entries to your desired

objectclas objectid changenr count

MATERIAL 00***001 1 3

MATERIAL 00***001 4 3

MATERIAL 00***001 7 3

MATERIAL 00***005 2 2

MATERIAL 00***005 6 2

MATERIAL 00***003 5 2

MATERIAL 00***003 3 2

but count field for all entries will be equal 0.

- just count your entries


data: st_index like sy-tabix, count type i.
loop at cdhdr_data.
at new objectid.
  "remember start position
  st_index = sy-tabix. 
endat

at end of objectid.
  count = sy-tabix - st_index + 1. "count accual position
  cdhrd_data-count = count. "now you have how many entries are in each objectid
  modify table cdfdr_data from cdhdr_data. 
endat.
endloop.

Edited by: Marcin Pciak on Oct 19, 2008 3:14 PM

0 Kudos

Hi Marcin,

Thanks for replying.

I'm having a trouble.

Let say I got an error on insert into ****.

It says me that the object (i_)cdhdr_data is not known.

Why, should I avoid to put objectclas = i_objectclas there.

I need to have MATERIAL OR DOKUMENT.

I can't just put 10000entries like that.

I'm also sceptic about how much this operation will cost.

Because I need to proceed the data with cdpos.

And This's why I'm doing that.

Later with this implementation I'm gone use LOOP AT *** FROM sy-tabix TO ****.

If I use my method, it will cost lower than inserting, changing, ...

I rather ignore the objectid and don't make any processing.

But with your solution I can say its rapidly.

Let assume there's n entries in cdhdr and m entries per n in cdpos.

So my algorithm will select n entries and will follow n*m entries but some of them will be proceeded an other not.

in cdhdr :

for n entries : n * 1 selecting

in cdpos :

always : n*m comparing,

processing between : n1 - nm

With you algorithm we will do :

in cdhdr :

for n entries : n* (1 selection + 1 modifing + 1 appending) <=> each operation cost O(1)

in cdpos :

for comparing between : n1 - nm

processing between : n1 - nm

Let see the middle value :

your case :

in cdhdr we have : n * O(3) ~ n * O(1) ~ O(n)

in cdpos :

O(c(nm)/2) + O(p(nm))2) ~ O((cp)((nm)/2)) ~ O(d(nm)) d= (cp)/2 ~ p/2

we know that O(c*n) ~ O (n) ; c ist a constant

c : comparing cost

p : processing cost

p >> c

my case :

in cdhdr we have : n * O(1) ~ O(n)

in cdpos :

O(c(nm)) + O(p((nm)/2)) ~ ? maybe O(d(nm)) d = c + (p/2) ~ p/2

c : comparing cost

p : processing cost

p >> c

Ok, this in theorie, but in reality I've no idea.

Is there a mathematician there ?

Regards,

Kais


FORM get_cdhdr_data_modified_1
  USING
    i_from_date TYPE dats
    i_from_time TYPE terf
    i_to_date TYPE dats
    i_to_time TYPE terf
    i_objectclas TYPE j_objnr
  CHANGING
    cdhdr_data TYPE SORTED TABLE.

types: begin of t_cdhdr_data,
            objectclas type cdhdr-objectclas,
            objectid type cdhdr-objectid,
            changenr type cdhdr-changenr,
            count type i,
      end of t_cdhdr_data.

  DATA : i_cdhdr_data type table of t_cdhdr_data with key objectclas objectid changenr with header line.

  DATA: st_index LIKE sy-tabix, count TYPE i.

  SELECT objectclas objectid changenr
  INTO TABLE i_cdhdr_data
  FROM cdhdr
  WHERE ( ( udate GT i_from_date AND udate LT i_to_date ) OR
          ( udate EQ i_from_date AND udate NE i_to_date AND utime GE i_from_time ) OR
          ( udate EQ i_to_date AND ( udate NE i_from_date OR utime GE i_from_time ) AND utime LE i_to_time )
        ) AND
        objectclas = i_objectclas.
  INSERT INTO i_cdhdr_data FROM i_cdhdr_data.
ENDSELECT.

LOOP AT i_cdhdr_data.
  AT NEW objectid.
    "remember start position
    st_index = sy-tabix.
  endat

  at end of objectid.
  count = sy-tabix - st_index + 1. "count accual position
  cdhrd_data-count = count. "now you have how many entries are in each objectid
  MODIFY TABLE i_cdhdr_data FROM i_cdhdr_data.
ENDAT.
ENDLOOP.

0 Kudos

Hi,

Can anyone tell me why it's not possible to use insert and modifiy in this code.

and why the count can't be updated.

Regards,

Kais


FORM get_cdhdr_data_modified_1
  USING
    i_from_date TYPE dats
    i_from_time TYPE terf
    i_to_date TYPE dats
    i_to_time TYPE terf
    i_objectclas TYPE j_objnr
  CHANGING
    i_cdhdr_data TYPE ANY TABLE.

  TYPES: BEGIN OF t_cdhdr_data,
              objectclas TYPE cdhdr-objectclas,
              objectid TYPE cdhdr-objectid,
              changenr TYPE cdhdr-changenr,
              count TYPE i,
        END OF t_cdhdr_data.

  DATA : cdhdr_data TYPE STANDARD TABLE OF t_cdhdr_data WITH KEY objectclas objectid changenr WITH HEADER LINE.

  DATA: st_index LIKE sy-tabix, count TYPE i.

  SELECT objectclas objectid changenr
  INTO cdhdr_data
  FROM cdhdr
  WHERE ( ( udate GT i_from_date AND udate LT i_to_date ) OR
          ( udate EQ i_from_date AND udate NE i_to_date AND utime GE i_from_time ) OR
          ( udate EQ i_to_date AND ( udate NE i_from_date OR utime GE i_from_time ) AND utime LE i_to_time )
        ) AND
        objectclas = i_objectclas.
    IF sy-subrc EQ 0.
      APPEND cdhdr_data TO cdhdr_data.
    ENDIF.

  ENDSELECT.

  LOOP AT cdhdr_data.
    AT NEW objectid.
      "remember start position
      st_index = sy-tabix.
    ENDAT.

    AT END OF objectid.
      count = sy-tabix - st_index + 1. "count accual position
      cdhdr_data-count = count. "now you have how many entries are in each objectid
      MODIFY TABLE cdhdr_data FROM cdhdr_data.
    ENDAT.
  ENDLOOP.

ENDFORM.                    "get_cdhdr_data