Application Development and Automation 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: 
Read only

is this code correct - logic wise and performance wise

Former Member
0 Likes
1,387

Hello,

<u><b>scenario:</b></u> iterating through bkpf to get all the document within a selected range of dates and document type 'KZ' . Then iterating through bseg(where belnr = belnr of the retrieved records from bkpf). Then looping through the selected bseg records and picking out the line items. In this loop i have to display the vendor line item's WRBTR(KOART = 'K') and other line item's WRBTR.

<u><b>The code is sumthing lyke:</b></u>

select * from bkpf into t_bkpf where document type ='KZ' and bldat in s_bldat.

select single * from bseg into wa_bseg where belnr = t_bkpf-belnr.

append wa_bseg to t_bseg.

endselect.

loop at t_bseg into wa_bseg.

at new belnr.

// is this following also correct or wrong

if KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

endloop.

I know this will comsume yur time, but if anyone is kind enuf to help me out or guide me through.

Thanks,

Shehryar

12 REPLIES 12
Read only

Former Member
0 Likes
1,277

There are issues with the code.

Performance can be improved for the program. Instead of select * from bkpf you can use select belnr from bkpf as

you are using only that field and instead of select,endselect and calling bseg inside it you change it as select all the belnr into an internal table and then do a for all entries query on bseg.

at new belnr.

// is this following also correct or wrong

if KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

This code will not work becuase when you do a at new belnr

the remaining all the fields in the work are will have ***

instead you can write it like this .

DATA : v_flag type c.

loop at t_bseg into wa_bseg.

at new belnr.

v_flag = 'X'.

endat.

if v_flag eq 'X'.

if wa_bseg-KOART EQ 'K'.

//Your logic

ELSE.

//Your logic

ENDIF.

clear v_flag.

endif.

endloop.

Read only

0 Likes
1,277

Thank Sudir.

refreshing the thread to get more view on this.

Read only

Former Member
0 Likes
1,277

1. BKPF will generally have a lot of entries, its better if you can make use of any of the secondary indexes.

One of the index is combination of fields

BUKRS, BSTAT, BUDAT. So if you can populate some values to BUKRS and BSTAT then your select can improve a lot.

2. I wouldnt suggest:

SELECT BKPF

SELECT BSEG.

ENDSELECT.

instead:

SELECT BKPF into <interal table1>

SELECT BSEG into <internal table2> for all entries in BKPF where <all the common fields>.

Read only

0 Likes
1,277

Hello.

Sharath, what abt the 'loop at' and 'at new' logic ?

Read only

0 Likes
1,277

Hi,

If there are existing secondary indices for BKPF, use that. Also, try to avoid select * since it will consume more time. Its much better to specify the fields explicitly. In your loop, you can use field-symbols to improve performance. Please look at the code below:

LOOP AT it_equz ASSIGNING <fs_equz>.

  • get functional location and put in it_finaltab

READ TABLE it_iloa WITH TABLE KEY iloan = <fs_equz>-iloan

INTO wa_iloa.

IF sy-subrc = 0.

wa_finaltab-funcloc = wa_iloa-tplnr.

ENDIF.

  • if value is present in s_anln1, continue.

IF s_anln1[] IS INITIAL.

---FOR RECORDS IN IT_EQUZ WITH A VALUE IN HEQUI---

IF NOT <fs_equz>-hequi IS INITIAL.

v_flag = 1.

  • check whether current hequi has already been processed

READ TABLE it_equz_dum WITH TABLE KEY hequi = <fs_equz>-hequi

INTO wa_equz_dum.

  • if not found, continue processing

IF sy-subrc <> 0.

wa_equz_dum = <fs_equz>-hequi.

INSERT wa_equz_dum INTO TABLE it_equz_dum.

CALL METHOD me->get_asset

EXPORTING equip_num = <fs_equz>-hequi

IMPORTING check = lv_check.

IF lv_check <> 'N'.

wa_finaltab-asset_dum = iloa-anlnr.

wa_finaltab-asset = iloa-anlnr.

wa_finaltab-description = eqkt-eqktx.

  • check whether current asset exists in ANLA

SELECT SINGLE anln1 anln2 ord42

FROM anla

INTO (wa_anla-anln1, wa_anla-anln2, wa_anla-ord42)

WHERE anln1 EQ wa_finaltab-asset

AND bukrs IN r_iwerk

AND deakt EQ '00000000'.

  • if not found, delete current record. Else, continue

IF sy-subrc = 0.

wa_finaltab-asset_sub = wa_anla-ord42.

CONCATENATE: wa_anla-anln1 '-' wa_anla-anln2

INTO wa_finaltab-asset_subnum.

ELSE.

DELETE it_equz WHERE equnr = <fs_equz>-equnr.

CLEAR: v_flag, wa_finaltab.

CONTINUE.

ENDIF.

READ TABLE it_t499s WITH TABLE KEY werks = wa_iloa-swerk

stand = wa_iloa-stort

INTO wa_t499s.

IF sy-subrc = 0.

wa_finaltab-location = wa_t499s-ktext.

ENDIF.

  • get records from ANLC based from current asset

SELECT gjahr kansw knafa kaafa answl nafav

nafag nafal aafav aafag nafap aafap

FROM anlc UP TO 1 ROWS

