Application Development and Automation 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: 
Read only

Program to compare versions of programs and customizing

Former Member
0 Likes
2,954

Hi All,

Does anyone know of a program that compare between versions of programs

and customizing between clients ?

I need a program that compare between all programs in the system, not just a single program.

Thanks,

Michal.

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
2,280

Hi,

I have the same requirement and checked out how transaction SE39 did remote compare. This is basically RFC enabled function module RPY_PROGRAM_READ. I wrote this program which can mass compare a list of programs between 2 systems ( normally one being local )

I have build in a rather primitive logic to ignore empty lines and different option to ignore ident and spaces. If a program with 1000 lines has one extra line in one of the systems at line 300, the program will say there are 700 lines differing. The purpose is to find programs there are not exactly identical - a 'normal' remote compare can then be done. The program is created as hotspot that takes you to SE38.

The program compares ABAP code and program texts.

I have tested this on 4.6C and ECC 5.0 systems

The usual disclaimer about no responsibility applies.

report z_remote_compare .

  • Mass remote compare programs

  • Ole Elmose QRAOLEE 2007-03-12

tables : rpy_prog, rfcdes.

************************************************************************

  • Selection screen

************************************************************************

selection-screen begin of block b1 with frame title text-001.

select-options: s_prname for rpy_prog-progname obligatory.

parameters : p_rfcde1 type rfcdes-rfcdest obligatory default 'LOCAL'.

parameters : p_rfcde2 type rfcdes-rfcdest obligatory.

selection-screen end of block b1.

selection-screen skip 1.

selection-screen begin of block b2 with frame title text-002.

parameters : rb_all radiobutton group spac.

parameters : rb_lead radiobutton group spac.

parameters : rb_no radiobutton group spac.

selection-screen end of block b2.

************************************************************************

  • DATA DECLARATION

************************************************************************

types : begin of gty_finaltab,

progname type progname,

version1 type versno,

version2 type versno,

changeon1 type rdir_udate,

changeon2 type rdir_udate,

changeby1 type unam,

changeby2 type unam,

count_abap1 type sytabix,

count_abap2 type sytabix,

error_abap type sytabix,

error_text type sytabix,

gen_text(60) type c,

selk type c,

color type lvc_t_scol, " color

end of gty_finaltab.

data : gt_source1 type standard table of abapsource.

data : ls_source1 type abapsource.

data : gt_source2 type standard table of abapsource.

data : ls_source2 type abapsource.

data : gt_textelem1 type standard table of textpool.

data : ls_textelem1 type textpool.

data : gt_textelem2 type standard table of textpool.

data : ls_textelem2 type textpool.

data : ls_progdata1 type rpy_prog.

data : ls_progdata2 type rpy_prog.

data : ld_progname type programm.

data : ld_spaces(6) type c.

data : ld_error_abap type sytabix.

data : ld_error_text type sytabix.

data : ld_count_abap1 type sytabix.

data : ld_count_abap2 type sytabix.

data : ld_count1 type sytabix.

data : ld_percent type i.

data : ld_text(50) type c.

data : ld_text_pro(4) type c.

data : ld_i_save type c.

data : gt_finaltab type standard table of gty_finaltab.

data : ls_finaltab type gty_finaltab.

data : ls_bdcdata type bdcdata.

data : gt_bdcdata type standard table of bdcdata.

      • ALV DATA ***

constants : lc_pick(7) type c value 'PICK'.

type-pools : slis.

data :

gt_fieldcat type slis_t_fieldcat_alv,

ls_fieldcat type slis_fieldcat_alv,

id_layout type slis_layout_alv,

repname type syrepid,

gt_events type slis_t_event.

  • Cell color

data: ls_cellcolor_tab type lvc_s_scol,

lt_cellcolor_tab type lvc_t_scol,

ls_color type lvc_s_colo.

  • CONSTANTS : lc_fname TYPE char7 VALUE 'STATUS'.

************************************************************************

  • START-OF-SELECTION.

************************************************************************

start-of-selection.

sort s_prname.

delete adjacent duplicates from s_prname.

describe table s_prname lines ld_count1.

loop at s_prname.

clear ld_error_abap.

clear ld_error_text.

clear ld_count_abap1.

clear ld_count_abap2.

clear ls_finaltab.

ld_progname = s_prname-low.

perform progressbar using sy-tabix ld_count1.

  • First RFC call for program details

clear gt_source1. clear gt_textelem1. clear ls_progdata1.

  • Get first ( local ) version

call function 'RPY_PROGRAM_READ'

destination p_rfcde1

exporting

language = sy-langu

program_name = ld_progname

with_includelist = ''

only_source = ' '

only_texts = ' '

read_latest_version = 'X'

with_lowercase = ' '

importing

prog_inf = ls_progdata1

tables

  • INCLUDE_TAB RPY_REPO OPTIONAL

source = gt_source1

textelements = gt_textelem1

exceptions

cancelled = 1

not_found = 2

permission_error = 3

communication_failure = 4

system failure = 5.

case sy-subrc.

when 0.

  • Delete empty lines

delete gt_source1 where line is initial.

  • Ignore program name in text

