04-18-2012 1:03 PM
Hi friends.
I want to find a FM or piece of reusable code which gives me the values user have changed and the previous values a material master was having.
Like we have XVBAP and YVBAP in sales order for storing new and old values
Thanks
Kanishak
04-19-2012 2:43 PM
Look at FM 'CHANGEDOCUMENT_READ'!
The objectclass you can find by table TCDOB or by transaction SCDO, e.g. 'MATERIAL' or 'MAT_FULL'.
ml
04-18-2012 3:36 PM
Search the FORUM!! Change management in SAP is accomplished through entries in tables CDHDR (header including who did, when and how) which then gives you the key to read CDPOS (details, including old and new). If you want to see how built, I would suggest that you make a small change in your development or test system, then go to SE11 for CDHDR and find what you just did with your userid. Those values are then the key to read CDPOS to see what changed and what is was before it was changed. A cautionary note: use the primary indices...there will be millions of records in a mature SAP instance.
There may be an FM...I've never used that...simple coding to get what you want.
04-18-2012 3:49 PM
Dear Kanishak Gupta,
I completely agree with Mr. Break Point. I have done the same. That is fetching data from tables CDHDR and CDPOS. Here is my code. you may make use of it. Thank you.
REPORT zsf_material_history.
*----------------------------------------------------------------------*
* FIELD SYMBOL DECLARATION
*----------------------------------------------------------------------*
FIELD-SYMBOLS:
<fs_select> TYPE ANY ,
<fs_field> TYPE ANY .
*----------------------------------------------------------------------*
* TYPES DECLARATION
*----------------------------------------------------------------------*
* Type of history table
TYPES: BEGIN OF ty_history,
material TYPE cdobjectv , " Material Number
changed_on TYPE cddatum , " Change Date
changed_by TYPE cdusername , " Change User Name
field TYPE fieldname , " Changed Field
old_value TYPE cdfldvalo , " Old Value
new_value TYPE cdfldvaln , " New Value
END OF ty_history,
* Type declaration to retrieve data from header cdhdr
BEGIN OF ty_ch_number ,
material TYPE cdobjectv , " Material Number
change_number TYPE cdchangenr , " Change Number
change_user TYPE cdusername , " Changed User
change_date TYPE cddatum , " Changed Date
END OF ty_ch_number ,
* Type declaration to retrieve data from Item table cdpos
BEGIN OF ty_ch_item ,
change_number TYPE cdchangenr , " Change Number
change_field TYPE fieldname , " Changed Field
change_old TYPE cdfldvalo , " Old Value
change_new TYPE cdfldvaln , " New Value
END OF ty_ch_item .
*----------------------------------------------------------------------*
* INTERNAL TABLE AND WORK AREA DECLARATION
*----------------------------------------------------------------------*
DATA:
* Declaration of history internal table and work area
lt_history TYPE STANDARD TABLE OF ty_history ,
ls_history TYPE ty_history ,
* Item internal table to fetch values from item table
lt_ch_item TYPE STANDARD TABLE OF ty_ch_item ,
ls_ch_item TYPE ty_ch_item ,
* Header Internal table to fetch data from Header table
lt_ch_number TYPE STANDARD TABLE OF ty_ch_number ,
ls_ch_number TYPE ty_ch_number ,
* ALV layout
ls_layout TYPE lvc_s_layo ,
* ALV Field catalog
lt_fieldcat TYPE STANDARD TABLE OF lvc_s_fcat ,
ls_fieldcat TYPE lvc_s_fcat .
*----------------------------------------------------------------------*
* CONSTANTS DECLARATION
*----------------------------------------------------------------------*
CONSTANTS:
c_material TYPE char8 VALUE 'MATERIAL' ,
c_x TYPE char01 VALUE 'X' .
* Selection Screen Declaration
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_matnr FOR ls_ch_number-material , " Material Number
s_chdat FOR ls_ch_number-change_date . " Changed Date
SELECTION-SCREEN END OF BLOCK b1 .
*----------------------------------------------------------------------*
* AT SELECTION SCREEN
*----------------------------------------------------------------------*
AT SELECTION-SCREEN.
IF sy-ucomm = 'ONLI'.
* Material Number is mandatory
IF s_matnr IS INITIAL.
MESSAGE 'Please enter Material Number'(e01) TYPE 'E'.
ENDIF.
ENDIF.
*----------------------------------------------------------------------*
* START OF SELECTION
*----------------------------------------------------------------------*
START-OF-SELECTION.
LOOP AT s_matnr ASSIGNING <fs_select>.
ASSIGN COMPONENT 3 OF STRUCTURE <fs_select> TO <fs_field>.
* Material Number Conversion
PERFORM conversion_material CHANGING <fs_field>.
UNASSIGN <fs_field>.
ASSIGN COMPONENT 4 OF STRUCTURE <fs_select> TO <fs_field>.
* Material Number Conversion
PERFORM conversion_material CHANGING <fs_field>.
ENDLOOP.
* Fetching data from Header table CDHDR
SELECT objectid " object id
changenr " Change Number
username " Chnage User
udate " Change Date
FROM cdhdr
INTO TABLE lt_ch_number
WHERE objectclas = c_material AND
objectid IN s_matnr AND
udate IN s_chdat.
* If there are any changes for the entered material
IF NOT lt_ch_number IS INITIAL.
* Fetching data from Item table CDPOS
SELECT changenr " Change Number
fname " Field Name
value_old " Old Value
value_new " New Value
FROM cdpos
INTO TABLE lt_ch_item
FOR ALL ENTRIES IN lt_ch_number
WHERE objectclas = c_material AND
objectid = lt_ch_number-material AND
changenr = lt_ch_number-change_number.
* Making the Final history internal table ready to display
LOOP AT lt_ch_item INTO ls_ch_item.
READ TABLE lt_ch_number
INTO ls_ch_number
WITH KEY change_number = ls_ch_item-change_number.
ls_history-material = ls_ch_number-material.
ls_history-changed_on = ls_ch_number-change_date.
ls_history-changed_by = ls_ch_number-change_user.
ls_history-field = ls_ch_item-change_field.
ls_history-old_value = ls_ch_item-change_old.
ls_history-new_value = ls_ch_item-change_new.
APPEND ls_history TO lt_history.
CLEAR ls_history.
ENDLOOP.
* To display history table in ALV
PERFORM alv_display TABLES lt_history.
ENDIF.
*&---------------------------------------------------------------------*
*& Form conversion_material
*&---------------------------------------------------------------------*
* Purpose - To convert entered material into internal format
*----------------------------------------------------------------------*
* -->P_MATERIAL - Material Number entered
*----------------------------------------------------------------------*
FORM conversion_material CHANGING p_material TYPE any.
* Function Module for Material Number Conversion
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = p_material
IMPORTING
output = p_material
EXCEPTIONS
length_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. "conversion_material
*&---------------------------------------------------------------------*
*& Form alv_display
*&---------------------------------------------------------------------*
* Purpose - to display the history table in alv
*----------------------------------------------------------------------*
* -->P_HISTORY - History table for output
*----------------------------------------------------------------------*
FORM alv_display TABLES p_history TYPE table.
* preparing the field catalog
ls_fieldcat-fieldname = 'MATERIAL'.
ls_fieldcat-scrtext_m = 'Material'(e02).
ls_fieldcat-col_pos = 1.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'CHANGED_ON'.
ls_fieldcat-scrtext_m = 'Changed On'(e03).
ls_fieldcat-col_pos = 2.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'CHANGED_BY'.
ls_fieldcat-scrtext_m = 'Changed By'(e04).
ls_fieldcat-col_pos = 3.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'FIELD'.
ls_fieldcat-scrtext_m = 'Changed Field'(e05).
ls_fieldcat-col_pos = 4.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'OLD_VALUE'.
ls_fieldcat-scrtext_m = 'Old Value'(e06).
ls_fieldcat-col_pos = 5.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'NEW_VALUE'.
ls_fieldcat-scrtext_m = 'New Value'(e07).
ls_fieldcat-col_pos = 6.
ls_fieldcat-col_opt = c_x.
APPEND ls_fieldcat TO lt_fieldcat.
CLEAR ls_fieldcat.
ls_layout-zebra = c_x.
* Function Module to Display internal table in ALV
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
is_layout_lvc = ls_layout
it_fieldcat_lvc = lt_fieldcat
TABLES
t_outtab = p_history
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. "alv_display
Thanks and regards,
kartik
04-18-2012 4:03 PM
Kartik - do you think that the person who paid for this code would be happy to see it on the internet?
One of the rules of engagement says that you have to own the rights to any code you post.
Rob
04-19-2012 4:31 AM
Dear Rob,
No, I do understand the rules of engagement of posting code pretty well. I have not written this code on anybody's request. This is one of the early pieces of coding that i have done as practice exercises to understand the concepts of abap.
How do i prove it that the code is solely written by me as a practice exercise while i was new to sap and learning about the concepts of internal tables and Select...for all entries... ???
Anyways, i am very happy to see that i am following all the coding standards, just by having a look at my practice program, you have assumed it to be written for a customer.
Will it be fine if i post the code with an header ( comment ) which shows the name of the author, date on which the program was written and the description ???
04-19-2012 2:35 PM
Kartik, I have a basic complaint.... what did our original poster learn from having lines and lines of code supplied to them? This really violates our guidelines, I believe, in that we are not supposed to be spoonfeeding code to new developers. So, may I ask that you consider a different approach? Suggest general steps, perhaps class and method names, perhaps FM names, table names, etc., but let the posters earn their keep (and develop their skills) by taking the suggestions and writing code to do what they need.
Another thing that I detest...and which I'm NOT accusing anyone of specifically...suggestions or code that contains obsolete usages or out-of-date tools and techniques.
Let's encourage (the newer posters, particularly) to use current techniques and tools, and suggest how the code or process could be done.
04-19-2012 3:23 PM
Dear Break Point,
Your point is considered, in this particular case, since i developed the exact code, which was not used for any purpose but for my own learning, i gave in to the temptation and published it as it is. Any ways, i will not repeat it again. Thank you.
Regards,
kartik
04-19-2012 3:34 PM
On the other hand, if you want to publish this as a document or WIKI to help others and there are no other similar documents (I didn't look) that might help others in the future.
Rob
04-19-2012 2:12 PM
04-19-2012 2:43 PM
Look at FM 'CHANGEDOCUMENT_READ'!
The objectclass you can find by table TCDOB or by transaction SCDO, e.g. 'MATERIAL' or 'MAT_FULL'.
ml
04-19-2012 3:41 PM
Hi freinds,
Actually I had asked for the FM which had old values stored while I am changing the material master through MM02.Thats why I gave a similar example of XVBAP and YVBAP...
I have found the FM's myself they are mara_single_read and makt_single_read.which stores the old values and the new values i got from the structure.
Thanks for your valuable answers.
regards
Kanishak
04-19-2012 3:51 PM
You were, apparently, not enough specific enough in the matter, by not mentioning that you wanted to extract the data during the update transaction and not after as SAP tools such as those described in Read and format change documents permit.
Regards,
Raymond