INTO (wa_anlc-gjahr, wa_anlc-kansw, wa_anlc-knafa,

wa_anlc-kaafa, wa_anlc-answl, wa_anlc-nafav,

wa_anlc-nafag, wa_anlc-nafal, wa_anlc-aafav,

wa_anlc-aafag, wa_anlc-nafap, wa_anlc-aafap)

WHERE anln1 = wa_anla-anln1

AND anln2 = wa_anla-anln2

AND bukrs IN r_iwerk

AND afabe = '01'

ORDER BY gjahr DESCENDING.

ENDSELECT.

wa_finaltab-accq_cost = wa_anlc-kansw + wa_anlc-answl.

IF p_posdep = 'X'.

wa_finaltab-acc_dep = wa_anlc-knafa +

wa_anlc-nafav +

wa_anlc-nafag +

wa_anlc-kaafa +

wa_anlc-aafav +

wa_anlc-aafag +

wa_anlc-nafal.

ELSE.

wa_finaltab-acc_dep = wa_anlc-knafa +

wa_anlc-nafav +

wa_anlc-kaafa +

wa_anlc-aafav +

wa_anlc-nafap +

wa_anlc-aafap.

ENDIF.

wa_finaltab-asset_book_val = wa_finaltab-accq_cost +

wa_finaltab-acc_dep.

ELSE.

lv_check = 'Y'.

ENDIF.

APPEND wa_finaltab TO it_finaltab.

CLEAR: wa_finaltab, wa_anla, wa_anlc, wa_iloa, eqkt, equz.

ENDIF.

ENDIF.

ENDIF.

Hope this helps...

P.S. Please award points for useful answers.

Read only

0 Likes
1,277

Hello,

Sharath, can u demonstrate how to achieve the following(u told) with a example.

SELECT BKPF into <interal table1>

SELECT BSEG into <internal table2> for all entries in BKPF where <all the common fields>.

what will be types n all..

Thanks..

Read only

Former Member
0 Likes
1,277

I think you can even use the below to simplify the code and efficient.

SELECT {list of fields required in your report from BKPF and BSEG}

INTO ITAB.

FROM BKPF AS A INNER JOIN BSEG AS B

ON ABUKRS = BBUKRS AND

ABELNR = BBELNR AND

AGJAHR = BGJAHR

WHERE ABLART = 'KZ' AND ABLDAT IN S_BLDAT.

U would need to initialise a variable for KOART as it would starred(*) during the AT NEW EVENT.

LOOP AT ITAB.

l_koart = itab-koart.

at new belnr.

if L_KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

ENDLOOP.

Regards

Anurag

Read only

0 Likes
1,277

Hi Anurag,

I aint getting anything when i give the condition for KOART = 'K'.

LOOP AT ITAB.

l_koart = itab-koart.

at new belnr.

if L_KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

ENDLOOP.

why and how ?

Read only

0 Likes
1,277

refreshing thread. can someone query the above problem ?

thanking in anticipation.

Shehryar Dahar

Read only

0 Likes
1,277

Please check couple of things..first you have selected the B~koart field in the select. Secondly, you have defined ITAB with header.

If yes, to above questions than pls paste you code and I can check it.

Regards

Anurag

Read only

0 Likes
1,277

Hi Anurag,

the code is.

elect * from bkpf into t_bkpf where document type ='KZ' and bldat in s_bldat.

select single * from bseg into wa_bseg where belnr = t_bkpf-belnr.

append wa_bseg to t_bseg.

endselect.

loop at t_bseg into wa_bseg.

at new belnr.

// is this following also correct or wrong

if KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

endloop.

basically what i wanna do is, iterate through bkpf whose bldat lies in the selected range and document type = 'KZ' , then iterate thru bseg for all entries(retrieved from bkpf). then loop thru these items(from bseg) and select vendor line item and other line items separately(cuz i have to show them in different columns).

but when i do,

AT NEW BELNR.

IF bseg-KOART EQ 'K'.

//

ENDIF.

ENDAT.

i am getting no value, whereas i get value when i remove the 'AT NEW BELNR' condition.

Thanks,

Shehryar Dahar

Read only

0 Likes
1,277

Hello Shehryar,

I would still advice you to use the SELECT statement with join. U can check the run time analysis or SQL Trace to understand which is efficient (My bet would be on the below as it is usually better to use one statement than nesting of loops.

SELECT {list of fields required in your report from BKPF and BSEG}

INTO T_BSEG.

FROM BKPF AS A INNER JOIN BSEG AS B

ON ABUKRS = BBUKRS AND

ABELNR = BBELNR AND

AGJAHR = BGJAHR

WHERE ABLART = 'KZ' AND ABLDAT IN S_BLDAT.

Ok as far as the Loop condition is concerned, it should as follows ...

loop at t_bseg into wa_bseg.

L_KOART = WA_BSEG-KOART.

at new belnr.

// is this following also correct or wrong

if L_KOART EQ 'K'.

// pick up vendor's WRBTR

ELSE

// pick up other line item's WRBTR ( how ?? )

endif.

endat.

endloop.

I feel the reason you are not able to see the value is due to the fact that KOART gets started out on AT NEW event and also you can use BSEG-KOART since you are looping the T_BSEG internal table(while BSEG-KOART would be indicating the last record value)

Regards

Anurag