delete gt_textelem1 where id = 'R'.

delete gt_textelem1 where id = 'H'.

  • Number of lines of ABAP

describe table gt_source1[] lines ld_count_abap1 .

when 1.

ls_finaltab-gen_text = text-003.

when 2.

ls_finaltab-gen_text = text-004.

when 3.

ls_finaltab-gen_text = text-005.

when 4.

ls_finaltab-gen_text = text-006.

when 5.

ls_finaltab-gen_text = text-007.

endcase.

  • Second RFC call for program details

clear gt_source2. clear gt_textelem2. clear ls_progdata2.

  • Get remote version

call function 'RPY_PROGRAM_READ'

destination p_rfcde2

exporting

language = sy-langu

program_name = ld_progname

with_includelist = ''

only_source = ' '

only_texts = ' '

read_latest_version = 'X'

with_lowercase = ' '

importing

prog_inf = ls_progdata2

tables

  • INCLUDE_TAB RPY_REPO OPTIONAL

source = gt_source2

textelements = gt_textelem2

exceptions

cancelled = 1

not_found = 2

permission_error = 3

communication_failure = 4

system failure = 5.

case sy-subrc.

when 0.

  • Delete empty lines

delete gt_source2 where line is initial.

  • Ignore program name in text

delete gt_textelem2 where id = 'R'.

delete gt_textelem2 where id = 'H'.

  • Number of lines of ABAP

describe table gt_source2[] lines ld_count_abap2 .

when 1.

ls_finaltab-gen_text = text-003.

when 2.

ls_finaltab-gen_text = text-004.

when 3.

ls_finaltab-gen_text = text-005.

when 4.

ls_finaltab-gen_text = text-006.

when 5.

ls_finaltab-gen_text = text-007.

endcase. .

  • Remove space depending on readiobutton selection

if rb_all is initial.

if rb_no is initial.

  • Remove multiple+leadeing spaces

loop at gt_source1 into ls_source1.

condense ls_source1-line.

modify gt_source1 from ls_source1 transporting line.

endloop.

loop at gt_source2 into ls_source2.

condense ls_source2-line.

modify gt_source2 from ls_source2 transporting line.

endloop.

else.

  • Remove all spaces

loop at gt_source1 into ls_source1.

condense ls_source1-line no-gaps.

modify gt_source1 from ls_source1 transporting line.

endloop.

loop at gt_source2 into ls_source2.

condense ls_source2-line no-gaps .

modify gt_source2 from ls_source2 transporting line.

endloop.

endif.

endif.

  • Compare ABAP SOURCE

clear ld_error_abap.

loop at gt_source1 into ls_source1.

read table gt_source2 index sy-tabix into ls_source2.

if ls_source2-line ne ls_source1-line.

ld_error_abap = ld_error_abap + 1.

endif.

endloop.

  • Compare texts

clear ld_error_text.

loop at gt_textelem1 into ls_textelem1.

read table gt_textelem2 into ls_textelem2 index sy-tabix.

translate ls_textelem2-entry to lower case.

translate ls_textelem1-entry to lower case.

if ls_textelem2-id ne ls_textelem1-id

or ls_textelem2-key ne ls_textelem1-key

or ls_textelem2-entry ne ls_textelem1-entry.

ld_error_text = ld_error_text + 1.

endif.

endloop.

  • Put to ALV output table

ls_finaltab-progname = ld_progname.

ls_finaltab-version1 = ls_progdata1-version.

ls_finaltab-version2 = ls_progdata2-version.

ls_finaltab-changeon1 = ls_progdata1-mod_date.

ls_finaltab-changeon2 = ls_progdata2-mod_date.

ls_finaltab-changeby1 = ls_progdata1-mod_user.

ls_finaltab-changeby2 = ls_progdata2-mod_user.

ls_finaltab-count_abap1 = ld_count_abap1.

ls_finaltab-count_abap2 = ld_count_abap2.

ls_finaltab-error_abap = ld_error_abap.

*Adding the color.

if ls_finaltab-error_abap is initial.

ls_color-col = 5. "green

else.

ls_color-col = 6. "red

endif.

clear ls_cellcolor_tab.

clear lt_cellcolor_tab.

clear ls_finaltab-color.

ls_cellcolor_tab-fname = 'ERROR_ABAP'. " Field name to color

ls_color-int = 1.

ls_color-inv = 0.

move ls_color to ls_cellcolor_tab-color.

insert ls_cellcolor_tab into table

lt_cellcolor_tab.

insert lines of lt_cellcolor_tab

into table ls_finaltab-color.

ls_finaltab-error_text = ld_error_text.

*Adding the color.

if ls_finaltab-error_text is initial.

ls_color-col = 5. "green

else.

ls_color-col = 6. "red

endif.

clear ls_cellcolor_tab.

clear ls_finaltab-color.

ls_cellcolor_tab-fname = 'ERROR_TEXT'." Field name to color

ls_color-int = 1.

ls_color-inv = 0.

move ls_color to ls_cellcolor_tab-color.

insert ls_cellcolor_tab into table

lt_cellcolor_tab.

