Adobe Forms – XML version comparison tool

Estimated read time 13 min read

Hello everyone,

In this blog I’ll present to you an alternative way to compare Adobe Form layout XML versions.

Introduction

As you may know, comparing Adobe Forms layout XML versions can be a time-consuming and cumbersome task.

For simpler objects such as programs/includes/classes/etc we can always rely on the split-screen version comparison tool:


However, it’s not quite simple when it comes to compare Adobe Form XML versions.
You’d have to browse into each version and download its XML Source, and then compare it using an external editor / comparison tool:


In order to facilitate/streamline that, I’ve built a tool that can do all that with more ease, very similar to what we can do with programs/includes/classes/etc.

Solution

In short, in this new program:

You enter a form nameChoose the two versions you want to compare and press ‘Compare XML’

Source code:

*&———————————————————————*
*& Report YJPEREZ_AFORM_COMPARE_XML_VERS
*&———————————————————————*
*&
*&———————————————————————*
REPORT yjperez_aform_compare_xml_vers.

SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.

PARAMETERS: p_aform TYPE fpcontextt-name.

CLASS lcl_event_handler DEFINITION.

PUBLIC SECTION.

CLASS-METHODS
user_command FOR EVENT after_user_command OF cl_gui_alv_grid IMPORTING e_ucomm.
CLASS-METHODS
toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object.

PRIVATE SECTION.

CONSTANTS c_ucomm_compare_xml TYPE sy-ucomm VALUE ‘CMP_XML’.

ENDCLASS.

AT SELECTION-SCREEN OUTPUT.

DATA lt_excluded_sel_functions TYPE TABLE OF rsexfcode.
lt_excluded_sel_functions = VALUE #(
( fcode = ‘GET’ )
( fcode = ‘VSHO’ )
( fcode = ‘VDEL’ )
( fcode = ‘SPOS’ )
).

CALL FUNCTION ‘RS_SET_SELSCREEN_STATUS’
EXPORTING
p_status = sy-pfkey
TABLES
p_exclude = lt_excluded_sel_functions.

START-OF-SELECTION.

TRY.

DATA(lv_objtype_adobe_form) = CONV vrsd-objtype( ‘SFPF’ ).

DATA(lo_vers_alv) = NEW cl_vers_objtype_ui_alv(
iv_objname = |{ p_aform }|
iv_objtype = lv_objtype_adobe_form
).

lo_vers_alv->get_vrs_for_display(
IMPORTING
et_vrs_disp = DATA(lt_vers_data)
).

TYPES:
BEGIN OF ts_simple_vers_data,
status TYPE vrs_disp-status,
versno TYPE vrs_disp-versno,
versnum TYPE vrs_disp-versnum,
rel TYPE vrs_disp-rel,
korrno TYPE vrs_disp-korrno,
korrtext TYPE vrs_disp-korrtext,
project TYPE vrs_disp-project,
date TYPE vrs_disp-date,
time TYPE vrs_disp-time,
usr TYPE vrs_disp-usr,
END OF ts_simple_vers_data.

DATA lt_simple_vers_data TYPE TABLE OF ts_simple_vers_data.

DATA(lo_grid) = NEW cl_gui_alv_grid(
i_parent = cl_gui_container=>screen0
i_appl_events = abap_true
).

DATA(ls_grid_layout) = VALUE lvc_s_layo(
sel_mode = if_dmc_ui_view_list_builder=>co_selection_mode_multiple
).

DATA(lo_simple_vers_data_descr) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data(
p_data = lt_simple_vers_data
) ).

DATA(lo_simple_vers_data_line_descr) = CAST cl_abap_structdescr( lo_simple_vers_data_descr->get_table_line_type( ) ).

DATA(lt_field_cat) = VALUE lvc_t_fcat( ).

DATA(lt_components) = lo_simple_vers_data_line_descr->get_components( ).
LOOP AT lt_components INTO DATA(ls_component).

DATA(lo_elemdescr) = CAST cl_abap_elemdescr( ls_component-type ).
DATA(ls_ddic) = lo_elemdescr->get_ddic_field( ).

APPEND VALUE #(
fieldname = ls_component-name
scrtext_s = ls_ddic-scrtext_s
scrtext_m = ls_ddic-scrtext_m
scrtext_l = ls_ddic-scrtext_l
col_opt = abap_true
) TO lt_field_cat.

ENDLOOP.

lt_simple_vers_data = CORRESPONDING #( lt_vers_data ).

lo_grid->set_table_for_first_display(
EXPORTING
is_layout = ls_grid_layout
CHANGING
it_fieldcatalog = lt_field_cat
it_outtab = lt_simple_vers_data
).

SET HANDLER lcl_event_handler=>toolbar FOR lo_grid.
SET HANDLER lcl_event_handler=>user_command FOR lo_grid.

