Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
perezjquim
Explorer
484

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:

perezjquim_1-1742420432702.png

perezjquim_2-1742420541664.png


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:

perezjquim_3-1742420855316.png


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:

  1. You enter a form name
  2. Choose the two versions you want to compare and press ‘Compare XML’

perezjquim_4-1742421096067.png

perezjquim_5-1742421151771.png

perezjquim_0-1742422567418.png

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

Labels in this area