insert lines of lt_cellcolor_tab

into table ls_finaltab-color.

  • Move to internal table

append ls_finaltab to gt_finaltab.

endloop.

clear ls_finaltab.

perform fieldcat.

perform f4000_events changing gt_events.

perform layout_build using id_layout.

perform grid_disp.

----


  • FORM f4000_events_init *

----


  • ........ *

----


  • --> I_EVENTS *

----


form f4000_events changing i_events type slis_t_event.

data: line_event type slis_alv_event.

clear line_event.

line_event-name = 'PF_STATUS_SET'.

line_event-form = 'F4200_PF_STATUS_SET'.

append line_event to i_events.

clear line_event.

line_event-name = 'USER_COMMAND'.

line_event-form = 'F4300_USER_COMMAND'.

append line_event to i_events.

endform. " f3000_events_init

----


  • FORM f4200_pf_status_set *

----


  • ........ *

----


  • --> I_EXTAB *

----


form f4200_pf_status_set using i_extab type slis_t_extab.

refresh i_extab.

  • The PF status is an exact copy of the PF status 'STANDARD' of program

  • SAPLSALV

set pf-status 'STANDARD' excluding i_extab.

endform. "f4200_pf_status_set

----


  • FORM layout_build *

----


  • ........ *

----


  • --> P_LAYOUT *

----


form layout_build using p_layout type slis_layout_alv.

p_layout-box_fieldname = 'SELK'. " Checkbox

p_layout-get_selinfos = 'X'.

p_layout-f2code = 'PICK' . " Doppelklickfunktion

p_layout-key_hotspot = 'X'.

p_layout-info_fieldname = 'COL'.

p_layout-coltab_fieldname = 'COLOR'.

p_layout-zebra = 'X'. " Stripes

p_layout-colwidth_optimize = 'X'. " Optimize

endform. " layout_build

----


  • FORM GRIDDISP *

----


  • ........ *

----


form grid_disp.

repname = sy-repid.

call function 'REUSE_ALV_GRID_DISPLAY'

exporting

  • I_INTERFACE_CHECK = ' '

  • I_BYPASSING_BUFFER =

  • I_BUFFER_ACTIVE = ' '

i_callback_program = repname

  • I_CALLBACK_PF_STATUS_SET = ''

  • I_CALLBACK_USER_COMMAND = ''

  • I_CALLBACK_TOP_OF_PAGE = ' '

  • I_CALLBACK_HTML_TOP_OF_PAGE = ' '

  • I_CALLBACK_HTML_END_OF_LIST = ' '

  • I_STRUCTURE_NAME =

  • I_BACKGROUND_ID = ' '

  • i_grid_title = ws_title

  • I_GRID_SETTINGS =

is_layout = id_layout

it_fieldcat = gt_fieldcat[]

  • IT_EXCLUDING =

  • IT_SPECIAL_GROUPS =

  • IT_SORT =

  • IT_FILTER =

  • IS_SEL_HIDE =

  • I_DEFAULT = 'X'

i_save = ld_i_save

  • is_variant = ds_variant

it_events = gt_events[]

  • it_event_exit = gt_event_exit[]

  • IS_PRINT =

  • IS_REPREP_ID =

  • I_SCREEN_START_COLUMN = 0

  • I_SCREEN_START_LINE = 0

  • I_SCREEN_END_COLUMN = 0

  • I_SCREEN_END_LINE = 0

  • IT_ALV_GRAPHICS =

  • IT_ADD_FIELDCAT =

  • IT_HYPERLINK =

  • I_HTML_HEIGHT_TOP =

  • I_HTML_HEIGHT_END =

  • IT_EXCEPT_QINFO =

  • IMPORTING

  • E_EXIT_CAUSED_BY_CALLER =

  • ES_EXIT_CAUSED_BY_USER =

tables

t_outtab = gt_finaltab

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. " grid_disp

&----


*& Form fieldcat

&----


  • text

----


  • --> p1 text

  • <-- p2 text

----


form fieldcat.

data: pos type i.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'PROGNAME'.

ls_fieldcat-seltext_m = 'Program name'.

ls_fieldcat-seltext_s = 'Program name'.

ls_fieldcat-seltext_l = 'Program name'.

ls_fieldcat-ddictxt = 'L'.

ls_fieldcat-hotspot = 'X'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'VERSION1'.

ls_fieldcat-seltext_m = 'Version 1'.

ls_fieldcat-seltext_s = 'Version 1'.

ls_fieldcat-seltext_l = 'Version 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'VERSION2'.

ls_fieldcat-seltext_m = 'Version 2'.

ls_fieldcat-seltext_s = 'Version 2'.

ls_fieldcat-seltext_l = 'Version 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEON1'.

ls_fieldcat-seltext_m = 'Changed on 1'.

ls_fieldcat-seltext_s = 'Changed on 1'.

ls_fieldcat-seltext_l = 'Changed on 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEON2'.

ls_fieldcat-seltext_m = 'Changed on 2'.

ls_fieldcat-seltext_s = 'Changed on 2'.

ls_fieldcat-seltext_l = 'Changed on 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEBY1'.

