Application Development 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: 

How to get encoded LOGDATA(for table TCURR) value of table DBTABLOG.

Former Member
0 Kudos

hello all

I want to get the updated table record from Log Table DBTABLOG.

This updated record is stored in the field LOGDATA ( type : lrow) of DBTABLOG

can any one tell me how to read this field and display in the output of my program?

1 ACCEPTED SOLUTION

SuhaSaha
Advisor
Advisor
0 Kudos

Hello,

Couple of things:

1. Table logging happens only when the param rec/client is activated in the system profile.

2. The data is stored as LRAW format in DBTABLOG & you can analyse the table logs via SCU3 transaction.

Further read available here: [http://help.sap.com/saphelp_nw04/helpdata/en/cf/21eaf9446011d189700000e8322d00/content.htm]

BR,

Suhas

8 REPLIES 8

SuhaSaha
Advisor
Advisor
0 Kudos

Hello,

Couple of things:

1. Table logging happens only when the param rec/client is activated in the system profile.

2. The data is stored as LRAW format in DBTABLOG & you can analyse the table logs via SCU3 transaction.

Further read available here: [http://help.sap.com/saphelp_nw04/helpdata/en/cf/21eaf9446011d189700000e8322d00/content.htm]

BR,

Suhas

Former Member
0 Kudos

You can read the changes made to a partucular table using change doucments concept...

IF you maintaintain change document object for that table... all the details.. who changed the data , which field was changed , date and time when it was changed and old value of the field and new value of the field all this information we can get...

we can maintain change document in the transaction scdo. a function module will be generated... which u can call whenevr u make changes to that table in your program... and then we can retrieve that change documents.

If you particularly want to read that table only(dbtablog) then u can to refer to the program rsvtprot which is the program for the transaction scu3.

Some fms are there to read lraw format:can try

1. READ_TEXT

2. SX_OBJECT_CONVERT_RAW_SCR OR SX_OBJECT_CONVERT_SCR_OTF

Edited by: prashanti korlepara on Jun 17, 2011 7:39 AM

Former Member
0 Kudos

Hi Prashanti,

Thanks for your replay.

I want to display old value and new value of the Exchange rate field(UKURS) using the table DBTABLOG.

Samplecode is very helpfull to me..

Former Member
0 Kudos

I have the sample code for the change document : while modifying the employee record:

CLEAR: LW_EMP_TABLE3 .

SELECT SINGLE * FROM ZTMS_EMP_TABLE INTO LW_EMP_TABLE3 WHERE ZKMD_INITIALS = I_ZKMD_INITIALS .

PERFORM FM_MODIFY USING lw_emp_table 'ZTMS_EMP_TABLE' .

IF sy-subrc = 0.

E_RETURN-TYPE = 'S'.

E_RETURN-MESSAGE = 'The Record is modified successfully'.

OBJECT_ID = I_ZKMD_INITIALS .

CALL FUNCTION 'ZEMP_HISTORY_WRITE_DOCUMENT'

EXPORTING

OBJECTID = OBJECT_ID

TCODE = SY-TCODE

UTIME = SY-UZEIT

UDATE = SY-DATUM

USERNAME = SY-UNAME

OBJECT_CHANGE_INDICATOR = 'U'

N_ZTMS_EMP_TABLE = lw_emp_table

O_ZTMS_EMP_TABLE = lw_emp_table3

UPD_ZTMS_EMP_TABLE = 'U'.

now the change document has been generated for the modified record

'ZEMP_HISTORY_WRITE_DOCUMENT' - this is the fm that got generated when I created the change document object for the table ZTMS_EMP_TABLE .

now if you want to view the report then this code will be helpfull..

GV_OBJECTCLASS = 'ZEMP_HISTORY'.

DATA: OBJECT_ID2 LIKE CDHDR-OBJECTID .

LOOP AT GT_CDHDR INTO GS_CDHDR .

CLEAR CDHDR.

CLEAR CDPOS.

CHECK GS_CDHDR-OBJECTID NE OBJECT_ID2 .

OBJECT_ID2 = GS_CDHDR-OBJECTID .

CDHDR-OBJECTCLAS = GV_OBJECTCLASS .

CDHDR-OBJECTID = GS_CDHDR-OBJECTID.

CALL FUNCTION 'CHANGEDOCUMENT_READ_HEADERS' " we pass the change data - date or time or object class or odject id or username- we get the respective records in cdhdr

EXPORTING

DATE_OF_CHANGE = CDHDR-UDATE

OBJECTCLASS = CDHDR-OBJECTCLAS

OBJECTID = CDHDR-OBJECTID

TIME_OF_CHANGE = CDHDR-UTIME

USERNAME = CDHDR-USERNAME

TABLES

I_CDHDR = ICDHDR

EXCEPTIONS

NO_POSITION_FOUND = 1

OTHERS = 2.

CHECK SY-SUBRC EQ 0.

CHECK NOT ICDHDR[] IS INITIAL.

LOOP AT ICDHDR.

  • CHECK ICDHDR-UDATE IN XUDATE.

  • CHECK ICDHDR-USERNAME IN XNAME.

CALL FUNCTION 'CHANGEDOCUMENT_READ_POSITIONS' " we pass the change numbers we got from above fm and get the data from CDSHW

EXPORTING CHANGENUMBER = ICDHDR-CHANGENR

IMPORTING HEADER = CDHDR

TABLES EDITPOS = ICDSHW

EXCEPTIONS NO_POSITION_FOUND = 1

OTHERS = 2.

CHECK SY-SUBRC EQ 0.

LOOP AT ICDSHW.

CHECK ICDSHW-TEXT_CASE EQ SPACE.

MOVE-CORRESPONDING ICDSHW TO ITAB.

MOVE-CORRESPONDING ICDHDR TO ITAB. " we are filling itab using the data we got in ICDHDR and ICDSHW

MOVE ICDSHW-TABKEY+3 TO ITAB-ZOBJECT_ID .

APPEND ITAB.

ENDLOOP.

ENDLOOP.

ENDLOOP.

ET_HISTORY[] = ITAB[] .

sandeep_katoch
Contributor
0 Kudos

Hi Raju,

I have done similar kind of coding . But I have used CDHDR and CDPOS tables instead as it is quiet simple using these tables.CDHDR contains the header fields while CDPOS contains the dat that has changed.

The most important thing is you can have old values and new values simultaneously using these two tables.

DATA:

g_logdate TYPE sy-datum,

g_co_code TYPE lfb1-bukrs,

g_user TYPE usr02-bname,

g_vendor TYPE lfb1-lifnr,

g_error TYPE i VALUE 0,

  • Declaration of the Structure for the main data

DATA:

BEGIN OF t_lifnr,

lifnr TYPE cdhdr-objectid,

END OF t_lifnr,

  • Structure for CDHDR

BEGIN OF t_cdhdr,

objectclas TYPE cdhdr-objectclas,

vendor TYPE cdhdr-objectid,

changenr TYPE cdhdr-changenr,

user TYPE cdhdr-username,

logdate TYPE cdhdr-udate,

logtime TYPE cdhdr-utime,

tcode TYPE cdhdr-tcode,

END OF t_cdhdr,

  • Structure for CDPOS

BEGIN OF t_cdpos,

objectclas TYPE cdpos-objectclas,

vendor TYPE cdpos-objectid,

changenr TYPE cdpos-changenr,

tabkey TYPE cdpos-tabkey,

value_new TYPE cdpos-value_new,

value_old TYPE cdpos-value_old,

END OF t_cdpos,

  • Structure for Final Data that is to be displayed in ALV

BEGIN OF t_final,

objectclas TYPE cdhdr-objectclas,

vendor TYPE cdhdr-objectid,

changenr TYPE cdhdr-changenr,

co_code TYPE lfb1-bukrs,

user TYPE cdhdr-username,

logdate TYPE cdhdr-udate,

logtime TYPE cdhdr-utime,

tcode TYPE cdhdr-tcode,

value_new TYPE cdpos-value_new,

value_old TYPE cdpos-value_old,

scn_sperr TYPE lfb1-sperr,

END OF t_final.

  • Internal tables for main data

DATA:

gi_lifnr LIKE STANDARD TABLE OF t_lifnr,

gi_cdhdr LIKE STANDARD TABLE OF t_cdhdr,

gi_cdpos LIKE STANDARD TABLE OF t_cdpos,

gi_final LIKE STANDARD TABLE OF t_final,

gwa_cdpos LIKE LINE OF gi_cdpos,

gwa_cdhdr LIKE LINE OF gi_cdhdr,

gwa_final LIKE LINE OF gi_final.

  • Select Options for the Screen

SELECT-OPTIONS:

s_date FOR g_logdate,

s_user FOR g_user,

s_vndr FOR g_vendor,

*----


  • Data Processing

*----


START-OF-SELECTION.

  • Process the log data

PERFORM get_log_data.

  • Display in alv.

PERFORM display_alv.

&----


*& Form get_log_data

&----


  • This is a form for getting the log data for the table LFB1 and

  • particularly in field SPERR

----


FORM get_log_data.

DATA:

l_co_code LIKE lfb1-bukrs,

l_length TYPE int3.

  • Check for empty date

IF s_date-low IS NOT INITIAL OR s_date-high IS NOT INITIAL.

IF g_blkind IS NOT INITIAL.

SELECT lifnr

FROM lfb1

INTO TABLE gi_lifnr

WHERE sperr = g_blkind

AND lifnr IN s_vndr

AND bukrs IN s_co_cd.

ELSE.

SELECT lifnr

FROM lfb1

INTO TABLE gi_lifnr

WHERE lifnr IN s_vndr

AND bukrs IN s_co_cd.

ENDIF.

IF sy-subrc = 0.

  • Select statement for filling the CDHDR internal table

SELECT objectclas objectid changenr username udate utime tcode

INTO TABLE gi_cdhdr

FROM cdhdr

FOR ALL ENTRIES IN gi_lifnr

WHERE objectid = gi_lifnr-lifnr

AND objectclas = k_kred

AND username IN s_user

AND udate BETWEEN s_date-low AND s_date-high

AND ( tcode = k_xk05 OR tcode = k_fk05 )

AND change_ind = k_update.

SORT gi_cdhdr BY logdate DESCENDING logtime DESCENDING.

IF sy-subrc = 0.

  • Select statement for filling the CDPOS internal table

SELECT objectclas objectid changenr tabkey value_new value_old

INTO TABLE gi_cdpos

FROM cdpos

FOR ALL ENTRIES IN gi_cdhdr

WHERE objectid = gi_cdhdr-vendor

AND objectclas = gi_cdhdr-objectclas

AND changenr = gi_cdhdr-changenr

AND tabname = k_lfb1

AND fname = k_sperr

AND chngind = k_update.

IF sy-subrc <> 0.

  • Error message for date

g_error = 3.

MESSAGE ID k_msgid TYPE k_msgty_s NUMBER k_msgno_nd DISPLAY LIKE k_msgty_e.

ENDIF.

  • Clear wa and internal table

CLEAR:

gwa_cdpos, gwa_cdhdr.

REFRESH:

gi_final.

  • Fill the final internal table

LOOP AT gi_cdpos INTO gwa_cdpos.

READ TABLE gi_cdhdr INTO gwa_cdhdr WITH KEY objectclas = gwa_cdpos-objectclas

vendor = gwa_cdpos-vendor

changenr = gwa_cdpos-changenr.

IF sy-subrc = 0.

l_length = STRLEN( gwa_cdpos-tabkey ).

l_length = l_length - 4. "------->Subtract the length of company code as in lfb1-bukrs.

l_co_code = gwa_cdpos-tabkey+l_length(4).

gwa_final-objectclas = gwa_cdhdr-objectclas.

gwa_final-vendor = gwa_cdhdr-vendor.

gwa_final-changenr = gwa_cdhdr-changenr.

gwa_final-co_code = l_co_code.

gwa_final-user = gwa_cdhdr-user.

gwa_final-logdate = gwa_cdhdr-logdate.

gwa_final-logtime = gwa_cdhdr-logtime.

gwa_final-tcode = gwa_cdhdr-tcode.

gwa_final-value_new = gwa_cdpos-value_new.

gwa_final-value_old = gwa_cdpos-value_old.

gwa_final-scn_sperr = g_blkind.

APPEND gwa_final TO gi_final.

CLEAR: gwa_final.

ENDIF.

By making small changes I think you can do that.

I hope that this will help you.

Venkat_Sesha
Advisor
Advisor
0 Kudos

Hey U can use This Fm to read DBLOG_READ_TABLE and also the values returned in TB_LOG can be read as follows

LOOP AT lt_log INTO x_log.

CALL FUNCTION 'DDIF_FIELDINFO_GET'

*Append To Global Table

APPEND LINES OF tb_dfies TO gtb_dfies.

ENDLOOP.

  • Get the instance of the Table data

ref_table_des ?=

cl_abap_typedescr=>describe_by_name( lv_table ).

  • Create dynamic internal table and assign to FS

CALL METHOD cl_alv_table_create=>create_dynamic_table

EXPORTING

it_fieldcatalog = ifc

IMPORTING

ep_table = dy_table.

ASSIGN dy_table->* TO <dy_table>.

LOOP AT tb_log INTO x_log Where OPTYPE <> SPACE.

CREATE DATA x_view_data-logentry TYPE (lv_table).

ASSIGN: x_view_data-logentry->* TO <logentry>,

<logentry> TO <logentry_x> CASTING.

<logentry_x> = x_log-logdata.

MOVE-CORRESPONDING <logentry> TO <dy_wa>.

Endloop.

Hope this solves your requirement

Regards,

Bhargav.

Former Member
0 Kudos

The LOGDATA contains the non key fields values,

and the simple way to read it is:

ASSIGN DBTABLOG-LOGDATA(DBTABLOG-DATALN) TO <LOGDATA> TYPE 'C'.

Eg.: let say we have a custom table: ZTABLE

      Field     Type         Length     Key
       MANDT     CLNT         3         X
       KEY1      CHAR         2         X
       KEY2      CHAR         2         X
       FIELD1    CHAR         3
       FIELD2    CHAR        10

I insert a new line to the ZTABLE with the below data:

MANDT  = '100'
KEY1   = 'ZZ'
KEY2   = 'XX'
FIELD1 = '23'
FIELD2 = 'TEST DATA'

If we check the DBTABLOG table in SE16 we will see:

TABNAME = ZTABLE
LOGKEY  = 100ZZXX
OPTYPE  = I
DATALN  = 13
LOGDATA = 32332054455354204441544120

And if we run the above abap code the value of <LOGDATA> is: '23 TEST DATA '

0 Kudos

Hello,

I have tried this and didn't work for tables which have field types diferents from CHAR. Actually I am trying to get the log from TFAWC. Fields BMASKE1 and BMASKE2 are RAW typed and I don't know how to interpretate their values from the LOGDATA field obtained with the DBLOG_READ_TABLE.

Do you how I could do it?

Thank you very much!

Regards.