2006 Mar 28 2:10 AM
Hello ABAPers,
I have created a sales order and I changed the order quantity over many times using Va02. If i want to programatically determine the orginal quantity, on the sales order when it was created , how would i determine ?
I thought, I would do a select query on CDPOS table and find out. But i found from se16 that for the Object ID - VERKBELEG and Object id = 00000XXXXX ( where XXXXX is sales order number), the VBEP and VBAP entries for Update mode shows no Old_vales and New_values.
But if i click on environment>Changes> in Va02 for that particular Sales order, I see the old and new values list.
Why is this not listed in CDPOS ? How do I progrmatically determine the original quanitity on Sales order ?
Thanks
SHK
2006 Mar 28 2:14 AM
Hi Shareen,
You can use this FM <b>CHANGEDOCUMENT_READ</b>.
CALL FUNCTION 'CHANGEDOCUMENT_READ'
EXPORTING
objectclass = k_orderdoc
objectid = '2938383'
TABLES
editpos = l_itab_editpos
Every standard object has owner FM to create change document. You can get all informations in transaction code <b>SCDO</b>.
Hope this will help.
Regards,
Ferry Lianto
2006 Mar 28 2:14 AM
Hi Shareen,
You can use this FM <b>CHANGEDOCUMENT_READ</b>.
CALL FUNCTION 'CHANGEDOCUMENT_READ'
EXPORTING
objectclass = k_orderdoc
objectid = '2938383'
TABLES
editpos = l_itab_editpos
Every standard object has owner FM to create change document. You can get all informations in transaction code <b>SCDO</b>.
Hope this will help.
Regards,
Ferry Lianto
2006 Mar 28 3:05 AM
Then I will sort l_itab_editpos by date and BMENG and Old_value ?
2006 Mar 28 3:28 AM
Hi Shareen,
Sorry ... I don't have SAP system now but will confirm tomorrow morning. You should be able to see new and old values based on sorting date and field name.
Regards,
Ferry Lianto
2006 Mar 28 5:15 AM
Set Object id equal to "00000XXXXX" + posnr (in form 000000) + schedule line (in form 0000). Field name = BMENG or WMENG. TABname = VBEP.
Sort ascending. The first entry contains your original qty in VALUE_OLD.
Please reward points accordingly.
2006 Mar 28 5:30 AM
Hi John Jakabcsin,
The object ID is always VERKBELEG. What u r mentioning there - "00000XXXXX" + posnr (in form 000000) + schedule line (in form 0000) - is actually the Table Key.
I think I am closer to the solution. Thanks to Ferry Lianto . A select query on CDPOS would be taxing on the system. I might prefer the FM mentioned above. Anyways, thanks for the try!
regards,
SHK
2006 Mar 28 5:32 AM
oops Object class is always VERKBELEG. Object ID is - Sales order Number (padded with 0's to make the Object ID a 10 digit number)
2006 Mar 28 2:51 PM
Sorry... did not have SAP in front of me at the time.
You NEVER want to go to CDPOS directly. You must go thru CDHDR. Here is the ABAP that will solve your problem:
select * from cdhdr into table i_cdhdr
where objectclas = 'VERKBELEG'
and objectid = i_vapma-vbeln
and change_ind = 'U'
order by udate utime username.
read table i_cdhdr index 1.
Get the change log detail record.
if sy-subrc = 0.
clear l_tabkey.
concatenate sy-mandt i_vapma-vbeln i_vapma-posnr '0001'
into l_tabkey.
select single * from cdpos
where objectclas = 'VERKBELEG'
and objectid = i_vapma-vbeln
and changenr = i_cdhdr-changenr
and tabname = 'VBEP'
and tabkey = l_tabkey
and fname = 'WMENG'
and chngind = 'U'.
if sy-subrc = 0.
output_tbl-kwmeng = cdpos-value_old. "original qty
output_tbl-alloc_qty = cdpos-value_new. "new qty
2006 Mar 29 1:49 AM
Hi John,
I tried your method first. But when i do the select query on CDPOS, the old_value and new_value fields are empty. I have a feeling that the BMENG values are not stored in CDPOS after all. I went thru the FM used by me and i saw that its getting the values from various structures like CDRED and tdinfo.Anyways, my problem is solved. Thanks for your effort. I appreciate.
Thanks,
SHK
2006 Mar 28 6:19 PM
Hi Shareen,
Yep ... you need to sort table l_itab_editpos by UDATE, UTIME (in case many changes happened in the same day), BMENG and F_OLD (old value) in order to determine original quantity.
Hope this will help.
Regards,
Ferry Lianto
2006 Mar 29 1:42 AM
Hi Ferry,
That FM did the trick. I ended up creating a FM myself to find the original qty and original unit. Somehow select qry on CDHDR and CDPOS, returned empty field for Old_value and new_value. Here is my FM below
FUNCTION z_sw_originalqty_on_so.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(I_VBELN) TYPE VBELN OPTIONAL
*" VALUE(I_POSNR) TYPE POSNR OPTIONAL
*" EXPORTING
*" VALUE(I_ORIGINAL_QTY) TYPE KWMENG
*" VALUE(I_ORIGINAL_UNIT) TYPE VRKME
*"----------------------------------------------------------------------
DATA : i_editpos TYPE TABLE OF cdred INITIAL SIZE 1 .
DATA : wa_editpos LIKE LINE OF i_editpos.
DATA : wa_editpos1 LIKE LINE OF i_editpos.
DATA : i_cdhdr TYPE TABLE OF cdhdr INITIAL SIZE 1.
DATA : i_cdpos TYPE TABLE OF cdpos INITIAL SIZE 1.
DATA : wa_cdhdr LIKE LINE OF i_cdhdr.
DATA : wa_cdpos LIKE LINE OF i_cdpos.
DATA : i_objid TYPE cdhdr-objectid.
DATA : delimiter(1) VALUE ' '.
DATA : lv_org_qty(127) TYPE c,
lv_org_unit(127) TYPE c.
DATA : l_tabkey TYPE cdpos-tabkey.
DATA : i_flag.
CLEAR i_flag.
CONCATENATE sy-mandt i_vbeln i_posnr '0001' INTO l_tabkey.
i_objid = i_vbeln .
CALL FUNCTION 'CHANGEDOCUMENT_READ'
EXPORTING
objectclass = 'VERKBELEG'
objectid = i_objid
tablekey = l_tabkey
tablename = 'VBEP'
TABLES
editpos = i_editpos
EXCEPTIONS
no_position_found = 1
wrong_access_to_archive = 2
time_zone_conversion_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
SELECT SINGLE bmeng INTO i_original_qty FROM vbep
WHERE vbeln = i_vbeln AND
posnr = i_posnr.
SELECT SINGLE vrkme INTO i_original_unit FROM vbep
WHERE vbeln = i_vbeln AND
posnr = i_posnr.
ENDIF.
SORT i_editpos BY udate utime tabname fname .
LOOP AT i_editpos INTO wa_editpos.
READ TABLE i_editpos INTO wa_editpos1
WITH KEY tabname = 'VBEP'
fname = 'WMENG'
CHNGIND = 'U'.
CLEAR : i_original_qty,i_original_unit.
IF sy-subrc EQ 0.
SHIFT wa_editpos1-f_old LEFT DELETING LEADING space.
SPLIT wa_editpos1-f_old AT delimiter INTO lv_org_qty lv_org_unit .
i_original_qty = lv_org_qty.
i_original_unit = lv_org_unit.
i_flag = 'X'.
EXIT .
ENDIF.
ENDLOOP.
sy-subrc = 4.
IF sy-subrc <> 0 AND i_flag NE 'X'.
SELECT SINGLE bmeng INTO i_original_qty FROM vbep
WHERE vbeln = i_vbeln AND
posnr = i_posnr.
SELECT SINGLE vrkme INTO i_original_unit FROM vbep
WHERE vbeln = i_vbeln AND
posnr = i_posnr.
ENDIF.
2006 Mar 29 8:10 AM
Hello Shareen,
BMENG is stored in the CDPOS table. I looked at the code which u have indicated from John. You have done only once read
read table index 1. I believe u should set a break point before read and check the number of entries in the internal table from CDHDR. I am sure they will be more than one and as u r reading only first entry it will not give u correct picture.
I have checked it on my system and it does give me the value.
2006 Mar 29 1:33 PM
Hi Abhijith,
I am not using index 1 in my case. I saw not just the first entry, but for every CDHDR entry, i saw the corresponding CDPOS entries, BMENG has got an entry, but both old and new values are blank. Maybe, it has something to do with the way our system is configured here.I also tried to see CDPOS in se16 , it has got entries for BMENG and WMENG for that sales order. But they r not filled.
Thanks,
SHK
2006 Mar 29 3:03 PM
Try setting up a breakpoint in program MV45AF0B_BELEG_SICHERN line 202 and c if the program stops when u change the qty. at line 1380 it calls to create a docuemtn change.