ls_fieldcat-seltext_m = 'Changed by 1'.

ls_fieldcat-seltext_s = 'Changed by 1'.

ls_fieldcat-seltext_l = 'Changed by 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEBY2'.

ls_fieldcat-seltext_m = 'Changed by 2'.

ls_fieldcat-seltext_s = 'Changed by 2'.

ls_fieldcat-seltext_l = 'Changed by 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'COUNT_ABAP1'.

ls_fieldcat-seltext_m = 'Count 1'.

ls_fieldcat-seltext_s = 'Count 1'.

ls_fieldcat-seltext_l = 'Count 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'COUNT_ABAP2'.

ls_fieldcat-seltext_m = 'Count 2'.

ls_fieldcat-seltext_s = 'Count 2'.

ls_fieldcat-seltext_l = 'Count 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'ERROR_ABAP'.

ls_fieldcat-seltext_m = 'ABAP differences'.

ls_fieldcat-seltext_s = 'ABAP differences'.

ls_fieldcat-seltext_l = 'ABAP differences'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'ERROR_TEXT'.

ls_fieldcat-seltext_m = 'Text differences'.

ls_fieldcat-seltext_s = 'Text differences'.

ls_fieldcat-seltext_l = 'Text differences'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'GEN_TEXT'.

ls_fieldcat-seltext_m = 'Status'.

ls_fieldcat-seltext_s = 'Status'.

ls_fieldcat-seltext_l = 'Status'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

endform. " fieldcat

&----


*& Form progressbar

&----


  • text

----


  • -->P_SY_TABIX text

  • -->P_LD_COUNT1 text

----


form progressbar using p_tabix p_count.

ld_percent = 100 * ( p_tabix - 1 ) / p_count.

move ld_percent to ld_text_pro.

ld_text = '% of programs processed'.

concatenate ld_text_pro ld_text into ld_text

separated by space.

call function 'SAPGUI_PROGRESS_INDICATOR'

exporting

percentage = ld_percent

text = ld_text.

endform. " progressbar

----


  • FORM f4300_user_command *

----


  • ........ *

----


  • --> UCOMM *

  • --> SELFIELD *

----


form f4300_user_command using ucomm like sy-ucomm

ls_selfield type slis_selfield.

  • Per default, keep position and refresh screen with DISPLAY

ls_selfield-col_stable = 'X'.

ls_selfield-row_stable = 'X'.

ls_selfield-refresh = 'X'.

case ucomm.

  • Double-click **********************

when lc_pick. " Doubleclick anywhere on line + hotspot

read table gt_finaltab index ls_selfield-tabindex into

ls_finaltab.

clear gt_bdcdata.

perform bdc_dynpro using 'SAPLWBABAP' '0100'.

perform bdc_field using 'RS38M-FUNC_EDIT' 'X'.

perform bdc_field using 'rs38m-programm'

ls_finaltab-progname.

perform bdc_field using 'BDC_OKCODE' '=SHOP'.

call transaction 'SE38' using gt_bdcdata mode 'E'.

when others.

endcase.

clear ucomm.

endform. " f4300_user_command

&----


*& Form bdc_dynpro

&----


  • text

----


  • -->PROGRAM

  • -->DYNPRO

----


form bdc_dynpro using

program

dynpro.

clear ls_bdcdata.

ls_bdcdata-program = program.

ls_bdcdata-dynpro = dynpro.

ls_bdcdata-dynbegin = 'X'.

append ls_bdcdata to gt_bdcdata.

endform. " bdc_dynpro

----


  • FORM BDC_FIELD *

----


  • ........ *

----


  • --> FNAM *

  • --> FVAL *

----


form bdc_field using

fnam

fval.

clear ls_bdcdata.

ls_bdcdata-fnam = fnam.

move fval to ls_bdcdata-fval .

append ls_bdcdata to gt_bdcdata.

endform. " bdc_field

Please use these text symbols :

001 Selection data

002 Text compression

003 RFC Call cancelled

004 Program does not exits on RFC target

005 RFC permission denied

006 RFC communication error

007 RFC system failure

and these selection texts :

P_RFCDE1 RFC Connection 1

P_RFCDE2 RFC Connection 2

RB_ALL Include identation

RB_LEAD Ignore leading spaces

RB_NO Ignore all spaces

S_PRNAME Program name

Hope someone finds this useful.

- Ole Elmose

Hi All,

Does anyone know of a program that compare between versions of programs

and customizing between clients ?

I need a program that compare between all programs in the system, not just a single program.

Thanks,

Michal.

6 REPLIES 6
Read only

Former Member
0 Likes
2,280

Hi,

For programs use UTILITIES --> VERSION --> VERSION MANAGEMENT.

Cheer

VJ

Read only

0 Likes
2,280

Thanks, I know that.

I need to compare all programs, this is good for a single program.

Read only

0 Likes
2,280

Hi Michal,

Oh ok... guess you have to write your own utility to compare all programs. I dont think SAP has provided a std utility.

Cheers

VJ

Read only

Former Member
0 Likes
2,280

check the Tcode SE39

limitations :

U can do it on a single program level

