TYPES:
BEGIN OF gty_diff,
type TYPE c,
segnam TYPE edidd-segnam,
hlevel TYPE edidd-hlevel,
idx_a TYPE i,
idx_b TYPE i,
END OF gty_diff,
gty_tt_diffs TYPE STANDARD TABLE OF gty_diff.
DATA:
gt_edidd_a TYPE edidd_tt,
gt_edidd_b TYPE edidd_tt,
gt_diffs TYPE gty_tt_diffs.
PARAMETERS:
p_idoc_a TYPE edidc-docnum MEMORY ID ida OBLIGATORY,
p_idoc_b TYPE edidc-docnum MEMORY ID idb OBLIGATORY.
START-OF-SELECTION.
PERFORM do_checks USING p_idoc_a p_idoc_b.
PERFORM write_legend.
PERFORM compare_idocs USING p_idoc_a p_idoc_b.
AT LINE-SELECTION.
PERFORM show_content USING gt_edidd_a gt_edidd_b gt_diffs sy-lilli.
*&---------------------------------------------------------------------*
*& Form do_checks
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IV_IDOC_A text
* -->IV_IDOC_B text
*----------------------------------------------------------------------*
FORM do_checks
USING
iv_idoc_a TYPE edidc-docnum
iv_idoc_b TYPE edidc-docnum.
DATA:
lv_partner_type TYPE edidc-sndprt,
lv_partner_name TYPE edidc-sndprn,
ls_edidc_a TYPE edidc,
ls_edidc_b TYPE edidc.
SELECT SINGLE * FROM edidc
INTO ls_edidc_a
WHERE docnum = iv_idoc_a.
IF sy-subrc <> 0.
" IDoc does not exist
MESSAGE e829(ea) WITH iv_idoc_a.
ENDIF.
SELECT SINGLE * FROM edidc
INTO ls_edidc_b
WHERE docnum = iv_idoc_b.
IF sy-subrc <> 0.
" IDoc does not exist
MESSAGE e829(ea) WITH iv_idoc_b.
ENDIF.
"Check IDoc type the same
IF ls_edidc_a-idoctp <> ls_edidc_b-idoctp.
MESSAGE 'Specified IDocs have different IDoc types' TYPE 'E'.
ENDIF.
"Check message types
IF ls_edidc_a-mestyp <> ls_edidc_b-mestyp.
MESSAGE 'Specified IDocs have different message types' TYPE 'E'.
ENDIF.
"Check extension
IF ls_edidc_a-cimtyp <> ls_edidc_b-cimtyp.
MESSAGE 'Specified IDocs have different extensions' TYPE 'E'.
ENDIF.
AUTHORITY-CHECK OBJECT 'S_IDOCMONI'
ID 'EDI_TCD' FIELD 'WE02'
ID 'ACTVT' FIELD '03'
ID 'EDI_DIR' FIELD ls_edidc_a-direct
ID 'EDI_MES' FIELD ls_edidc_a-mestyp
ID 'EDI_PRN' FIELD lv_partner_name
ID 'EDI_PRT' FIELD lv_partner_type.
IF sy-subrc <> 0.
MESSAGE 'No authorizations to display the specified IDocs.' TYPE 'E'.
ENDIF.
ENDFORM. "do_checks
*&---------------------------------------------------------------------*
*& Form compare_idocs
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IV_IDOC_A text
* -->IV_IDOC_B text
*----------------------------------------------------------------------*
FORM compare_idocs
USING
iv_idoc_a TYPE edidc-docnum
iv_idoc_b TYPE edidc-docnum.
PERFORM read_idoc USING iv_idoc_a CHANGING gt_edidd_a.
PERFORM read_idoc USING iv_idoc_b CHANGING gt_edidd_b.
SORT gt_edidd_a BY segnum DESCENDING.
SORT gt_edidd_b BY segnum DESCENDING.
PERFORM compute_diffs USING gt_edidd_a gt_edidd_b CHANGING gt_diffs.
PERFORM write_segment_diffs USING gt_diffs.
ENDFORM. "compare_idocs
*&---------------------------------------------------------------------*
*& Form write_segment_diffs
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IT_DIFFS text
*----------------------------------------------------------------------*
FORM write_segment_diffs
USING
it_diffs TYPE gty_tt_diffs.
DATA:
lv_indent TYPE i,
ls_diff TYPE gty_diff.
LOOP AT it_diffs INTO ls_diff.
PERFORM set_format USING ls_diff-type.
IF ls_diff-hlevel = '01'.
lv_indent = ls_diff-hlevel * 2 + 1.
ELSE.
lv_indent = ( ls_diff-hlevel - 1 ) * 2 + 1.
ENDIF.
ENDFORM. "write_segments
*&---------------------------------------------------------------------*
*& Form write_content
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IS_EDIDD text
*----------------------------------------------------------------------*
FORM write_content
USING
is_edidd TYPE edidd.
CONSTANTS:
lco_end TYPE i VALUE 85.
DATA:
lv_offset TYPE p VALUE 0,
lt_fields TYPE dfies_tab,
ls_field TYPE dfies,
lv_value TYPE c LENGTH 50,
lv_tabname TYPE ddobjname.
WRITE: / 'Segment', is_edidd-segnam.
ULINE AT /(lco_end).
FORMAT COLOR COL_HEADING INTENSIFIED OFF.
WRITE: / sy-vline NO-GAP, 'Field Name', 33 sy-vline NO-GAP, 'Field Content', AT lco_end sy-vline NO-GAP.
FORMAT COLOR OFF.
LOOP AT lt_fields INTO ls_field.
ASSIGN is_edidd-sdata+lv_offset(ls_field-leng) TO <field>
TYPE ls_field-inttype.
lv_value = <field>.
lv_offset = lv_offset + ls_field-leng.
CHECK NOT lv_value IS INITIAL.
ULINE AT /(lco_end).
WRITE: / sy-vline NO-GAP, ls_field-fieldname, sy-vline NO-GAP, lv_value, sy-vline NO-GAP.
ENDLOOP.
ULINE AT /(lco_end).
ENDFORM. "write_content
*&---------------------------------------------------------------------*
*& Form write_content_diff
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IS_EDIDD_A text
* -->IS_EDIDD_B text
*----------------------------------------------------------------------*
FORM write_content_diff
USING
is_edidd_a TYPE edidd
is_edidd_b TYPE edidd.
CONSTANTS:
lco_end TYPE i VALUE 137.
DATA:
lv_offset TYPE p VALUE 0,
lt_fields TYPE dfies_tab,
ls_field TYPE dfies,
lv_value_a TYPE c LENGTH 50,
lv_value_b TYPE c LENGTH 50,
lv_tabname TYPE ddobjname.
WRITE: / 'Segment', is_edidd_a-segnam.
ULINE AT /(lco_end).
FORMAT COLOR COL_HEADING INTENSIFIED OFF.
WRITE: / sy-vline NO-GAP, 'Field Name', 33 sy-vline NO-GAP, 'Field Content (A)', 85 sy-vline NO-GAP, 'Field Content (B)', AT lco_end sy-vline NO-GAP.
FORMAT COLOR OFF.
LOOP AT lt_fields INTO ls_field.
ASSIGN is_edidd_a-sdata+lv_offset(ls_field-leng) TO <field>
TYPE ls_field-inttype.
lv_value_a = <field>.
ASSIGN is_edidd_b-sdata+lv_offset(ls_field-leng) TO <field>
TYPE ls_field-inttype.
lv_value_b = <field>.
lv_offset = lv_offset + ls_field-leng.
CHECK NOT ( lv_value_a IS INITIAL AND lv_value_b IS INITIAL ).
ULINE AT /(lco_end).
IF lv_value_a <> lv_value_b.
FORMAT COLOR COL_TOTAL.
ENDIF.
WRITE: / sy-vline NO-GAP, ls_field-fieldname, sy-vline NO-GAP, lv_value_a, sy-vline NO-GAP, lv_value_b, sy-vline NO-GAP.
IF lv_value_a <> lv_value_b.
FORMAT COLOR OFF.
ENDIF.
ENDLOOP.
ULINE AT /(lco_end).
ENDFORM. "write_content
*&---------------------------------------------------------------------*
*& Form read_idoc
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IV_DOCNUM text
* -->CT_EDIDD text
*----------------------------------------------------------------------*
FORM read_idoc USING iv_docnum TYPE edidc-docnum
CHANGING ct_edidd TYPE edidd_tt.
SELECT * FROM edid4
INTO CORRESPONDING FIELDS OF TABLE ct_edidd
WHERE docnum = iv_docnum.
" EDID4 is a cluster table and cannot be sorted in SELECT
SORT ct_edidd BY segnum.
ENDFORM. " read_idoc
*&---------------------------------------------------------------------*
*& Form set_format
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IV_DIFF_TYPE text
*----------------------------------------------------------------------*
FORM set_format USING iv_diff_type TYPE c.
CASE iv_diff_type.
WHEN ' '.
FORMAT COLOR OFF HOTSPOT.
WHEN 'D'.
FORMAT COLOR COL_NEGATIVE HOTSPOT.
WHEN 'U'.
FORMAT COLOR COL_TOTAL HOTSPOT.
WHEN 'I'.
FORMAT COLOR COL_POSITIVE HOTSPOT.
ENDCASE.
ENDFORM. " set_format
*&---------------------------------------------------------------------*
*& Form write_legend
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM write_legend .
NEW-PAGE NO-TITLE.
FORMAT RESET.
WRITE /'Legend:'.
FORMAT COLOR COL_NEGATIVE.
WRITE: AT /10 ''. FORMAT COLOR OFF. WRITE 'Segment deleted from the 2nd IDoc'.
FORMAT COLOR COL_POSITIVE.
WRITE: AT /10 ''. FORMAT COLOR OFF. WRITE 'Segment inserted into the 2nd IDoc'.
FORMAT COLOR COL_TOTAL.
WRITE: AT /10''. FORMAT COLOR OFF. WRITE 'Content of the segment changed'.
ULINE.
ENDFORM. " write_legend
*----------------------------------------------------------------------*
* CLASS gcl_integer_array DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS gcl_integer_array DEFINITION.
PUBLIC SECTION.
METHODS:
constructor IMPORTING iv_height TYPE i iv_width TYPE i,
get_item IMPORTING i TYPE i j TYPE i RETURNING value(value) TYPE i,
set_item IMPORTING i TYPE i j TYPE i value TYPE i,
get_width RETURNING value(width) TYPE i,
get_height RETURNING value(height) TYPE i,
print.
PRIVATE SECTION.
METHODS:
get_offset IMPORTING i TYPE i j TYPE i RETURNING value(off) TYPE i.
DATA:
lv_width TYPE i,
lv_height TYPE i,
lt_arr TYPE STANDARD TABLE OF i INITIAL SIZE 10000.
ENDCLASS. "declaration GCL_ARRAY
*----------------------------------------------------------------------*
* CLASS gcl_integer_array IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS gcl_integer_array IMPLEMENTATION.
METHOD constructor.
lv_width = iv_width.
lv_height = iv_height.
DATA:
lv_size TYPE i.
lv_size = lv_width * lv_height.
DO lv_size TIMES.
APPEND 0 TO lt_arr.
ENDDO.
ENDMETHOD. "constructor
METHOD get_item.
DATA:
lv_index TYPE i.
lv_index = get_offset( i = i j = j ).
READ TABLE lt_arr INDEX lv_index INTO value.
ENDMETHOD. "get_item
METHOD set_item.
DATA:
lv_index TYPE i.
FIELD-SYMBOLS:
<val> TYPE i.
lv_index = get_offset( i = i j = j ).
READ TABLE lt_arr INDEX lv_index ASSIGNING <val>.
<val> = value.
ENDMETHOD. "set_item
METHOD get_offset.
off = j * lv_width + i + 1.
ENDMETHOD. "get_offset
METHOD print.
DATA:
i TYPE i,
j TYPE i,
val TYPE n LENGTH 2.
DO lv_width TIMES.
i = sy-index - 1.
DO lv_height TIMES.
j = sy-index - 1.
val = get_item( i = i j = j ).
WRITE val.
ENDDO.
NEW-LINE.
ENDDO.
ENDMETHOD. "print
ENDCLASS. "gcl_array IMPLEMENTATION
*&---------------------------------------------------------------------*
*& Form compute_diffs
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IT_EDIDD_A text
* -->IT_EDIDD_B text
* -->CT_DIFFS text
*----------------------------------------------------------------------*
FORM compute_diffs
USING
it_edidd_a TYPE edidd_tt
it_edidd_b TYPE edidd_tt
CHANGING
ct_diffs TYPE gty_tt_diffs.
DATA:
lo_arr TYPE REF TO gcl_integer_array,
lv_idx_a TYPE i VALUE 1,
lv_idx_b TYPE i VALUE 1,
lv_prev_idx_a TYPE i,
lv_prev_idx_b TYPE i,
lv_val1 TYPE i,
lv_val2 TYPE i,
lv_segs_a TYPE i,
lv_segs_b TYPE i,
lv_width TYPE i,
lv_height TYPE i,
ls_edidd_a LIKE LINE OF it_edidd_a,
ls_edidd_b LIKE LINE OF it_edidd_b.
" Computing the length of the (L)ongest (C)ommon (S)ubsequence
LOOP AT it_edidd_a INTO ls_edidd_a.
lv_idx_a = sy-tabix.
lv_prev_idx_a = lv_idx_a - 1.
LOOP AT it_edidd_b INTO ls_edidd_b.
lv_idx_b = sy-tabix.
lv_prev_idx_b = lv_idx_b - 1.
IF ls_edidd_a-segnam = ls_edidd_b-segnam AND ls_edidd_a-sdata = ls_edidd_b-sdata.
lv_val1 = lo_arr->get_item( i = lv_prev_idx_a j = lv_prev_idx_b ) + 1.
lo_arr->set_item( i = lv_idx_a j = lv_idx_b value = lv_val1 ).
ELSE.
lv_val1 = lo_arr->get_item( i = lv_idx_a j = lv_prev_idx_b ).
lv_val2 = lo_arr->get_item( i = lv_prev_idx_a j = lv_idx_b ).
"Compute max of lv_val1 and lv_val2 and set lv_val1 to the max.
IF lv_val1 < lv_val2.
lv_val1 = lv_val2.
ENDIF.
lo_arr->set_item( i = lv_idx_a j = lv_idx_b value = lv_val1 ).
ENDIF.
ENDLOOP.
ENDLOOP.
PERFORM fill_diffs USING lo_arr it_edidd_a it_edidd_b lv_segs_a lv_segs_b CHANGING ct_diffs.
PERFORM aggregate_diffs CHANGING ct_diffs.
ENDFORM. " compute_diffs
*&---------------------------------------------------------------------*
*& Form fill_diffs
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IO_LCS_ARR text
* -->IT_EDIDD_A text
* -->IT_EDIDD_B text
* -->IV_IDX_A text
* -->IV_IDX_B text
* -->CT_DIFFS text
*----------------------------------------------------------------------*
FORM fill_diffs
USING
io_lcs_arr TYPE REF TO gcl_integer_array
it_edidd_a TYPE edidd_tt
it_edidd_b TYPE edidd_tt
iv_idx_a TYPE i
iv_idx_b TYPE i
CHANGING
ct_diffs TYPE gty_tt_diffs.
DATA:
ls_diff TYPE gty_diff,
lv_prev_idx_a TYPE i,
lv_prev_idx_b TYPE i,
ls_edidd_a LIKE LINE OF it_edidd_a,
ls_edidd_b LIKE LINE OF it_edidd_b.
READ TABLE it_edidd_a INTO ls_edidd_a INDEX iv_idx_a.
READ TABLE it_edidd_b INTO ls_edidd_b INDEX iv_idx_b.
IF iv_idx_a > 0 AND iv_idx_b > 0 AND ls_edidd_a-segnam = ls_edidd_b-segnam AND ls_edidd_a-sdata = ls_edidd_b-sdata.
CLEAR ls_diff-type.
ls_diff-segnam = ls_edidd_a-segnam.
ls_diff-hlevel = ls_edidd_a-hlevel.
ls_diff-idx_a = iv_idx_a.
ls_diff-idx_b = iv_idx_b.
APPEND ls_diff TO ct_diffs.
PERFORM fill_diffs USING io_lcs_arr it_edidd_a it_edidd_b lv_prev_idx_a lv_prev_idx_b CHANGING ct_diffs.
ELSEIF iv_idx_b > 0 AND ( iv_idx_a = 0 OR io_lcs_arr->get_item( i = iv_idx_a j = lv_prev_idx_b ) >= io_lcs_arr->get_item( i = lv_prev_idx_a j = iv_idx_b ) ).
ls_diff-type = 'I'.
ls_diff-segnam = ls_edidd_b-segnam.
ls_diff-hlevel = ls_edidd_b-hlevel.
ls_diff-idx_b = iv_idx_b.
APPEND ls_diff TO ct_diffs.
PERFORM fill_diffs USING io_lcs_arr it_edidd_a it_edidd_b iv_idx_a lv_prev_idx_b CHANGING ct_diffs.
ELSEIF iv_idx_a > 0 AND ( iv_idx_b = 0 OR io_lcs_arr->get_item( i = iv_idx_a j = lv_prev_idx_b ) < io_lcs_arr->get_item( i = lv_prev_idx_a j = iv_idx_b ) ).
ls_diff-type = 'D'.
ls_diff-segnam = ls_edidd_a-segnam.
ls_diff-hlevel = ls_edidd_a-hlevel.
ls_diff-idx_a = iv_idx_a.
APPEND ls_diff TO ct_diffs.
PERFORM fill_diffs USING io_lcs_arr it_edidd_a it_edidd_b lv_prev_idx_a iv_idx_b CHANGING ct_diffs.
ENDIF.
ENDFORM. " fill_diffs
*&---------------------------------------------------------------------*
*& Form show_content
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IT_EDIDD_A text
* -->IT_EDIDD_B text
* -->IT_DIFFS text
* -->IV_SCREEN_LINE text
*----------------------------------------------------------------------*
FORM show_content
USING
it_edidd_a TYPE edidd_tt
it_edidd_b TYPE edidd_tt
it_diffs TYPE gty_tt_diffs
iv_screen_line TYPE i.
CONSTANTS:
lco_line_offset TYPE i VALUE 5.
DATA:
lv_index TYPE i,
ls_edidd_1 TYPE edidd,
ls_edidd_2 TYPE edidd,
ls_diff TYPE gty_diff.
lv_index = iv_screen_line - lco_line_offset.
READ TABLE it_diffs INTO ls_diff INDEX lv_index.
CASE ls_diff-type.
WHEN 'I'.
READ TABLE it_edidd_b INTO ls_edidd_1 INDEX ls_diff-idx_b.
PERFORM write_content USING ls_edidd_1.
WHEN 'D'.
READ TABLE it_edidd_a INTO ls_edidd_1 INDEX ls_diff-idx_a.
PERFORM write_content USING ls_edidd_1.
WHEN 'U'.
READ TABLE it_edidd_a INTO ls_edidd_1 INDEX ls_diff-idx_a.
READ TABLE it_edidd_b INTO ls_edidd_2 INDEX ls_diff-idx_b.
PERFORM write_content_diff USING ls_edidd_1 ls_edidd_2.
WHEN ' '.
READ TABLE it_edidd_a INTO ls_edidd_1 INDEX ls_diff-idx_a.
PERFORM write_content USING ls_edidd_1.
ENDCASE.
ENDFORM. " show_diff
*&---------------------------------------------------------------------*
*& Form aggregate_diffs
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->CT_DIFFS text
*----------------------------------------------------------------------*
FORM aggregate_diffs
CHANGING
ct_diffs TYPE gty_tt_diffs.
DATA:
lv_change_count TYPE i,
lv_index TYPE i,
ls_diff TYPE gty_diff,
lt_diffs TYPE gty_tt_diffs.
FIELD-SYMBOLS:
<diff> TYPE gty_diff,
<related_diff> TYPE gty_diff.
LOOP AT ct_diffs ASSIGNING <diff>.
lv_index = sy-tabix.
CASE <diff>-type.
WHEN 'I'.
READ TABLE lt_diffs INDEX 1 INTO ls_diff.
APPEND <diff> TO lt_diffs.
WHEN 'D'.
READ TABLE lt_diffs INDEX 1 INTO ls_diff.
IF sy-subrc = 0 AND ls_diff-type = 'I' AND ls_diff-segnam = <diff>-segnam.
ls_diff-idx_a = <diff>-idx_a.
DELETE ct_diffs INDEX lv_index.
DESCRIBE TABLE lt_diffs LINES lv_change_count.
lv_index = lv_index - lv_change_count.
READ TABLE ct_diffs ASSIGNING <related_diff> INDEX lv_index.
<related_diff>-type = 'U'.
<related_diff>-idx_a = ls_diff-idx_a.
DELETE lt_diffs INDEX 1.
ELSE.
APPEND <diff> TO lt_diffs.
ENDIF.
WHEN OTHERS.
CLEAR lt_diffs.
ENDCASE.
ENDLOOP.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG. SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG. Every effort is made to ensure content integrity. Use information on this site at your own risk.