lo_grid->set_ready_for_input( 1 ).

CALL SELECTION-SCREEN 2000.

CATCH cx_root INTO DATA(lx_root).

MESSAGE lx_root->get_longtext( ) TYPE ‘I’.

ENDTRY.

CLASS lcl_event_handler IMPLEMENTATION.

METHOD toolbar.

CLEAR: e_object->mt_toolbar.

APPEND VALUE #(
butn_type = if_sat_ui_button_types=>normal
function = c_ucomm_compare_xml
icon = ‘@46@’
text = ‘Compare XML’
) TO e_object->mt_toolbar.

ENDMETHOD.

METHOD user_command.

CASE e_ucomm.

WHEN c_ucomm_compare_xml .

lo_grid->get_selected_rows(
IMPORTING
et_index_rows = DATA(lt_index_rows)
).

IF lines( lt_index_rows ) = 2.

DATA(ls_left_version) = lt_simple_vers_data[ lt_index_rows[ 1 ] ].
DATA(lo_left_form) = cl_fp_wb_helper=>form_create_from_version(
i_name = p_aform
i_version = CONV #( ls_left_version-versno )
).
DATA(lo_left_form_obj) = CAST cl_fp_form( lo_left_form->get_object( ) ).
DATA(lo_left_form_lay) = lo_left_form_obj->if_fp_form~get_layout( ).
DATA(lv_left_version_xstr) = lo_left_form_lay->get_layout_data( ).
DATA(lv_left_version_str) = cl_bcs_convert=>xstring_to_string(
iv_xstr = lv_left_version_xstr
iv_cp = cl_ehprc_c_gen_cp=>code_page_latin1
).

SPLIT lv_left_version_str AT cl_abap_char_utilities=>cr_lf INTO TABLE DATA(lt_left_version_str).

DATA(ls_right_version) = lt_simple_vers_data[ lt_index_rows[ 2 ] ].
DATA(lo_right_form) = cl_fp_wb_helper=>form_create_from_version(
i_name = p_aform
i_version = CONV #( ls_right_version-versno )
).
DATA(lo_right_form_obj) = CAST cl_fp_form( lo_right_form->get_object( ) ).
DATA(lo_right_form_lay) = lo_right_form_obj->if_fp_form~get_layout( ).
DATA(lv_right_version_xstr) = lo_right_form_lay->get_layout_data( ).
DATA(lv_right_version_str) = cl_bcs_convert=>xstring_to_string(
iv_xstr = lv_right_version_xstr
iv_cp = cl_ehprc_c_gen_cp=>code_page_latin1
).

SPLIT lv_right_version_str AT cl_abap_char_utilities=>cr_lf INTO TABLE DATA(lt_right_version_str).

lo_grid->set_visible( abap_false ).

DATA(ls_transport_key) = VALUE trkey(
obj_type = lv_objtype_adobe_form
obj_name = p_aform
sub_type = lv_objtype_adobe_form
sub_name = p_aform
).

DATA(lv_title_left) = |{ ls_left_version-versno } ({ ls_left_version-date DATE = ENVIRONMENT } { ls_left_version-time TIME = ENVIRONMENT })|.
DATA(lv_title_right) = |{ ls_right_version-versno } ({ ls_right_version-date DATE = ENVIRONMENT } { ls_right_version-time TIME = ENVIRONMENT })|.

DATA(lt_source_l) = CONV rswsourcet( lt_left_version_str ).
DATA(lt_source_r) = CONV rswsourcet( lt_right_version_str ).
CALL FUNCTION ‘WB_SPLIT_EDITOR_START’
EXPORTING
mode_left = swbm_c_op_display
mode_right = swbm_c_op_display
object_left = CONV syrepid( p_aform )
object_right = CONV syrepid( p_aform )
title_left = lv_title_left
title_right = lv_title_right
transport_key_l = ls_transport_key
TABLES
source_l = lt_source_l
source_r = lt_source_r ” ABAP Source
EXCEPTIONS
parameter_invalid = 1 ” Invalid parameter
source_not_found = 2
not_executed = 3
error_message = 4
OTHERS = 5.

lo_grid->set_visible( abap_true ).

ELSE.

MESSAGE i103(sb).

ENDIF.

ENDCASE.

ENDMETHOD.

ENDCLASS.

Feel free to try this tool and share any suggestions/insights if you have them 🙂

Conclusion

To sum up, this kind of Adobe Form XML comparisons are very clunky and impractical by nature.
Nevertheless, by doing it with such a program we can easily make such comparisons with much less effort.

Any questions/comments/suggestions?
Feel free to leave them down below.

For more resources related to Adobe Forms, feel free to:
– Follow the Adobe Form topic
– Post/answer/check questions related to Adobe Forms

Best regards,
Joaquim Perez

 

​ Hello everyone,In this blog I’ll present to you an alternative way to compare Adobe Form layout XML versions.IntroductionAs you may know, comparing Adobe Forms layout XML versions can be a time-consuming and cumbersome task.For simpler objects such as programs/includes/classes/etc we can always rely on the split-screen version comparison tool:However, it’s not quite simple when it comes to compare Adobe Form XML versions.You’d have to browse into each version and download its XML Source, and then compare it using an external editor / comparison tool:In order to facilitate/streamline that, I’ve built a tool that can do all that with more ease, very similar to what we can do with programs/includes/classes/etc.SolutionIn short, in this new program:You enter a form nameChoose the two versions you want to compare and press ‘Compare XML’Source code:*&———————————————————————*
*& Report YJPEREZ_AFORM_COMPARE_XML_VERS
*&———————————————————————*
*&
*&———————————————————————*
REPORT yjperez_aform_compare_xml_vers.

SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.

PARAMETERS: p_aform TYPE fpcontextt-name.

CLASS lcl_event_handler DEFINITION.

PUBLIC SECTION.

CLASS-METHODS
user_command FOR EVENT after_user_command OF cl_gui_alv_grid IMPORTING e_ucomm.
CLASS-METHODS
toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object.

PRIVATE SECTION.

CONSTANTS c_ucomm_compare_xml TYPE sy-ucomm VALUE ‘CMP_XML’.

ENDCLASS.

AT SELECTION-SCREEN OUTPUT.

DATA lt_excluded_sel_functions TYPE TABLE OF rsexfcode.
lt_excluded_sel_functions = VALUE #(
( fcode = ‘GET’ )
( fcode = ‘VSHO’ )
( fcode = ‘VDEL’ )
( fcode = ‘SPOS’ )
).

CALL FUNCTION ‘RS_SET_SELSCREEN_STATUS’
EXPORTING
p_status = sy-pfkey
TABLES
p_exclude = lt_excluded_sel_functions.

START-OF-SELECTION.

TRY.

DATA(lv_objtype_adobe_form) = CONV vrsd-objtype( ‘SFPF’ ).

DATA(lo_vers_alv) = NEW cl_vers_objtype_ui_alv(
iv_objname = |{ p_aform }|
iv_objtype = lv_objtype_adobe_form
).

lo_vers_alv->get_vrs_for_display(
IMPORTING
et_vrs_disp = DATA(lt_vers_data)
).

TYPES:
BEGIN OF ts_simple_vers_data,
status TYPE vrs_disp-status,
versno TYPE vrs_disp-versno,
versnum TYPE vrs_disp-versnum,
rel TYPE vrs_disp-rel,
korrno TYPE vrs_disp-korrno,
korrtext TYPE vrs_disp-korrtext,
project TYPE vrs_disp-project,
date TYPE vrs_disp-date,
time TYPE vrs_disp-time,
usr TYPE vrs_disp-usr,
END OF ts_simple_vers_data.

DATA lt_simple_vers_data TYPE TABLE OF ts_simple_vers_data.

DATA(lo_grid) = NEW cl_gui_alv_grid(
i_parent = cl_gui_container=>screen0
i_appl_events = abap_true
).

DATA(ls_grid_layout) = VALUE lvc_s_layo(
sel_mode = if_dmc_ui_view_list_builder=>co_selection_mode_multiple
).

DATA(lo_simple_vers_data_descr) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>describe_by_data(
p_data = lt_simple_vers_data
) ).

DATA(lo_simple_vers_data_line_descr) = CAST cl_abap_structdescr( lo_simple_vers_data_descr->get_table_line_type( ) ).

DATA(lt_field_cat) = VALUE lvc_t_fcat( ).

DATA(lt_components) = lo_simple_vers_data_line_descr->get_components( ).
LOOP AT lt_components INTO DATA(ls_component).

DATA(lo_elemdescr) = CAST cl_abap_elemdescr( ls_component-type ).
DATA(ls_ddic) = lo_elemdescr->get_ddic_field( ).

APPEND VALUE #(
fieldname = ls_component-name
scrtext_s = ls_ddic-scrtext_s
scrtext_m = ls_ddic-scrtext_m
scrtext_l = ls_ddic-scrtext_l
col_opt = abap_true
) TO lt_field_cat.

ENDLOOP.

lt_simple_vers_data = CORRESPONDING #( lt_vers_data ).

lo_grid->set_table_for_first_display(
EXPORTING
is_layout = ls_grid_layout
CHANGING
it_fieldcatalog = lt_field_cat
it_outtab = lt_simple_vers_data
).

SET HANDLER lcl_event_handler=>toolbar FOR lo_grid.
SET HANDLER lcl_event_handler=>user_command FOR lo_grid.

lo_grid->set_ready_for_input( 1 ).

CALL SELECTION-SCREEN 2000.

CATCH cx_root INTO DATA(lx_root).

MESSAGE lx_root->get_longtext( ) TYPE ‘I’.

ENDTRY.

CLASS lcl_event_handler IMPLEMENTATION.

METHOD toolbar.

CLEAR: e_object->mt_toolbar.

APPEND VALUE #(
butn_type = if_sat_ui_button_types=>normal
function = c_ucomm_compare_xml
icon = ‘@46@’
text = ‘Compare XML’
) TO e_object->mt_toolbar.

ENDMETHOD.

METHOD user_command.

CASE e_ucomm.

WHEN c_ucomm_compare_xml .

lo_grid->get_selected_rows(
IMPORTING
et_index_rows = DATA(lt_index_rows)
).

IF lines( lt_index_rows ) = 2.

DATA(ls_left_version) = lt_simple_vers_data[ lt_index_rows[ 1 ] ].
DATA(lo_left_form) = cl_fp_wb_helper=>form_create_from_version(
i_name = p_aform
i_version = CONV #( ls_left_version-versno )
).
DATA(lo_left_form_obj) = CAST cl_fp_form( lo_left_form->get_object( ) ).
DATA(lo_left_form_lay) = lo_left_form_obj->if_fp_form~get_layout( ).
DATA(lv_left_version_xstr) = lo_left_form_lay->get_layout_data( ).
DATA(lv_left_version_str) = cl_bcs_convert=>xstring_to_string(
iv_xstr = lv_left_version_xstr
iv_cp = cl_ehprc_c_gen_cp=>code_page_latin1
).

SPLIT lv_left_version_str AT cl_abap_char_utilities=>cr_lf INTO TABLE DATA(lt_left_version_str).

DATA(ls_right_version) = lt_simple_vers_data[ lt_index_rows[ 2 ] ].
DATA(lo_right_form) = cl_fp_wb_helper=>form_create_from_version(
i_name = p_aform
i_version = CONV #( ls_right_version-versno )
).
DATA(lo_right_form_obj) = CAST cl_fp_form( lo_right_form->get_object( ) ).
DATA(lo_right_form_lay) = lo_right_form_obj->if_fp_form~get_layout( ).
DATA(lv_right_version_xstr) = lo_right_form_lay->get_layout_data( ).
DATA(lv_right_version_str) = cl_bcs_convert=>xstring_to_string(
iv_xstr = lv_right_version_xstr
iv_cp = cl_ehprc_c_gen_cp=>code_page_latin1
).

SPLIT lv_right_version_str AT cl_abap_char_utilities=>cr_lf INTO TABLE DATA(lt_right_version_str).

lo_grid->set_visible( abap_false ).

DATA(ls_transport_key) = VALUE trkey(
obj_type = lv_objtype_adobe_form
obj_name = p_aform
sub_type = lv_objtype_adobe_form
sub_name = p_aform
).

DATA(lv_title_left) = |{ ls_left_version-versno } ({ ls_left_version-date DATE = ENVIRONMENT } { ls_left_version-time TIME = ENVIRONMENT })|.
DATA(lv_title_right) = |{ ls_right_version-versno } ({ ls_right_version-date DATE = ENVIRONMENT } { ls_right_version-time TIME = ENVIRONMENT })|.

DATA(lt_source_l) = CONV rswsourcet( lt_left_version_str ).
DATA(lt_source_r) = CONV rswsourcet( lt_right_version_str ).
CALL FUNCTION ‘WB_SPLIT_EDITOR_START’
EXPORTING
mode_left = swbm_c_op_display
mode_right = swbm_c_op_display
object_left = CONV syrepid( p_aform )
object_right = CONV syrepid( p_aform )
title_left = lv_title_left
title_right = lv_title_right
transport_key_l = ls_transport_key
TABLES
source_l = lt_source_l
source_r = lt_source_r ” ABAP Source
EXCEPTIONS
parameter_invalid = 1 ” Invalid parameter
source_not_found = 2
not_executed = 3
error_message = 4
OTHERS = 5.

lo_grid->set_visible( abap_true ).

ELSE.

MESSAGE i103(sb).

ENDIF.

ENDCASE.

ENDMETHOD.

ENDCLASS.Feel free to try this tool and share any suggestions/insights if you have them 🙂ConclusionTo sum up, this kind of Adobe Form XML comparisons are very clunky and impractical by nature.Nevertheless, by doing it with such a program we can easily make such comparisons with much less effort.Any questions/comments/suggestions?Feel free to leave them down below.For more resources related to Adobe Forms, feel free to:– Follow the Adobe Form topic– Post/answer/check questions related to Adobe FormsBest regards,Joaquim Perez   Read More Technology Blogs by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author