give the program name and compare the versions between different systems .

regards,

vijay.

Read only

raviprakash
Product and Topic Expert
Product and Topic Expert
0 Likes
2,280

Hi Michal,

I know the SAP Standard program, which compares the the different versions of a same program. This SAP Standard program can also be used to do remote comparision of the different versions of the same program too.

The programs used for the Report comparision are: RSVRSRE1

RSVRSRS1

RSVRSRE3.

NOTE: The observed pattern for the SAP Standard Comparision Programs is

RSVRS***.

Probably you can create your own function module which would take the program names as the input and provide the comparision result.

NOTE: Please award points if you are satisfied with the solution.

Thanks and regards,

Ravi.

Read only

Former Member
0 Likes
2,281

Hi,

I have the same requirement and checked out how transaction SE39 did remote compare. This is basically RFC enabled function module RPY_PROGRAM_READ. I wrote this program which can mass compare a list of programs between 2 systems ( normally one being local )

I have build in a rather primitive logic to ignore empty lines and different option to ignore ident and spaces. If a program with 1000 lines has one extra line in one of the systems at line 300, the program will say there are 700 lines differing. The purpose is to find programs there are not exactly identical - a 'normal' remote compare can then be done. The program is created as hotspot that takes you to SE38.

The program compares ABAP code and program texts.

I have tested this on 4.6C and ECC 5.0 systems

The usual disclaimer about no responsibility applies.

report z_remote_compare .

  • Mass remote compare programs

  • Ole Elmose QRAOLEE 2007-03-12

tables : rpy_prog, rfcdes.

************************************************************************

  • Selection screen

************************************************************************

selection-screen begin of block b1 with frame title text-001.

select-options: s_prname for rpy_prog-progname obligatory.

parameters : p_rfcde1 type rfcdes-rfcdest obligatory default 'LOCAL'.

parameters : p_rfcde2 type rfcdes-rfcdest obligatory.

selection-screen end of block b1.

selection-screen skip 1.

selection-screen begin of block b2 with frame title text-002.

parameters : rb_all radiobutton group spac.

parameters : rb_lead radiobutton group spac.

parameters : rb_no radiobutton group spac.

selection-screen end of block b2.

************************************************************************

  • DATA DECLARATION

************************************************************************

types : begin of gty_finaltab,

progname type progname,

version1 type versno,

version2 type versno,

changeon1 type rdir_udate,

changeon2 type rdir_udate,

changeby1 type unam,

changeby2 type unam,

count_abap1 type sytabix,

count_abap2 type sytabix,

error_abap type sytabix,

error_text type sytabix,

gen_text(60) type c,

selk type c,

color type lvc_t_scol, " color

end of gty_finaltab.

data : gt_source1 type standard table of abapsource.

data : ls_source1 type abapsource.

data : gt_source2 type standard table of abapsource.

data : ls_source2 type abapsource.

data : gt_textelem1 type standard table of textpool.

data : ls_textelem1 type textpool.

data : gt_textelem2 type standard table of textpool.

data : ls_textelem2 type textpool.

data : ls_progdata1 type rpy_prog.

data : ls_progdata2 type rpy_prog.

data : ld_progname type programm.

data : ld_spaces(6) type c.

data : ld_error_abap type sytabix.

data : ld_error_text type sytabix.

data : ld_count_abap1 type sytabix.

data : ld_count_abap2 type sytabix.

data : ld_count1 type sytabix.

data : ld_percent type i.

data : ld_text(50) type c.

data : ld_text_pro(4) type c.

data : ld_i_save type c.

data : gt_finaltab type standard table of gty_finaltab.

data : ls_finaltab type gty_finaltab.

data : ls_bdcdata type bdcdata.

data : gt_bdcdata type standard table of bdcdata.

      • ALV DATA ***

constants : lc_pick(7) type c value 'PICK'.

type-pools : slis.

data :

gt_fieldcat type slis_t_fieldcat_alv,

ls_fieldcat type slis_fieldcat_alv,

id_layout type slis_layout_alv,

repname type syrepid,

gt_events type slis_t_event.

  • Cell color

data: ls_cellcolor_tab type lvc_s_scol,

lt_cellcolor_tab type lvc_t_scol,

ls_color type lvc_s_colo.

  • CONSTANTS : lc_fname TYPE char7 VALUE 'STATUS'.

************************************************************************

  • START-OF-SELECTION.

************************************************************************

start-of-selection.

sort s_prname.

delete adjacent duplicates from s_prname.

describe table s_prname lines ld_count1.

loop at s_prname.

clear ld_error_abap.

clear ld_error_text.

clear ld_count_abap1.

clear ld_count_abap2.

clear ls_finaltab.

ld_progname = s_prname-low.

perform progressbar using sy-tabix ld_count1.

  • First RFC call for program details

clear gt_source1. clear gt_textelem1. clear ls_progdata1.

  • Get first ( local ) version

call function 'RPY_PROGRAM_READ'

destination p_rfcde1

exporting

language = sy-langu

program_name = ld_progname

with_includelist = ''

only_source = ' '

only_texts = ' '

read_latest_version = 'X'

with_lowercase = ' '

importing

prog_inf = ls_progdata1

tables

  • INCLUDE_TAB RPY_REPO OPTIONAL

source = gt_source1

textelements = gt_textelem1

exceptions

cancelled = 1

not_found = 2

permission_error = 3

communication_failure = 4

system failure = 5.

case sy-subrc.

when 0.

  • Delete empty lines

delete gt_source1 where line is initial.

  • Ignore program name in text

delete gt_textelem1 where id = 'R'.

delete gt_textelem1 where id = 'H'.

  • Number of lines of ABAP

describe table gt_source1[] lines ld_count_abap1 .

when 1.

ls_finaltab-gen_text = text-003.

when 2.

ls_finaltab-gen_text = text-004.

when 3.

ls_finaltab-gen_text = text-005.

when 4.

ls_finaltab-gen_text = text-006.

when 5.

ls_finaltab-gen_text = text-007.

endcase.

  • Second RFC call for program details

clear gt_source2. clear gt_textelem2. clear ls_progdata2.

  • Get remote version

call function 'RPY_PROGRAM_READ'

destination p_rfcde2

exporting

language = sy-langu

program_name = ld_progname

with_includelist = ''

only_source = ' '

only_texts = ' '

read_latest_version = 'X'

with_lowercase = ' '

importing

prog_inf = ls_progdata2

tables

  • INCLUDE_TAB RPY_REPO OPTIONAL

source = gt_source2

textelements = gt_textelem2

exceptions

cancelled = 1

not_found = 2

permission_error = 3

communication_failure = 4

system failure = 5.

case sy-subrc.

when 0.

  • Delete empty lines

delete gt_source2 where line is initial.

  • Ignore program name in text

delete gt_textelem2 where id = 'R'.

delete gt_textelem2 where id = 'H'.

  • Number of lines of ABAP

describe table gt_source2[] lines ld_count_abap2 .

when 1.

ls_finaltab-gen_text = text-003.

when 2.

ls_finaltab-gen_text = text-004.

when 3.

ls_finaltab-gen_text = text-005.

when 4.

ls_finaltab-gen_text = text-006.

when 5.

ls_finaltab-gen_text = text-007.

endcase. .

  • Remove space depending on readiobutton selection

if rb_all is initial.

if rb_no is initial.

  • Remove multiple+leadeing spaces

loop at gt_source1 into ls_source1.

condense ls_source1-line.

modify gt_source1 from ls_source1 transporting line.

endloop.

loop at gt_source2 into ls_source2.

condense ls_source2-line.

modify gt_source2 from ls_source2 transporting line.

endloop.

else.

  • Remove all spaces

loop at gt_source1 into ls_source1.

condense ls_source1-line no-gaps.

modify gt_source1 from ls_source1 transporting line.

endloop.

loop at gt_source2 into ls_source2.

condense ls_source2-line no-gaps .

modify gt_source2 from ls_source2 transporting line.

endloop.

endif.

endif.

  • Compare ABAP SOURCE

clear ld_error_abap.

loop at gt_source1 into ls_source1.

read table gt_source2 index sy-tabix into ls_source2.

if ls_source2-line ne ls_source1-line.

ld_error_abap = ld_error_abap + 1.

endif.

endloop.

  • Compare texts

clear ld_error_text.

loop at gt_textelem1 into ls_textelem1.

read table gt_textelem2 into ls_textelem2 index sy-tabix.

translate ls_textelem2-entry to lower case.

translate ls_textelem1-entry to lower case.

if ls_textelem2-id ne ls_textelem1-id

or ls_textelem2-key ne ls_textelem1-key

or ls_textelem2-entry ne ls_textelem1-entry.

ld_error_text = ld_error_text + 1.

endif.

endloop.

  • Put to ALV output table

ls_finaltab-progname = ld_progname.

ls_finaltab-version1 = ls_progdata1-version.

ls_finaltab-version2 = ls_progdata2-version.

ls_finaltab-changeon1 = ls_progdata1-mod_date.

ls_finaltab-changeon2 = ls_progdata2-mod_date.

ls_finaltab-changeby1 = ls_progdata1-mod_user.

ls_finaltab-changeby2 = ls_progdata2-mod_user.

ls_finaltab-count_abap1 = ld_count_abap1.

ls_finaltab-count_abap2 = ld_count_abap2.

ls_finaltab-error_abap = ld_error_abap.

*Adding the color.

if ls_finaltab-error_abap is initial.

ls_color-col = 5. "green

else.

ls_color-col = 6. "red

endif.

clear ls_cellcolor_tab.

clear lt_cellcolor_tab.

clear ls_finaltab-color.

ls_cellcolor_tab-fname = 'ERROR_ABAP'. " Field name to color

ls_color-int = 1.

ls_color-inv = 0.

move ls_color to ls_cellcolor_tab-color.

insert ls_cellcolor_tab into table

lt_cellcolor_tab.

insert lines of lt_cellcolor_tab

into table ls_finaltab-color.

ls_finaltab-error_text = ld_error_text.

*Adding the color.

if ls_finaltab-error_text is initial.

ls_color-col = 5. "green

else.

ls_color-col = 6. "red

endif.

clear ls_cellcolor_tab.

clear ls_finaltab-color.

ls_cellcolor_tab-fname = 'ERROR_TEXT'." Field name to color

ls_color-int = 1.

ls_color-inv = 0.

move ls_color to ls_cellcolor_tab-color.

insert ls_cellcolor_tab into table

lt_cellcolor_tab.

insert lines of lt_cellcolor_tab

into table ls_finaltab-color.

  • Move to internal table

append ls_finaltab to gt_finaltab.

endloop.

clear ls_finaltab.

perform fieldcat.

perform f4000_events changing gt_events.

perform layout_build using id_layout.

perform grid_disp.

----


  • FORM f4000_events_init *

----


  • ........ *

----


  • --> I_EVENTS *

----


form f4000_events changing i_events type slis_t_event.

data: line_event type slis_alv_event.

clear line_event.

line_event-name = 'PF_STATUS_SET'.

line_event-form = 'F4200_PF_STATUS_SET'.

append line_event to i_events.

clear line_event.

line_event-name = 'USER_COMMAND'.

line_event-form = 'F4300_USER_COMMAND'.

append line_event to i_events.

endform. " f3000_events_init

----


  • FORM f4200_pf_status_set *

----


  • ........ *

----


  • --> I_EXTAB *

----


form f4200_pf_status_set using i_extab type slis_t_extab.

refresh i_extab.

  • The PF status is an exact copy of the PF status 'STANDARD' of program

  • SAPLSALV

set pf-status 'STANDARD' excluding i_extab.

endform. "f4200_pf_status_set

----


  • FORM layout_build *

----


  • ........ *

----


  • --> P_LAYOUT *

----


form layout_build using p_layout type slis_layout_alv.

p_layout-box_fieldname = 'SELK'. " Checkbox

p_layout-get_selinfos = 'X'.

p_layout-f2code = 'PICK' . " Doppelklickfunktion

p_layout-key_hotspot = 'X'.

p_layout-info_fieldname = 'COL'.

p_layout-coltab_fieldname = 'COLOR'.

p_layout-zebra = 'X'. " Stripes

p_layout-colwidth_optimize = 'X'. " Optimize

endform. " layout_build

----


  • FORM GRIDDISP *

----


  • ........ *

----


form grid_disp.

repname = sy-repid.

call function 'REUSE_ALV_GRID_DISPLAY'

exporting

  • I_INTERFACE_CHECK = ' '

  • I_BYPASSING_BUFFER =

  • I_BUFFER_ACTIVE = ' '

i_callback_program = repname

  • I_CALLBACK_PF_STATUS_SET = ''

  • I_CALLBACK_USER_COMMAND = ''

  • I_CALLBACK_TOP_OF_PAGE = ' '

  • I_CALLBACK_HTML_TOP_OF_PAGE = ' '

  • I_CALLBACK_HTML_END_OF_LIST = ' '

  • I_STRUCTURE_NAME =

  • I_BACKGROUND_ID = ' '

  • i_grid_title = ws_title

  • I_GRID_SETTINGS =

is_layout = id_layout

it_fieldcat = gt_fieldcat[]

  • IT_EXCLUDING =

  • IT_SPECIAL_GROUPS =

  • IT_SORT =

  • IT_FILTER =

  • IS_SEL_HIDE =

  • I_DEFAULT = 'X'

i_save = ld_i_save

  • is_variant = ds_variant

it_events = gt_events[]

  • it_event_exit = gt_event_exit[]

  • IS_PRINT =

  • IS_REPREP_ID =

  • I_SCREEN_START_COLUMN = 0

  • I_SCREEN_START_LINE = 0

  • I_SCREEN_END_COLUMN = 0

  • I_SCREEN_END_LINE = 0

  • IT_ALV_GRAPHICS =

  • IT_ADD_FIELDCAT =

  • IT_HYPERLINK =

  • I_HTML_HEIGHT_TOP =

  • I_HTML_HEIGHT_END =

  • IT_EXCEPT_QINFO =

  • IMPORTING

  • E_EXIT_CAUSED_BY_CALLER =

  • ES_EXIT_CAUSED_BY_USER =

tables

t_outtab = gt_finaltab

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. " grid_disp

&----


*& Form fieldcat

&----


  • text

----


  • --> p1 text

  • <-- p2 text

----


form fieldcat.

data: pos type i.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'PROGNAME'.

ls_fieldcat-seltext_m = 'Program name'.

ls_fieldcat-seltext_s = 'Program name'.

ls_fieldcat-seltext_l = 'Program name'.

ls_fieldcat-ddictxt = 'L'.

ls_fieldcat-hotspot = 'X'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'VERSION1'.

ls_fieldcat-seltext_m = 'Version 1'.

ls_fieldcat-seltext_s = 'Version 1'.

ls_fieldcat-seltext_l = 'Version 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'VERSION2'.

ls_fieldcat-seltext_m = 'Version 2'.

ls_fieldcat-seltext_s = 'Version 2'.

ls_fieldcat-seltext_l = 'Version 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEON1'.

ls_fieldcat-seltext_m = 'Changed on 1'.

ls_fieldcat-seltext_s = 'Changed on 1'.

ls_fieldcat-seltext_l = 'Changed on 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEON2'.

ls_fieldcat-seltext_m = 'Changed on 2'.

ls_fieldcat-seltext_s = 'Changed on 2'.

ls_fieldcat-seltext_l = 'Changed on 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEBY1'.

ls_fieldcat-seltext_m = 'Changed by 1'.

ls_fieldcat-seltext_s = 'Changed by 1'.

ls_fieldcat-seltext_l = 'Changed by 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'CHANGEBY2'.

ls_fieldcat-seltext_m = 'Changed by 2'.

ls_fieldcat-seltext_s = 'Changed by 2'.

ls_fieldcat-seltext_l = 'Changed by 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'COUNT_ABAP1'.

ls_fieldcat-seltext_m = 'Count 1'.

ls_fieldcat-seltext_s = 'Count 1'.

ls_fieldcat-seltext_l = 'Count 1'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'COUNT_ABAP2'.

ls_fieldcat-seltext_m = 'Count 2'.

ls_fieldcat-seltext_s = 'Count 2'.

ls_fieldcat-seltext_l = 'Count 2'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'ERROR_ABAP'.

ls_fieldcat-seltext_m = 'ABAP differences'.

ls_fieldcat-seltext_s = 'ABAP differences'.

ls_fieldcat-seltext_l = 'ABAP differences'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'ERROR_TEXT'.

ls_fieldcat-seltext_m = 'Text differences'.

ls_fieldcat-seltext_s = 'Text differences'.

ls_fieldcat-seltext_l = 'Text differences'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

pos = pos + 1.

ls_fieldcat-col_pos = pos.

ls_fieldcat-tabname = 'gt_fulltab'.

ls_fieldcat-fieldname = 'GEN_TEXT'.

ls_fieldcat-seltext_m = 'Status'.

ls_fieldcat-seltext_s = 'Status'.

ls_fieldcat-seltext_l = 'Status'.

ls_fieldcat-ddictxt = 'L'.

append ls_fieldcat to gt_fieldcat.

clear ls_fieldcat.

endform. " fieldcat

&----


*& Form progressbar

&----


  • text

----


  • -->P_SY_TABIX text

  • -->P_LD_COUNT1 text

----


form progressbar using p_tabix p_count.

ld_percent = 100 * ( p_tabix - 1 ) / p_count.

move ld_percent to ld_text_pro.

ld_text = '% of programs processed'.

concatenate ld_text_pro ld_text into ld_text

separated by space.

call function 'SAPGUI_PROGRESS_INDICATOR'

exporting

percentage = ld_percent

text = ld_text.

endform. " progressbar

----


  • FORM f4300_user_command *

----


  • ........ *

----


  • --> UCOMM *

  • --> SELFIELD *

----


form f4300_user_command using ucomm like sy-ucomm

ls_selfield type slis_selfield.

  • Per default, keep position and refresh screen with DISPLAY

ls_selfield-col_stable = 'X'.

ls_selfield-row_stable = 'X'.

ls_selfield-refresh = 'X'.

case ucomm.

  • Double-click **********************

when lc_pick. " Doubleclick anywhere on line + hotspot

read table gt_finaltab index ls_selfield-tabindex into

ls_finaltab.

clear gt_bdcdata.

perform bdc_dynpro using 'SAPLWBABAP' '0100'.

perform bdc_field using 'RS38M-FUNC_EDIT' 'X'.

perform bdc_field using 'rs38m-programm'

ls_finaltab-progname.

perform bdc_field using 'BDC_OKCODE' '=SHOP'.

call transaction 'SE38' using gt_bdcdata mode 'E'.

when others.

endcase.

clear ucomm.

endform. " f4300_user_command

&----


*& Form bdc_dynpro

&----


  • text

----


  • -->PROGRAM

  • -->DYNPRO

----


form bdc_dynpro using

program

dynpro.

clear ls_bdcdata.

ls_bdcdata-program = program.

ls_bdcdata-dynpro = dynpro.

ls_bdcdata-dynbegin = 'X'.

append ls_bdcdata to gt_bdcdata.

endform. " bdc_dynpro

----


  • FORM BDC_FIELD *

----


  • ........ *

----


  • --> FNAM *

  • --> FVAL *

----


form bdc_field using

fnam

fval.

clear ls_bdcdata.

ls_bdcdata-fnam = fnam.

move fval to ls_bdcdata-fval .

append ls_bdcdata to gt_bdcdata.

endform. " bdc_field

Please use these text symbols :

001 Selection data

002 Text compression

003 RFC Call cancelled

004 Program does not exits on RFC target

005 RFC permission denied

006 RFC communication error

007 RFC system failure

and these selection texts :

P_RFCDE1 RFC Connection 1

P_RFCDE2 RFC Connection 2

RB_ALL Include identation

RB_LEAD Ignore leading spaces

RB_NO Ignore all spaces

S_PRNAME Program name

Hope someone finds this useful.

- Ole Elmose