*&---------------------------------------------------------------------*
*& Report ZGET_CHANGE_LOGS
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zget_change_logs.
TYPES: BEGIN OF ty_ddic,
tabname TYPE tabname,
fieldname TYPE fieldname,
rollname TYPE rollname,
position TYPE tabfdpos,
keyflag TYPE keyflag,
inttype TYPE inttype,
intlen TYPE intlen,
decimals TYPE decimals,
scrtext_l TYPE scrtext_l,
END OF ty_ddic,
BEGIN OF ty_pre_final,
tabname TYPE tabname,
langu TYPE syst_langu,
field TYPE zgoal_sn_field,
fdesc TYPE zgoal_sn_fdesc,
value TYPE zgoal_sn_value,
val_desc TYPE zgoal_sn_vdesc,
desc_field TYPE fieldname,
udate TYPE ersda,
utime TYPE created_at_time,
sno TYPE zgoal_sn_sno,
chngind TYPE cdchngind,
END OF ty_pre_final,
BEGIN OF ty_field_info,
tabname TYPE tabname,
END OF ty_field_info.
DATA: lt_ms_data TYPE TABLE OF zmaster_tab, "List of Tables
lw_ms_data TYPE zmaster_tab,
lt_field_info TYPE TABLE OF ty_field_info,
lw_field_info TYPE ty_field_info,
lt_junk TYPE TABLE OF zmaster_tab, "Cpature the issue list
lt_cfg_data TYPE TABLE OF zdata_table, "Actual Value table
lt_final TYPE TABLE OF zdata_table,
lt_archive TYPE TABLE OF zdata_table,
lw_final TYPE zdata_table,
lt_pre_data TYPE TABLE OF ty_pre_final,
lt_pre_final TYPE TABLE OF ty_pre_final,
lw_pre_data TYPE ty_pre_final,
lt_ms_ddic TYPE TABLE OF ty_ddic,
ls_ms_ddic TYPE ty_ddic,
lt_ms_split TYPE TABLE OF field,
lt_ds_split TYPE TABLE OF field,
ls_split TYPE field.
DATA: lv_sel_mfields TYPE string,
lv_sel_dfields TYPE string,
lv_key1 TYPE string,
lv_key2 TYPE string,
lv_key3 TYPE string,
lv_key4 TYPE string,
lv_key5 TYPE string,
lv_val1 TYPE string,
lv_val2 TYPE string,
lv_val3 TYPE string,
lv_val4 TYPE string,
lv_val5 TYPE string,
lv_key_fields TYPE char300,
lv_main_fdesc TYPE char1024_cs,
lv_val_desc TYPE char1024_cs,
lv_no_cols TYPE i,
lv_intlen TYPE i,
lv_dec TYPE i,
lv_cnt TYPE i,
lv_inttype TYPE inttype,
lv_value TYPE string,
lv_udate TYPE ersda,
lv_utime TYPE created_at_time,
lt_main_comp TYPE cl_abap_structdescr=>component_table,
ls_main_comp LIKE LINE OF lt_main_comp,
l_data TYPE REF TO data,
l_new_tab TYPE REF TO cl_abap_tabledescr,
l_new_type TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS: <lt_main_dyntab> TYPE ANY TABLE,
<lt_desc_dyntab> TYPE ANY TABLE,
<lw_main_data> TYPE any,
<lw_desc_data> TYPE any,
<lv_field> TYPE any,
<lv_final> TYPE ty_pre_final.
CONSTANTS: lc_lang TYPE char1 VALUE 'E',
lc_pipe TYPE char1 VALUE '|',
lc_insr TYPE char1 VALUE 'I',
lc_updt TYPE char1 VALUE 'U',
lc_dele TYPE char1 VALUE 'D',
lc_spras TYPE char5 VALUE 'SPRAS'.
INITIALIZATION.
START-OF-SELECTION.
SELECT * FROM zmaster_tab
INTO TABLE lt_ms_data
WHERE langu = lc_lang.
IF sy-subrc = '0'.
SORT lt_ms_data BY langu tabname field.
LOOP AT lt_ms_data INTO lw_ms_data.
lw_field_info-tabname = lw_ms_data-tabname.
APPEND lw_field_info TO lt_field_info.
CLEAR: lw_field_info,lw_ms_data.
ENDLOOP.
LOOP AT lt_ms_data INTO lw_ms_data.
lw_field_info-tabname = lw_ms_data-desc_tab.
APPEND lw_field_info TO lt_field_info.
CLEAR: lw_field_info,lw_ms_data.
ENDLOOP.
IF lt_field_info IS NOT INITIAL.
SORT lt_field_info.
ENDIF.
*--Fetch DDIC Information
SELECT tabname
fieldname
rollname
position
keyflag
inttype
intlen
decimals
scrtext_l FROM dd03m
INTO TABLE lt_ms_ddic
FOR ALL ENTRIES IN lt_field_info
WHERE tabname EQ lt_field_info-tabname
AND ddlanguage EQ lc_lang.
* AND keyflag EQ abap_true.
IF sy-subrc = 0.
SORT lt_ms_ddic BY tabname fieldname.
ENDIF.
*--Fetch the value table data
SELECT * FROM zdata_table
INTO TABLE lt_cfg_data
FOR ALL ENTRIES IN lt_ms_data
WHERE langu EQ lc_lang
AND tabname EQ lt_ms_data-tabname
AND archive NE abap_true.
IF sy-subrc = 0.
SORT lt_cfg_data BY langu tabname field value.
ENDIF.
ENDIF.
LOOP AT lt_ms_data INTO lw_ms_data.
*-------------------Logic for Main data------------------------------
*--Separating the key fields
CLEAR: lt_ms_split, lt_main_comp, lv_sel_mfields, lv_key_fields,
lv_main_fdesc, lv_no_cols.
SPLIT lw_ms_data-field AT lc_pipe INTO TABLE lt_ms_split.
DESCRIBE TABLE lt_ms_split LINES lv_no_cols.
LOOP AT lt_ms_split INTO ls_split.
CLEAR: ls_ms_ddic, ls_main_comp, lv_intlen, lv_dec.
READ TABLE lt_ms_ddic INTO ls_ms_ddic WITH KEY
tabname = lw_ms_data-tabname
fieldname = ls_split
keyflag = abap_true
BINARY SEARCH.
IF sy-subrc = 0.
*--Concatenating fields for select query
CONCATENATE lv_sel_mfields ls_ms_ddic-fieldname
INTO lv_sel_mfields SEPARATED BY space.
*--Concatenating fields to prepare key
CONCATENATE lv_key_fields ls_ms_ddic-fieldname
INTO lv_key_fields SEPARATED BY lc_pipe.
*--Concatenating field descriptions
CONCATENATE lv_main_fdesc ls_ms_ddic-scrtext_l
INTO lv_main_fdesc SEPARATED BY lc_pipe.
*---Filling the component table
lv_intlen = ls_ms_ddic-intlen.
lv_dec = ls_ms_ddic-decimals.
TRY.
CALL METHOD cl_abap_elemdescr=>get_by_kind
EXPORTING
p_type_kind = ls_ms_ddic-inttype
p_length = lv_intlen
p_decimals = lv_dec
RECEIVING
p_result = ls_main_comp-type.
ls_main_comp-name = ls_ms_ddic-fieldname.
CATCH cx_parameter_invalid_range.
ENDTRY.
APPEND ls_main_comp TO lt_main_comp.
CLEAR: ls_main_comp.
ENDIF.
ENDLOOP.
IF lt_main_comp IS INITIAL.
APPEND lw_ms_data TO lt_junk.
CONTINUE.
ENDIF.
*--Remove leading space
SHIFT lv_sel_mfields LEFT BY 1 PLACES.
SHIFT lv_key_fields LEFT BY 1 PLACES.
SHIFT lv_main_fdesc LEFT BY 1 PLACES.
*--- Create a New Type
TRY.
CLEAR: l_new_type.
CALL METHOD cl_abap_structdescr=>create
EXPORTING
p_components = lt_main_comp
RECEIVING
p_result = l_new_type.
CATCH cx_sy_struct_creation.
ENDTRY.
*--- New dynamic internal Table type
TRY.
CLEAR: l_new_tab.
CALL METHOD cl_abap_tabledescr=>create
EXPORTING
p_line_type = l_new_type
p_unique = abap_false
RECEIVING
p_result = l_new_tab.
CATCH cx_sy_table_creation.
ENDTRY.
*--data to handle the new table type
CLEAR: l_data.
CREATE DATA l_data TYPE HANDLE l_new_tab.
*--New internal table in the fieldsymbols
ASSIGN l_data->* TO <lt_main_dyntab>.
CLEAR: l_data.
*-------------------End Logic for Main data---------------------------
*-------------------Logic for Description data------------------------
IF lw_ms_data-desc_tab IS NOT INITIAL.
*--Separating the key fields
CLEAR: lt_ds_split, ls_split, lt_main_comp, lv_sel_dfields.
SPLIT lw_ms_data-desc_keys AT lc_pipe INTO TABLE lt_ds_split.
LOOP AT lt_ds_split INTO ls_split.
CLEAR: ls_ms_ddic, ls_main_comp, lv_intlen, lv_dec.
READ TABLE lt_ms_ddic INTO ls_ms_ddic WITH KEY
tabname = lw_ms_data-desc_tab
fieldname = ls_split
keyflag = abap_true
BINARY SEARCH.
IF sy-subrc = 0.
*--Concatenating fields for select query
CONCATENATE lv_sel_dfields ls_ms_ddic-fieldname
INTO lv_sel_dfields SEPARATED BY space.
*---Filling the component table
lv_intlen = ls_ms_ddic-intlen.
lv_dec = ls_ms_ddic-decimals.
TRY.
CALL METHOD cl_abap_elemdescr=>get_by_kind
EXPORTING
p_type_kind = ls_ms_ddic-inttype
p_length = lv_intlen
p_decimals = lv_dec
RECEIVING
p_result = ls_main_comp-type.
ls_main_comp-name = ls_ms_ddic-fieldname.
CATCH cx_parameter_invalid_range.
ENDTRY.
APPEND ls_main_comp TO lt_main_comp.
CLEAR: ls_main_comp.
ENDIF.
ENDLOOP.
IF lt_main_comp IS NOT INITIAL.
*--Remove leading space
SHIFT lv_sel_dfields LEFT BY 1 PLACES.
*---Populate Value Description Field
READ TABLE lt_ms_ddic INTO ls_ms_ddic WITH KEY
tabname = lw_ms_data-desc_tab
fieldname = lw_ms_data-desc_tx_field
BINARY SEARCH.
IF sy-subrc = 0.
IF lw_ms_data-desc_tx_field IS NOT INITIAL.
TRY.
lv_inttype = 'C'.
lv_intlen = 50.
CALL METHOD cl_abap_elemdescr=>get_by_kind
EXPORTING
p_type_kind = lv_inttype
p_length = lv_intlen
RECEIVING
p_result = ls_main_comp-type.
ls_main_comp-name = lw_ms_data-desc_tx_field.
CATCH cx_parameter_invalid_range.
ENDTRY.
APPEND ls_main_comp TO lt_main_comp.
CLEAR: ls_main_comp.
*--Concatenate desc field to select query
CONCATENATE lv_sel_dfields lw_ms_data-desc_tx_field INTO lv_sel_dfields
SEPARATED BY space.
ENDIF.
ELSE.
APPEND lw_ms_data TO lt_junk.
ENDIF.
*--- Create a New Type
TRY.
CLEAR: l_new_type.
CALL METHOD cl_abap_structdescr=>create
EXPORTING
p_components = lt_main_comp
RECEIVING
p_result = l_new_type.
CATCH cx_sy_struct_creation.
ENDTRY.
*--- New dynamic internal Table type
TRY.
CLEAR: l_new_tab.
CALL METHOD cl_abap_tabledescr=>create
EXPORTING
p_line_type = l_new_type
p_unique = abap_false
RECEIVING
p_result = l_new_tab.
CATCH cx_sy_table_creation.
ENDTRY.
*--data to handle the new table type
CLEAR: l_data.
CREATE DATA l_data TYPE HANDLE l_new_tab.
*--New internal table in the fieldsymbols
ASSIGN l_data->* TO <lt_desc_dyntab>.
CLEAR: l_data.
*--Fetching Description from Text/Main Tables dynamically
IF lw_ms_data-desc_tab IS NOT INITIAL.
SELECT (lv_sel_dfields)
INTO CORRESPONDING FIELDS OF
TABLE <lt_desc_dyntab> FROM (lw_ms_data-desc_tab).
*--Only capture upto 5 keys
CLEAR: lv_cnt,lv_key1,lv_key2,lv_key3,lv_key4,lv_key5,
lv_val1,lv_val2,lv_val3,lv_val4,lv_val5.
LOOP AT lt_ms_split INTO ls_split.
READ TABLE lt_ds_split TRANSPORTING NO FIELDS WITH KEY table_line = lc_spras.
IF sy-subrc = 0 AND lv_key1 IS INITIAL.
lv_key1 = lc_spras.
lv_val1 = sy-langu.
lv_cnt = 1.
ENDIF.
READ TABLE lt_ds_split INTO DATA(lw_sp) WITH KEY table_line = ls_split.
IF sy-subrc = 0 AND lw_sp <> lc_spras.
lv_cnt = lv_cnt + 1.
CASE lv_cnt.
WHEN '1'.
lv_key1 = lw_sp.
WHEN '2'.
lv_key2 = lw_sp.
WHEN '3'.
lv_key3 = lw_sp.
WHEN '4'.
lv_key4 = lw_sp.
WHEN OTHERS.
lv_key5 = lw_sp.
ENDCASE.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
*-------------------End Logic for Description data---------------------
*--Fetching Data from Config Tables dynamically
SELECT (lv_sel_mfields)
INTO CORRESPONDING FIELDS OF
TABLE <lt_main_dyntab> FROM (lw_ms_data-tabname).
LOOP AT <lt_main_dyntab> ASSIGNING <lw_main_data>.
IF lw_ms_data-desc_tab IS NOT INITIAL.
ASSIGN COMPONENT lv_key1 OF STRUCTURE <lw_main_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val1 = <lv_field>.
ENDIF.
ASSIGN COMPONENT lv_key2 OF STRUCTURE <lw_main_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val2 = <lv_field>.
ENDIF.
ASSIGN COMPONENT lv_key3 OF STRUCTURE <lw_main_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val3 = <lv_field>.
ENDIF.
ASSIGN COMPONENT lv_key4 OF STRUCTURE <lw_main_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val4 = <lv_field>.
ENDIF.
ASSIGN COMPONENT lv_key5 OF STRUCTURE <lw_main_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val5 = <lv_field>.
ENDIF.
*--Get the value description
IF <lt_desc_dyntab> IS ASSIGNED.
READ TABLE <lt_desc_dyntab> ASSIGNING <lw_desc_data>
WITH KEY (lv_key1) = lv_val1
(lv_key2) = lv_val2
(lv_key3) = lv_val3
(lv_key4) = lv_val4
(lv_key5) = lv_val5.
IF sy-subrc = 0.
ASSIGN COMPONENT lw_ms_data-desc_tx_field OF STRUCTURE <lw_desc_data> TO <lv_field>.
IF sy-subrc = 0.
lv_val_desc = <lv_field>.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
*--Concatenate the Values
DO.
ASSIGN COMPONENT sy-index
OF STRUCTURE <lw_main_data>
TO <lv_field>.
*--Capture only the field values and not the value description
IF sy-subrc EQ 0 AND sy-index <= lv_no_cols.
IF sy-index EQ 1.
lv_value = <lv_field>.
ELSE.
CONCATENATE lv_value <lv_field> INTO lv_value SEPARATED BY lc_pipe.
ENDIF.
ELSE.
EXIT.
ENDIF.
ENDDO.
lw_pre_data-tabname = lw_ms_data-tabname.
lw_pre_data-langu = lc_lang.
lw_pre_data-field = lv_key_fields.
lw_pre_data-fdesc = lv_main_fdesc.
lw_pre_data-value = lv_value.
lw_pre_data-val_desc = lv_val_desc.
lw_pre_data-desc_field = lw_ms_data-desc_tx_field.
APPEND lw_pre_data TO lt_pre_data.
CLEAR: lw_pre_data.
CLEAR: lv_value, lv_val_desc.
ENDLOOP.
IF <lt_main_dyntab> IS ASSIGNED.
UNASSIGN: <lt_main_dyntab>.
ENDIF.
IF <lt_desc_dyntab> IS ASSIGNED.
UNASSIGN: <lt_desc_dyntab>.
ENDIF.
CLEAR: lw_pre_data, lt_main_comp, l_new_tab, l_new_type, lv_no_cols.
ENDLOOP.
*--Comparing the data and preparing the final for Insert and Update records
SORT lt_pre_data BY langu tabname field value.
SORT lt_cfg_data BY langu tabname field value.
LOOP AT lt_pre_data ASSIGNING <lv_final>.
<lv_final>-sno = sy-tabix.
MOVE-CORRESPONDING <lv_final> TO lw_pre_data.
READ TABLE lt_cfg_data INTO DATA(lw_dt) WITH KEY langu = <lv_final>-langu
tabname = <lv_final>-tabname
field = <lv_final>-field
value = <lv_final>-value
BINARY SEARCH.
IF sy-subrc = 0.
*--For Arciving purpose
CLEAR: lw_final.
MOVE-CORRESPONDING lw_dt TO lw_final.
*--Data Exists
*--Compare the field descriptions and get the updated records
IF <lv_final>-desc_field IS NOT INITIAL.
IF <lv_final>-val_desc <> lw_dt-val_desc.
<lv_final>-chngind = lc_updt.
lw_pre_data-chngind = lc_updt.
<lv_final>-val_desc = <lv_final>-val_desc.
lw_pre_data-val_desc = <lv_final>-val_desc.
APPEND lw_pre_data TO lt_pre_final.
*--Capturing Archive record.
lw_final-archive = abap_true.
APPEND lw_final TO lt_final.
CLEAR: lw_final.
ENDIF.
ENDIF.
ELSE.
*--Data does not exists
*--Capture this data as new records
<lv_final>-chngind = lc_insr.
lw_pre_data-chngind = lc_insr.
APPEND lw_pre_data TO lt_pre_final.
ENDIF.
CLEAR: lw_pre_data, lw_dt.
ENDLOOP.
*--Comparing the data and preparing the final for delete records
SORT lt_pre_data BY langu tabname field value.
LOOP AT lt_cfg_data INTO lw_dt.
CLEAR: lw_pre_data.
READ TABLE lt_pre_data INTO lw_pre_data WITH KEY
langu = lw_dt-langu
tabname = lw_dt-tabname
field = lw_dt-field
value = lw_dt-value
BINARY SEARCH.
IF sy-subrc = '0'.
*--Data Exists Can be ignored
ELSE.
*--Data does not exists Capture the deleted records
MOVE-CORRESPONDING lw_dt TO lw_pre_data.
lw_pre_data-chngind = lc_dele.
APPEND lw_pre_data TO lt_pre_final.
*--Capturing Archive record.
MOVE-CORRESPONDING lw_dt TO lw_final.
lw_final-archive = abap_true.
APPEND lw_final TO lt_final.
CLEAR: lw_final.
ENDIF.
CLEAR: lw_dt.
ENDLOOP.
*--Preparing final table
lv_udate = sy-datum.
lv_utime = sy-timlo.
SORT lt_pre_final BY tabname.
SORT lt_cfg_data BY langu tabname ASCENDING sno DESCENDING.
LOOP AT lt_pre_final ASSIGNING <lv_final>.
AT NEW tabname.
CLEAR: lv_no_cols, lw_dt.
READ TABLE lt_cfg_data INTO lw_dt WITH KEY
langu = lc_lang
tabname = <lv_final>-tabname
BINARY SEARCH.
IF sy-subrc = 0.
lv_no_cols = lw_dt-sno + 1.
ELSE.
lv_no_cols = 1.
ENDIF.
ENDAT.
<lv_final>-sno = lv_no_cols.
lv_no_cols = lv_no_cols + 1.
<lv_final>-udate = lv_udate.
<lv_final>-utime = lv_utime.
MOVE-CORRESPONDING <lv_final> TO lw_final.
lw_final-mandt = sy-mandt.
APPEND lw_final TO lt_final.
CLEAR: lw_final.
ENDLOOP.
*--Inserting data into tabe
IF lt_final IS NOT INITIAL.
SORT lt_final BY langu tabname sno.
MODIFY zdata_table FROM TABLE lt_final.
ENDIF.
*-- Sending only the updated records.
DELETE lt_final WHERE archive IS NOT INITIAL.
IF <lv_final> IS ASSIGNED.
UNASSIGN <lv_final>.
ENDIF.
CLEAR: lv_utime, lv_udate, lt_pre_data, lt_pre_final,
lt_final.
LOOP AT lt_junk INTO lw_ms_data.
WRITE:/ lw_ms_data.
ENDLOOP.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
5 | |
4 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 |