2007 Oct 26 7:05 AM
Hi Abap Gurus,
I have a program that return timeout error code.
The objective of the program is to fetch the latest 'Released' date from the audit trail (cdhdr & cdpos). As this is a huge table, my program return timeout error.
How do I do this?
Any good tuning tricks?
Thank you very much in advanced.
Below is the code:
REPORT zmm_kpirpt.
TABLES: cdpos,cdhdr,ekpo.
*Types for Change Document Item
TYPES: BEGIN OF type_cdpos,
objectclas TYPE cdobjectcl, "Objectclas
objectid TYPE cdobjectv, "Objectid
changenr TYPE cdchangenr, "Change Number
chngind TYPE cdchngind, "Change Type
value_old TYPE cdunit,
value_new TYPE cdunit,
tabname TYPE tabname, "Table Name
fname TYPE fname, "Field Name
mytype(2) TYPE c ,
END OF type_cdpos.
*Types for Change Document Header
TYPES: BEGIN OF type_cdhdr,
objectid TYPE cdobjectv, "Objectid
udate TYPE cddatum, "Creation date of the change document
utime TYPE cduzeit, "Time changed
mytypez(2) TYPE c,
END OF type_cdhdr.
*Types for PO & PR connection
TYPES: BEGIN OF type_ekpo,
ebeln TYPE ebeln, "Purchasing Document Number
banfn TYPE banfn, "Purchase Requisition Number
badat1 TYPE badat, "Requisition (Request) Date
bedat1 TYPE ebdat, "Purchasing Document Date
mthno TYPE i, "Month no added by lakshmi
mth(5) TYPE c,
cnt TYPE i,
tot TYPE i,
avgday TYPE i,
END OF type_ekpo.
TYPES: BEGIN OF type_mytype,
mthno TYPE i,
mth(5) TYPE c,
cnt TYPE i,
tot TYPE i,
avgday TYPE i,
END OF type_mytype.
*&----
*& Work areas Decalartion
*&----
DATA :
fs_cdpos TYPE type_cdpos,
fs_cdhdr TYPE type_cdhdr,
fs_ekpo TYPE type_ekpo,
fs_ekpo2 TYPE type_ekpo,
fs_mytype TYPE type_mytype.
*&----
*& Internal tables Decalartion
*&----
DATA:
Internal Table Purchasing Document Item
t_ekpo TYPE STANDARD TABLE OF type_ekpo,
Internal Table Purchasing Document Item
t_ekpo2 TYPE STANDARD TABLE OF type_ekpo,
Internal Table for Change Document Item
t_cdpos TYPE STANDARD TABLE OF type_cdpos,
Internal Table for Change Document Header
t_cdhdr TYPE STANDARD TABLE OF type_cdhdr,
Internal Table for Mytype
t_mytype TYPE STANDARD TABLE OF type_mytype.
*&----
*& Work variables Decalartion
*&----
DATA:
w_index TYPE i,
wa_num TYPE i,
w_mthno TYPE i.
*populating t_cdpos that matches the PO & PR crietria
IF sy-subrc EQ 0.
SELECT
objectclas
objectid
changenr
chngind
value_old
value_new
tabname
fname
FROM cdpos INTO TABLE t_cdpos
WHERE chngind EQ 'U'
AND fname EQ 'FRGKE'
AND tabname EQ 'EKKO'
AND value_new EQ 'R'.
LOOP AT t_cdpos INTO fs_cdpos.
w_index = w_index + 1.
fs_cdpos-mytype = 'PO'.
IF sy-subrc EQ 0.
MODIFY t_cdpos FROM fs_cdpos INDEX w_index TRANSPORTING mytype.
ENDIF.
ENDLOOP.
ENDIF.
CLEAR fs_cdpos.
IF sy-subrc EQ 0.
SELECT
objectclas
objectid
changenr
chngind
value_old
value_new
tabname
fname
FROM cdpos
APPENDING TABLE t_cdpos
WHERE chngind EQ 'U'
AND fname EQ 'FRGKZ'
AND tabname EQ 'EBAN'
AND value_new EQ '2'.
LOOP AT t_cdpos INTO fs_cdpos.
w_index = w_index + 1.
fs_cdpos-mytype = 'PR'.
IF sy-subrc EQ 0.
MODIFY t_cdpos FROM fs_cdpos INDEX w_index TRANSPORTING mytype.
ENDIF.
ENDLOOP.
ENDIF.
*populating t_cdhdr to get PO that match cdpos
CLEAR fs_cdpos.
LOOP AT t_cdpos INTO fs_cdpos.
SELECT objectid
udate
utime
FROM cdhdr INTO TABLE t_cdhdr
FOR ALL ENTRIES IN t_cdpos
WHERE objectid EQ t_cdpos-objectid.
ENDLOOP.
*get the most recent pr & po
SORT t_cdhdr BY objectid udate utime DESCENDING.
DELETE ADJACENT DUPLICATES FROM t_cdhdr COMPARING objectid.
SORT t_cdpos BY objectid changenr DESCENDING.
DELETE ADJACENT DUPLICATES FROM t_cdpos COMPARING objectid .
*update t_cdhdr with corresponding type (po or pr)
CLEAR fs_cdpos.
CLEAR fs_cdhdr.
CLEAR w_index.
LOOP AT t_cdpos INTO fs_cdpos.
w_index = w_index + 1.
READ TABLE t_cdhdr INTO fs_cdhdr WITH KEY objectid = fs_cdpos-objectid
BINARY SEARCH.
IF sy-subrc EQ 0.
fs_cdhdr-mytypez = fs_cdpos-mytype.
MODIFY t_cdhdr FROM fs_cdhdr INDEX w_index TRANSPORTING mytypez.
ENDIF.
ENDLOOP.
populating t_ekpo
IF sy-subrc EQ 0.
SELECT ebeln
banfn
FROM ekpo INTO TABLE t_ekpo
FOR ALL ENTRIES IN t_cdpos
WHERE ebeln EQ t_cdpos-objectid+0(10)
OR banfn EQ t_cdpos-objectid+0(10).
ENDIF.
*get only those transaction with po creation
DELETE t_ekpo WHERE banfn IS INITIAL OR banfn = '' OR ebeln IS INITIAL
OR ebeln = ''.
CLEAR w_index.
CLEAR fs_cdhdr.
LOOP AT t_ekpo INTO fs_ekpo.
w_index = w_index + 1.
READ TABLE t_cdhdr INTO fs_cdhdr WITH KEY objectid = fs_ekpo-ebeln
BINARY SEARCH.
IF sy-subrc EQ 0.
IF fs_cdhdr-mytypez ='PO'.
fs_ekpo-bedat1 = fs_cdhdr-udate.
MODIFY t_ekpo FROM fs_ekpo INDEX w_index TRANSPORTING bedat1.
ENDIF.
ENDIF.
ENDLOOP.
CLEAR w_index.
CLEAR fs_ekpo.
CLEAR fs_cdhdr.
LOOP AT t_ekpo INTO fs_ekpo.
w_index = w_index + 1.
READ TABLE t_cdhdr INTO fs_cdhdr WITH KEY objectid = fs_ekpo-banfn
BINARY SEARCH.
IF sy-subrc EQ 0.
IF fs_cdhdr-mytypez ='PR'.
fs_ekpo-badat1 = fs_cdhdr-udate.
MODIFY t_ekpo FROM fs_ekpo INDEX w_index TRANSPORTING badat1.
ENDIF.
ENDIF.
ENDLOOP.
DELETE t_ekpo WHERE bedat1 = '00000000' OR badat1 = '00000000'.
CLEAR w_index.
CLEAR fs_ekpo.
CLEAR fs_cdhdr.
LOOP AT t_ekpo INTO fs_ekpo.
w_index = w_index + 1.
IF sy-subrc EQ 0.
CASE fs_ekpo-badat1+4(2).
WHEN '01'.
fs_ekpo-mth = 'Jan'.
fs_ekpo-mthno = 1.
WHEN '02'.
fs_ekpo-mth = 'Feb'.
fs_ekpo-mthno = 2.
WHEN '03'.
fs_ekpo-mth = 'Mar'.
fs_ekpo-mthno = 3.
WHEN '04'.
fs_ekpo-mth = 'Apr'.
fs_ekpo-mthno = 4.
WHEN '05'.
fs_ekpo-mth = 'May'.
fs_ekpo-mthno = 5.
WHEN '06'.
fs_ekpo-mth = 'Jun'.
fs_ekpo-mthno = 6.
WHEN '07'.
fs_ekpo-mth = 'Jul'.
fs_ekpo-mthno = 7.
WHEN '08'.
fs_ekpo-mth = 'Aug'.
fs_ekpo-mthno = 8.
WHEN '09'.
fs_ekpo-mth = 'Sep'.
fs_ekpo-mthno = 9.
WHEN '10'.
fs_ekpo-mth = 'Oct'.
fs_ekpo-mthno = 10.
WHEN '11'.
fs_ekpo-mth = 'Nov'.
fs_ekpo-mthno = 11.
WHEN '12'.
fs_ekpo-mth = 'Dec'.
fs_ekpo-mthno = 12.
ENDCASE.
MODIFY t_ekpo FROM fs_ekpo INDEX w_index TRANSPORTING mthno
mth.
ENDIF.
ENDLOOP.
Clear the work variables
CLEAR:
w_index,
w_mthno,
fs_ekpo.
Sort the internal table based on Month.
SORT t_ekpo BY mthno.
Loop through the internal table to identify no of POs/Month
LOOP AT t_ekpo INTO fs_ekpo.
Current loop counter
w_index = sy-tabix.
For the first record assign the month value into variable
and set the counter to 1.
IF w_index EQ 1.
w_mthno = fs_ekpo-mthno.
fs_mytype-mthno = w_mthno.
fs_mytype-mth = fs_ekpo-mth.
fs_mytype-cnt = fs_mytype-cnt + 1.
fs_mytype-tot = fs_mytype-tot + fs_ekpo-bedat1 - fs_ekpo-badat1.
ELSE.
From second record onwards, check whether the month in current
record is same as that of prevous record and if found to be same
then increment the counter for no of PO's
IF fs_ekpo-mthno EQ w_mthno.
fs_mytype-cnt = fs_mytype-cnt + 1.
fs_mytype-tot = fs_mytype-tot + fs_ekpo-bedat1 - fs_ekpo-badat1.
ELSE.
If the Month value of current record is not as same as that of
previous one, then append the record count for previous month
into the final internal table, clear the work area, assign
the new month to work variable, set the counter for no of PO's
in this month to 1 again.
APPEND fs_mytype TO t_mytype.
CLEAR: fs_mytype.
w_mthno = fs_ekpo-mthno.
fs_mytype-mthno = w_mthno.
fs_mytype-mth = fs_ekpo-mth.
fs_mytype-cnt = fs_mytype-cnt + 1.
fs_mytype-tot = fs_mytype-tot + fs_ekpo-bedat1 - fs_ekpo-badat1.
ENDIF.
ENDIF.
CLEAR: fs_ekpo.
ENDLOOP.
At the end of all records final record is still not updated to
final internal table hence needs to be appended
APPEND fs_mytype TO t_mytype.
CLEAR:
fs_mytype,
w_mthno.
WRITE:/1 sy-uline(88).
Sort the internal table by internal counter (month no) which will
not be displayed at any point of time
SORT t_mytype BY mthno.
write: /1 sy-vline,
5 'Month',
20 sy-vline,
30 'No.',
37 sy-vline,
46 'Total' ,
55 sy-vline,
61 'Average',
72 sy-vline,
76 'Target',
88 sy-vline.
WRITE:/1 sy-uline(88).
LOOP AT t_mytype INTO fs_mytype.
Write out the output
fs_mytype-avgday = fs_mytype-tot div fs_mytype-cnt.
write: /1 sy-vline,
5 fs_mytype-mth,
20 sy-vline,
22 fs_mytype-cnt ,
37 sy-vline,
39 fs_mytype-tot,
55 sy-vline,
57 fs_mytype-avgday,
72 sy-vline,
79 '7',
88 sy-vline.
CLEAR: fs_mytype.
ENDLOOP.
WRITE:/1 sy-uline(88).
FREE fs_ekpo.
2007 Oct 26 7:10 AM
The time out error would mostly be occuring while selecting CDPOS records. This table contains lot number of records. Since this table contains every change record for any document.
To overcome such an issue its better to give all the keys in the WHERE clause of the SELECT.
OBJECTCLAS
OBJECTID
CHANGENR
TABNAME
TABKEY
FNAME
CHNGIND
and also in the same order.
2008 Jan 15 7:51 PM
Better to avoid modify in code and replace with field symbols that will increase performance .