2010 Jul 19 10:29 AM
Hi,
I had this coding:
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
* move rbkp to result
PERFORM move_rbkp.
CLEAR l_counter.
IF gs_rbkp-xrech = ' '.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4NR'.
l_counter = l_counter + 1.
ENDLOOP.
ELSEIF gs_rbkp-xrech = 'X'.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4ND'.
l_counter = l_counter + 1.
ENDLOOP.
ENDIF.
* move vbak to result
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDFORM. "select_data
In l_counter I had number for run loops (counted all) if there was more then one document.
But I needed to change coding (because it is possible to have more then one record in vbak. So I moved this part of code in the loop and code looks like this:
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
CLEAR l_counter.
* move rbkp to result
PERFORM move_rbkp.
IF gs_rbkp-xrech = ' '.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4NR'.
l_counter = l_counter + 1.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ELSEIF gs_rbkp-xrech = 'X'.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4ND'.
l_counter = l_counter + 1.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDIF.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDFORM. "select_dataand in l_counter now I do not have total run of loop but number for each run. What shoul I change in coding to have total number of loops for l_counter (of course I get it after endloop).
2010 Jul 19 11:05 AM
I guess you didn't understand the problem.
Now if I found more then one document in vbak for my WHERE clausule (let say it will be 3 docs), l_counter will handle three different numbers:
for first run of loop it will be 1,
for second run of loop it will be 2,
for third run of loop it will be 3.
And what I want is to have 3 for l_counter for each run of loop. I know that before endloop I do not know this number. But problem is how to find and enter this number before endloop.
And if I will do not make clear for l_counter it will be even worst. So, thank you but it is not the answer.
When this part of code perform move vbak:
FORM MOVE_VBAK .
gs_result-vbak_number = l_counter.
gs_result-vbak_vbeln = gs_vbak-vbeln.
gs_result-vbak_erdat = gs_vbak-erdat.
gs_result-vbak_ernam = gs_vbak-ernam.
gs_result-vbak_audat = gs_vbak-audat.
gs_result-vbak_vbtyp = gs_vbak-vbtyp.
gs_result-vbak_auart = gs_vbak-auart.
gs_result-vbak_netwr = gs_vbak-netwr.
gs_result-vbak_waerk = gs_vbak-waerk.
gs_result-vbak_vkorg = gs_vbak-vkorg.
gs_result-vbak_vtweg = gs_vbak-vtweg.
gs_result-vbak_fkara = gs_vbak-fkara.
gs_result-vbak_bstnk = gs_vbak-bstnk.
gs_result-vbak_ihrez = gs_vbak-ihrez.
gs_result-vbak_bname = gs_vbak-bname.
gs_result-vbak_kunnr = gs_vbak-kunnr.
gs_result-vbak_xblnr = gs_vbak-xblnr.
ENDFORM.was outside the loop then for l_counter I had correct value. But when I moved this into loop, then for l_counter I have total loop counter only in last record, and want to have it for each
Hi,
I had this coding:
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
* move rbkp to result
PERFORM move_rbkp.
CLEAR l_counter.
IF gs_rbkp-xrech = ' '.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4NR'.
l_counter = l_counter + 1.
ENDLOOP.
ELSEIF gs_rbkp-xrech = 'X'.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4ND'.
l_counter = l_counter + 1.
ENDLOOP.
ENDIF.
* move vbak to result
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDFORM. "select_data
In l_counter I had number for run loops (counted all) if there was more then one document.
But I needed to change coding (because it is possible to have more then one record in vbak. So I moved this part of code in the loop and code looks like this:
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
CLEAR l_counter.
* move rbkp to result
PERFORM move_rbkp.
IF gs_rbkp-xrech = ' '.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4NR'.
l_counter = l_counter + 1.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ELSEIF gs_rbkp-xrech = 'X'.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = 'Z4ND'.
l_counter = l_counter + 1.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDIF.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
APPEND gs_result TO gt_result.
ENDLOOP.
ENDFORM. "select_dataand in l_counter now I do not have total run of loop but number for each run. What shoul I change in coding to have total number of loops for l_counter (of course I get it after endloop).
2010 Jul 19 10:54 AM
>
in l_counter now I do not have total run of loop but number for each run. What shoul I change in coding to have total number of loops for l_counter (of course I get it after endloop).
Remove the CLEAR l_counter statement.
2010 Jul 19 11:05 AM
I guess you didn't understand the problem.
Now if I found more then one document in vbak for my WHERE clausule (let say it will be 3 docs), l_counter will handle three different numbers:
for first run of loop it will be 1,
for second run of loop it will be 2,
for third run of loop it will be 3.
And what I want is to have 3 for l_counter for each run of loop. I know that before endloop I do not know this number. But problem is how to find and enter this number before endloop.
And if I will do not make clear for l_counter it will be even worst. So, thank you but it is not the answer.
When this part of code perform move vbak:
FORM MOVE_VBAK .
gs_result-vbak_number = l_counter.
gs_result-vbak_vbeln = gs_vbak-vbeln.
gs_result-vbak_erdat = gs_vbak-erdat.
gs_result-vbak_ernam = gs_vbak-ernam.
gs_result-vbak_audat = gs_vbak-audat.
gs_result-vbak_vbtyp = gs_vbak-vbtyp.
gs_result-vbak_auart = gs_vbak-auart.
gs_result-vbak_netwr = gs_vbak-netwr.
gs_result-vbak_waerk = gs_vbak-waerk.
gs_result-vbak_vkorg = gs_vbak-vkorg.
gs_result-vbak_vtweg = gs_vbak-vtweg.
gs_result-vbak_fkara = gs_vbak-fkara.
gs_result-vbak_bstnk = gs_vbak-bstnk.
gs_result-vbak_ihrez = gs_vbak-ihrez.
gs_result-vbak_bname = gs_vbak-bname.
gs_result-vbak_kunnr = gs_vbak-kunnr.
gs_result-vbak_xblnr = gs_vbak-xblnr.
ENDFORM.was outside the loop then for l_counter I had correct value. But when I moved this into loop, then for l_counter I have total loop counter only in last record, and want to have it for each
2010 Jul 19 2:32 PM
Well, the simplest way at that point in the code is just to LOOP twice, the first time without field transport and set your counter then, prior to doing anything with the data. Assuming you don't have tens of thousands of records in the table, it won't be much of a performance hit. If you do have a large volume of data, then you're going to have to optimize the count process another way or collect the count as you select the data in another table. There are plenty of options.
2010 Jul 19 2:59 PM
Hi,
Simplify your coding...:
IF gs_rbkp-xrech = ' '.
lv_fkara = 'Z4NR'
ELSEIF gs_rbkp-xrech = 'X'.
lv_fkara = 'Z4ND'.
ELSE.
CLEAR lv_fkara.
ENDIF.
IF lv_fkara IS NOT INITIAL.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = lv_fkara.
AT FIRST.
l_counter = l_counter + 1. " Here what you are looking for
ENDAT.
.....
ENDLOOP.
ENDIF.
Regards, Fernando Da Ró
2010 Jul 19 3:35 PM
Fernando,
Thank you for simplify my coding.
But using AT FIRST (also AT LAST) didn't solve my situation.
I have 4 MM invoices (RBKP table). Then I search in VBAK for sales orders created for this invoices. I found 5 (for one MM invoice I have two same Sales Orders).
In previous version I was not aware that I need to display as many lines as I have Sales Orders for MM invoice. As PERFORM move_vbak was outside LOOP, l_counter was set correctly. As I added this perform in LOOP I have problems with set correctly l_counter (or even any additional counter).
When I use your proposition AT FIRST I have 1 in first line in results, and in other lines I have 0.
2010 Jul 19 5:29 PM
Hi,
I read all thread again and understood the point, ignore the AT FIRST suggestion.
In order to obtain the total number of records on VBAK at first time you need to to Brad Bohn suggestion, or use a temporary internal table that you will append to it inside the loop and update the counter field outside, in that case move to final table.
REFRESH: lt_result_temp.
LOOP AT gt_vbak INTO gs_vbak WHERE ihrez = gs_rbkp-xblnr
AND bname = gs_rbkp-sgtxt
AND fkara = lv_fkara.
l_counter = l_counter + 1.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO lt_result_temp.
ENDLOOP.
FIELD-SYMBOLS: <fs_result> TYPE gs_result.
LOOP AT lt_result_temp ASSIGNING <fs_result>.
<fs_result>-vbak_number = l_counter.
ENDLOOP.
APPEND LINES lt_result_temp TO gt_result.Regards, Fernando Da Rós
Edited by: Fernando Ros on Jul 19, 2010 6:31 PM
2010 Jul 20 1:52 PM
2010 Jul 20 1:58 PM
>
> Fernando,
>
> What type should be
lt_result_temp?
Same type as gt_result.
2010 Jul 20 1:59 PM
Hello,
As you are appending lt_result_temp to gt_result, both should have same type.
Regards
2010 Jul 20 11:43 AM
Hi,
Thank you all for your attention and advice.
I needed to rebuild report. I'm not base any more on text field search for VBAK (ihrez and bname) and make LOOP.
Now I base on NAST and CMFP records.
And code for build result table looks like this:
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_nast.
CLEAR gs_cmfp.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
CLEAR l_objky.
CLEAR l_counter.
* move rbkp to result
PERFORM move_rbkp.
CONCATENATE '$$$$' gs_rbkp-belnr gs_rbkp-gjahr '000000' INTO l_objky.
LOOP AT gt_nast INTO gs_nast WHERE objky = l_objky.
READ TABLE gt_cmfp INTO gs_cmfp WITH KEY nr = gs_nast-cmfpnr.
* Convert gs_cmfp-msgv2 to l_vbeln
IF gs_nast-cmfpnr IS NOT INITIAL.
CLEAR l_vbeln.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = gs_cmfp-msgv2
IMPORTING
OUTPUT = l_vbeln.
* Check what SO type should be searched for
IF gs_rbkp-xrech = ' '.
lv_fkara = 'Z4NR'.
ELSEIF gs_rbkp-xrech = 'X'.
lv_fkara = 'Z4ND'.
ELSE.
CLEAR lv_fkara.
ENDIF.
IF lv_fkara IS NOT INITIAL.
READ TABLE gt_vbak INTO gs_vbak WITH KEY vbeln = l_vbeln fkara = lv_fkara.
ENDIF.
* move vbak to result (without l_counter)
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result.
ELSE.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
APPEND gs_result TO gt_result.
ENDIF.
ENDLOOP.
ENDLOOP.Could you please take a look and advise me if it is simplified.
Also as I understand to use Fernando proposition, I should add l_counter in this IF
IF gs_nast-cmfpnr IS NOT INITIAL., and then copy rest of proposed code?
2010 Jul 20 2:21 PM
Your code are getting side tracked from the previous version, I'm not sure if using NAST you go to correct approuch.
Anyway, I'll focus on your code only and guessing that you know what are you doing and fetched every record outside LOOP AT gt_rbkp. Ok?
Here you are making a wrong test, because in fact you are inside the LOOP at gt_NAST, so the code below will not work.
ELSE.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
APPEND gs_result TO gt_result.
ENDIF.Other think is that you missed the l_counter update (+1) for every VBAK update, and are not updating it outside the loop...
You must review your coding there are a lot of missing points that certainly will reach erroneous and unexpected error:
- check if all READ TABLE you are using result in FOUND records, if not ignore the records. In your code you read VBAK but you didn't check if SY-SUBRC = 0 that reveals a record found.
- the same for other READ TABLES
- you are checking if found inside the loop, so you have no guarantee that what you want is what you will reach.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
- Also, check sy-subrc is only valid just after the statment, since you have many statments that can change the sy-subrc value is incorrect to use this resource to check if loop was run at least once
Before post again, do a "home work" using these tips.
2010 Jul 20 3:34 PM
Here you are making a wrong test, because in fact you are inside the LOOP at gt_NAST, so the code below will not work.
You're right that I'm inside LOOP AT gt_nast, but I need to check if correct output was created. No other option, if I want to find if Sales Order was created. Because there can be MM documents without generated output, or with error output, but we want to display them too in result table.
If I found output, then I read a message generated for tis output, where Sales Order number is stored as message variable. And my check "do I have correct output?" works for sure. Below you have full code, where you can check that this check is with IF statement.
Besides if I open IF in LOOP I can't close it outside LOOP
Other think is that you missed the l_counter update (+1) for every VBAK update, and are not updating it outside the loop...
No, I didn't missed it. I just not added it when my question was posted.
- check if all READ TABLE you are using result in FOUND records, if not ignore the records. In your code you read VBAK but you didn't check if SY-SUBRC = 0 that reveals a record found.
I my SELECT I use checks, for example:
* Get invoice headers for selection screen
SELECT belnr gjahr blart bldat budat usnam tcode cpudt xblnr bukrs lifnr waers rmwwr wmwst1 mwskz1 xrech stblg zuonr kidno bkref ername sgtxt
FROM rbkp
INTO CORRESPONDING FIELDS OF TABLE gt_rbkp
WHERE belnr IN s_belnr
AND gjahr IN s_gjahr
AND blart IN s_blart
AND bldat IN s_bldat
AND budat IN s_budat
AND usnam IN s_usnam
AND cpudt IN s_cpudt
AND cputm IN s_cputm
AND xblnr IN s_xblnr
AND bukrs IN s_bukrs
AND lifnr IN s_lifnr
AND bktxt IN s_bktxt
AND ivtyp IN gr_ivtyp
AND rbstat IN gr_rbstat.
* Set object key for MM invoices
IF LINES( gt_rbkp ) IS NOT INITIAL.
PERFORM set_objky.
* Get message status for MM invoices
SELECT *
APPENDING TABLE gt_nast
FROM nast
WHERE objky IN gr_objky
AND kschl = 'ZRIV'.
SORT gt_nast BY objky erdat eruhr.
ENDIF.,
and for sure I have there only FOUNDED results.I was trying to add also FOR ALL ENTRIES, but get error on WHERE clausue.
Here is also full BUILD_RESULT table part of code.
* Build result table
CLEAR gs_rbkp.
LOOP AT gt_rbkp INTO gs_rbkp.
CLEAR gs_result.
CLEAR gs_nast.
CLEAR gs_cmfp.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
CLEAR l_objky.
CLEAR l_counter.
* move rbkp to result
PERFORM move_rbkp.
CONCATENATE '$$$$' gs_rbkp-belnr gs_rbkp-gjahr '000000' INTO l_objky.
REFRESH: gt_result_temp.
LOOP AT gt_nast INTO gs_nast WHERE objky = l_objky.
CLEAR gs_vbak.
CLEAR gs_vbfa.
CLEAR gs_vbrk.
READ TABLE gt_cmfp INTO gs_cmfp WITH KEY nr = gs_nast-cmfpnr.
* Convert gs_cmfp-msgv2 to l_vbeln
IF gs_nast-cmfpnr IS NOT INITIAL.
l_counter = l_counter + 1.
CLEAR l_vbeln.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = gs_cmfp-msgv2
IMPORTING
OUTPUT = l_vbeln.
* Check what SO type should be searched for
IF gs_rbkp-xrech = ' '.
lv_fkara = 'Z4NR'.
ELSEIF gs_rbkp-xrech = 'X'.
lv_fkara = 'Z4ND'.
ELSE.
CLEAR lv_fkara.
ENDIF.
IF lv_fkara IS NOT INITIAL.
READ TABLE gt_vbak INTO gs_vbak WITH KEY vbeln = l_vbeln fkara = lv_fkara.
ENDIF.
* move vbak to result
PERFORM move_vbak.
READ TABLE gt_vbfa INTO gs_vbfa WITH KEY vbelv = gs_vbak-vbeln.
READ TABLE gt_vbrk INTO gs_vbrk WITH TABLE KEY vbeln = gs_vbfa-vbeln.
* move vbrk to result
PERFORM move_vbrk.
APPEND gs_result TO gt_result_temp.
ELSE.
* check if loop was run at least once
CHECK sy-subrc IS NOT INITIAL.
APPEND gs_result TO gt_result.
ENDIF.
ENDLOOP.
* create field symbol for l_counter usage
FIELD-SYMBOLS: <fs_result> TYPE ty_s_result.
LOOP AT gt_result_temp ASSIGNING <fs_result>.
<fs_result>-vbak_number = l_counter.
ENDLOOP.
APPEND LINES OF gt_result_temp TO gt_result.
ENDLOOP.
ENDFORM.
| User | Count |
|---|---|
| 3 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |