Auf der Suche nach einer geeigneten Möglichkeit Smartform Formularversionen über die Systemgrenzen hinaus zu vergleichen, bin ich leider nirgends fündig geworden.
Der Bedarf an einem solchen Tools scheint mir jedoch sehr groß zu sein , deshalb .....
Der Smartformvergleicher besteht aus:
1.) einem RFC-fähigen Funktionsbaustein der eine Smartform Formular Definition als XML einliest und
via Tabellenparameter über die Schnittstelle bereitstellt. Dieser Funktionsbaustein sollte in alle verbundenen Systeme transportiert werden.
2.) Einem Report, welcher die Definitionen vergleicht (was einfacher klingt, als es ist.)
Wenn man genau wissen möchte was unterschiedlich ist, kann man die Ergebnistabelle (lt_xx) des Bausteins RS_CMP_COMPUTE_DELTA auf einem ALV ausgeben.
Die Differenzen sind gekennzeichnet (oder was er dafür hält) . Alle Tags eines Smartform formulars, welche generell unterschiedlich sind, wie FORMNAME LASTDATE ..
werden über ein Range Objekt abgefangen, da sonst jeder Vergleich zu Differenzen führen würde. (Also falls noch jemand etwas entdecken sollte...)
Mein Tipp wäre hier noch, die Liste ab der Differenz, Richtung Anfang zu gehen, bis zum Element INAME , das Element kann man dann in Smartforms suchen !

Der Vergleich reagiert auf Übersetzungen und funktioniert sogar mit nicht aktivierten Formularen.
Der Report kann im Entwicklungssystem bleiben, solange man nicht von den angeschlossenen Systemen aus vergleichen möchte.
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- *&---------------------------------------------------------------------*
- *& Report ZTEST_SF_COMP_ALV
- *&
- *&---------------------------------------------------------------------*
- *&
- *&
- *&---------------------------------------------------------------------*
- REPORT ztest_sf_comp_alv.
- line1 TYPE eddispline,
- line2 TYPE eddispline,
- text1 TYPE rsline,
- text2 TYPE rsline,
- flag1 TYPE sedflgdelt,
- flag2 TYPE sedflgdelt,
- iname1 TYPE rsline,
- iname2 TYPE rsline,
- END OF ty_output.
- * Grid Parameter
- g_container TYPE scrfname VALUE 'GRID1',
- grid1 TYPE REF TO cl_gui_alv_grid,
- g_custom_container TYPE REF TO cl_gui_custom_container,
- g_dock_container TYPE REF TO cl_gui_docking_container,
- is_variant TYPE disvariant.
- *--- Field catalog table
- *--- Layout structure
- * LT_EXCLUDE => Tabelle zum Ausschliessen von Funktionen innerhalb
- * der Toolbar des ALV-Grid
- ls_exclude TYPE ui_func.
- *---------------------------------------------------------------------*
- * CLASS lcl_event_handler DEFINITION
- *---------------------------------------------------------------------*
- *
- *---------------------------------------------------------------------*
- PUBLIC SECTION .
- *--To add new functional buttons to the ALV toolbar
- handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
- IMPORTING e_object e_interactive ,
- *--To implement user commands
- handle_user_command
- FOR EVENT user_command OF cl_gui_alv_grid
- IMPORTING e_ucomm .
- PRIVATE SECTION.
- *---------------------------------------------------------------------*
- * CLASS lcl_event_handler IMPLEMENTATION
- *---------------------------------------------------------------------*
- *
- *---------------------------------------------------------------------*
- *--Handle Toolbar
- METHOD handle_toolbar.
- *--Handle User Command
- METHOD handle_user_command .
- * Info Destinationen
- des2_info TYPE rfcsi.
- *DATA lv_mandt1(3).
- *DATA lv_mandt2(3).
- p_form1 TYPE tdsfname OBLIGATORY MATCHCODE OBJECT sh_stxfadm,
- p_form2 TYPE tdsfname OBLIGATORY MATCHCODE OBJECT sh_stxfadm.
- PERFORM check_avail.
- PERFORM fill_exclude_range.
- PERFORM compare_sf.
- *&---------------------------------------------------------------------*
- *& Form Check_avail
- *&---------------------------------------------------------------------*
- * text
- *----------------------------------------------------------------------*
- * -->DEST text
- *----------------------------------------------------------------------*
- FORM check_avail.
- DATA:
- " info LIKE rfcsi,
- msg_text(80) TYPE c. "Message text
- CALL FUNCTION 'RFC_SYSTEM_INFO'
- DESTINATION p_des1
- IMPORTING
- rfcsi_export = des1_info
- EXCEPTIONS
- CALL FUNCTION 'RFC_SYSTEM_INFO'
- DESTINATION p_des2
- IMPORTING
- rfcsi_export = des2_info
- EXCEPTIONS
- *&---------------------------------------------------------------------*
- *& Form write_for_display
- *&---------------------------------------------------------------------*
- * text
- *----------------------------------------------------------------------*
- FORM write_for_display.
- msg_text(80) TYPE c. "Message text
- CLEAR msg_text.
- CALL FUNCTION 'RFC_PING'
- DESTINATION p_des2
- EXCEPTIONS
- t1 = p_des2.
- CONDENSE t1.
- t2 COLOR COL_POSITIVE.
- ELSE.
- t2 COLOR COL_NEGATIVE.
- CLEAR msg_text.
- CALL FUNCTION 'RFC_PING'
- DESTINATION p_des1
- EXCEPTIONS
- t1 = p_des1.
- CONDENSE t1.
- t2 COLOR COL_POSITIVE.
- ELSE.
- t2 COLOR COL_NEGATIVE.
- AT SELECTION-SCREEN.
- * Teste Erreichbarkeit
- PERFORM write_for_display.
- CALL FUNCTION 'C14A_POPUP_LIST_DISPLAY'
- EXPORTING
- i_callback = 'WRITE_FOR_DISPLAY'
- i_callback_program = sy-repid
- i_title = 'RFC-connections'
- i_col = 4
- i_row = 4
- i_width = 84
- i_height = 10
- * I_TEXT_WIDTH =
- * I_FLG_SHOW_PRINT_BUTTON = ESP1_FALSE
- EXCEPTIONS
- no_callback_specified = 1
- OTHERS = 2.
- WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
- sscrfields-functxt_01 = '@FC@ Check RFC-Destinations'(003).
- FORM compare_sf.
- CALL FUNCTION 'Z_BC_READSFXML' DESTINATION p_des1
- EXPORTING
- i_form = p_form1
- i_langu = ' '
- sftab = t_sftab1
- * RETURN =
- EXCEPTIONS
- form_not_exist = 1
- wrong_access_to_archive = 2
- OTHERS = 5.
- CALL FUNCTION 'Z_BC_READSFXML' DESTINATION p_des2
- EXPORTING
- i_form = p_form2
- i_langu = ' '
- sftab = t_sftab2
- * RETURN =
- EXCEPTIONS
- form_not_exist = 1
- wrong_access_to_archive = 2
- OTHERS = 5.
- CALL FUNCTION 'RS_CMP_COMPUTE_DELTA'
- EXPORTING
- * COMPARE_MODE = '1'
- * FLG_EXT_IGNORE = ' '
- ignore_case_differences = ' '
- * FLG_WB99 = ' '
- IMPORTING
- flg_equal = lv_equal
- text_tab1 = lt_t2
- text_tab2 = lt_t1
- text_tab_res = lt_xx
- EXCEPTIONS
- parameter_invalid = 1
- difference_not_found = 2
- OTHERS = 3.
- *----------------------------------------------------------
- lv_lastname1 = ls_data-text1+6.
- ls_data-iname1 = lv_lastname1.
- *----------------------------------------------------------
- lv_lastname2 = ls_data-text2+6.
- ls_data-iname2 = lv_lastname2.
- *----------------------------------------------------------
- CALL SCREEN 100.
- ELSE.
- FORM fill_exclude_range.
- CLEAR gr_excl .
- gr_excl-sign = 'E'.
- gr_excl-option = 'EQ'.
- * gr_excl-low = 'item'. APPEND gr_excl.
- *&---------------------------------------------------------------------*
- *& Module PBO OUTPUT
- *&---------------------------------------------------------------------*
- * text
- *----------------------------------------------------------------------*
- MODULE pbo OUTPUT.
- CREATE OBJECT g_custom_container
- EXPORTING
- container_name = g_container.
- CREATE OBJECT grid1
- EXPORTING
- i_parent = g_custom_container.
- ELSE.
- * Hintergrund
- CREATE OBJECT grid1
- EXPORTING
- i_parent = g_dock_container.
- * CREATE OBJECT g_custom_container
- * EXPORTING
- * container_name = g_container.
- *
- * CREATE OBJECT grid1
- * EXPORTING
- * i_parent = g_custom_container.
- *--Creating an instance for the event handler
- CREATE OBJECT gr_event_handler .
- *----Preparing field catalog.
- *----Preparing layout structure
- *----Preparing Disable Toolbar Buttons
- PERFORM change_buttons .
- is_variant-variant = '/GLOB_DEF'.
- ELSE.
- is_variant-variant = '/GLOB_JOB'.
- *'X': nur globales Speichern
- *'U': nur benutzerspezifisches Speichern
- *'A': entspricht 'X' und 'U'
- *SPACE:kein Speichern
- CALL METHOD grid1->set_table_for_first_display
- EXPORTING
- is_variant = is_variant
- i_save = 'X'
- is_layout = gs_layout
- it_toolbar_excluding = lt_exclude
- CHANGING
- it_outtab = it_data[]
- it_fieldcatalog = gt_fieldcat[].
- *--Registering handler methods to handle ALV Grid events JG
- SET HANDLER gr_event_handler->handle_toolbar FOR grid1.
- SET HANDLER gr_event_handler->handle_user_command FOR grid1.
- CALL METHOD grid1->set_toolbar_interactive.
- * Der GRID1 wird noch refreshed
- CALL METHOD grid1->refresh_table_display.
- SET PF-STATUS 'MAIN100'.
- SET TITLEBAR 'AUSW' WITH gv_title.
- *&---------------------------------------------------------------------*
- *& Module PAI INPUT
- *&---------------------------------------------------------------------*
- * text
- *----------------------------------------------------------------------*
- * to react on oi_custom_events:
- CALL METHOD cl_gui_cfw=>dispatch.
- CASE ok_code.
- PERFORM exit_program.
- * do nothing
- CLEAR ok_code.
- *---------------------------------------------------------------------*
- * FORM EXIT_PROGRAM *
- *---------------------------------------------------------------------*
- FORM exit_program.
- * CALL METHOD G_CUSTOM_CONTAINER->FREE.
- * CALL METHOD CL_GUI_CFW=>FLUSH.
- *&--------------------------------------------------------------------*
- *& Form Change_buttons
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- FORM change_buttons .
- * Kein Symbol für Drucken / Graphik / Info
- ls_exclude = cl_gui_alv_grid=>mc_fc_print_back.
- ls_exclude = cl_gui_alv_grid=>mc_fc_graph.
- ls_exclude = cl_gui_alv_grid=>mc_fc_info.
- *&--------------------------------------------------------------------*
- *& Form handle_toolbar
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- * -->I_OBJECT text
- *---------------------------------------------------------------------*
- e_interactive .
- * Paltzhalter / Seperator
- CLEAR ls_toolbar.
- ** Button Show Differences
- CLEAR ls_toolbar.
- ** Button Delete Filter Differences
- CLEAR ls_toolbar.
- ** Paltzhalter / Seperator
- * CLEAR ls_toolbar.
- * MOVE 3 TO ls_toolbar-butn_type.
- * APPEND ls_toolbar TO i_object->mt_toolbar.
- *&---------------------------------------------------------------------*
- *& Form handle_user_command
- *&---------------------------------------------------------------------*
- * text
- *----------------------------------------------------------------------*
- CASE i_ucomm .
- ls_filter-fieldname = 'FLAG1'. "Field Name
- ls_filter-sign = 'I'.
- ls_filter-option = 'NE'.
- ls_filter-low = ' '. "Filter Value
- ls_filter-fieldname = 'FLAG2'. "Field Name
- ls_filter-sign = 'I'.
- ls_filter-option = 'NE'.
- ls_filter-low = ' '. "Filter Value
- CALL METHOD grid1->set_filter_criteria
- EXPORTING
- it_filter = lt_filter.
- CALL METHOD grid1->get_filter_criteria
- IMPORTING
- et_filter = lt_filter.
- CALL METHOD grid1->set_filter_criteria
- EXPORTING
- it_filter = lt_filter.
- ENDCASE .
- lv_stable-row = 'X'.
- CALL METHOD grid1->refresh_table_display
- EXPORTING
- is_stable = lv_stable.
- * EXCEPTIONS
- * finished = 1
- * OTHERS = 2.
- *&--------------------------------------------------------------------*
- *& Form prepare_field_catalog
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- * -->PT_FIELDCATtext
- *---------------------------------------------------------------------*
- * DATA ls_fcat TYPE lvc_s_fcat .
- * DATA lv_depth TYPE i.
- l_struc = indx_id .
- CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
- EXPORTING
- i_structure_name = l_struc
- CHANGING
- ct_fieldcat = pt_fieldcat[]
- EXCEPTIONS
- inconsistent_interface = 1
- program_error = 2
- OTHERS = 3.
- *--Exception handling
- READ TABLE pt_fieldcat INTO ls_fieldcat WITH KEY fieldname = 'TEXT1'.
- ls_fieldcat-col_pos = 7.
- ls_fieldcat-fieldname = 'INAME1'.
- ls_fieldcat-ref_table = space.
- ls_fieldcat-tabname = space.
- ls_fieldcat-col_pos = 8.
- ls_fieldcat-fieldname = 'INAME2'.
- <p>-scrtext_l = 'Element A'.
- <p>-scrtext_m = 'Elem.A'.
- <p>-scrtext_s = 'EA'.
- <p>-scrtext_l = 'Element B'.
- <p>-scrtext_m = 'Elem.B'.
- <p>-scrtext_s = 'EB'.
- <p>-scrtext_l = 'Line A'.
- <p>-scrtext_m = 'Line A'.
- <p>-scrtext_s = 'LA'.
- <p>-scrtext_l = 'Line B'.
- <p>-scrtext_m = 'Line B'.
- <p>-scrtext_s = 'LB'.
- <p>-scrtext_l = 'Source A'.
- <p>-scrtext_m = 'Src A'.
- <p>-scrtext_s = 'A'.
- <p>-scrtext_l = 'Source B'.
- <p>-scrtext_m = 'Src B'.
- <p>-scrtext_s = 'B'.
- <p>-scrtext_l = 'Change A'.
- <p>-scrtext_m = 'C-Flg A'.
- <p>-scrtext_s = 'A'.
- <p>-scrtext_l = 'Change B'.
- <p>-scrtext_m = 'C-Flg B'.
- <p>-scrtext_s = 'B'.
- *&--------------------------------------------------------------------*
- *& Form prepare_layout
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- * -->PS_LAYOUT text
- *---------------------------------------------------------------------*
- ps_layout-zebra = 'X' .
- ps_layout-numc_total = ' '.
- ps_layout-no_merging = 'X'.
- ps_layout-no_rowmark = ' '.
- ps_layout-sel_mode = 'A'.
- GeSHi ©
Der benötigte RFC-Enabled Funktionsbaustein.
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- FUNCTION Z_BC_READSFXML.
- *"----------------------------------------------------------------------
- *"*"Local Interface:
- *" IMPORTING
- *" VALUE(I_FORM) TYPE TDSFNAME
- *" VALUE(I_LANGU) TYPE SPRAS DEFAULT 'E'
- *" TABLES
- *" SFTAB STRUCTURE SMUM_XMLTB
- *" RETURN STRUCTURE BAPIRET2 OPTIONAL
- *" EXCEPTIONS
- *" FORM_NOT_EXIST
- *"----------------------------------------------------------------------
- VALUE 'urn:sap-com:SmartForms:2000:internal-structure', "#EC NOTEXT
- c_xml_ns_uri_ifr(255) TYPE c
- VALUE 'urn:sap-com:sdixml-ifr:2000'. "#EC NOTEXT
- t_gnodes TYPE tsfgnode.
- l_file_filter TYPE string,
- l_user_action TYPE i.
- l_language(2) TYPE c.
- l_splitted_name_tab TYPE TABLE OF string.
- l_stylevari TYPE tdvariant,
- l_save_style TYPE tdssname.
- xml_document TYPE REF TO if_ixml_document,
- xml_element TYPE REF TO if_ixml_element,
- xml_ns_prefix_sf TYPE string,
- xml_ns_uri_sf TYPE string,
- xml_ns_uri_ifr TYPE string,
- xml_macro_name TYPE string,
- xml_macro_rc TYPE i,
- xml_macro_objt TYPE stxfobjt,
- xml_macro_text TYPE stxftxt,
- xml_macro_tline TYPE tline,
- xml_upload_language TYPE tdspras.
- xml_document_size TYPE i.
- * Namen der aktuell bearbeiteten Objekte
- variant TYPE tdvariant, " Name der Formularvariante
- language TYPE sy-langu, " Bearbeitungssprache
- fmnumb TYPE tdfmnumb, " Nummer des zugeordneten Fb
- fmnumb_test TYPE tdfmnumb. " Fb zum Test der inaktiven Fassung
- gv_size TYPE sy-tabix.
- RAISE form_not_exist.
- ELSE.
- formname = i_form.
- language = ls_admin-masterlang.
- ELSE.
- language = i_langu.
- * create form object
- CREATE OBJECT sform.
- CALL METHOD sform->load
- EXPORTING
- im_formname = formname
- im_language = language
- im_active = space
- IMPORTING
- ex_fmnumb = fmnumb
- ex_fmnumb_test = fmnumb_test.
- g_ixml = cl_ixml=>create( ).
- xml_document = g_ixml->create_document( ).
- xml_ns_prefix_sf = 'sf'.
- xml_ns_uri_sf = c_xml_ns_uri_sf.
- xml_ns_uri_ifr = c_xml_ns_uri_ifr.
- sform->xml_init( ).
- * create XML for the entire smart form
- CALL METHOD sform->xml_download
- EXPORTING
- parent = xml_document
- CHANGING
- document = xml_document.
- * namespace
- l_element = xml_document->get_root_element( ).
- l_element->set_attribute( name = xml_ns_prefix_sf
- namespace = 'xmlns'
- value = xml_ns_uri_sf ).
- l_element->set_attribute( name = 'xmlns'
- value = xml_ns_uri_ifr ).
- * language
- l_language_str = l_language.
- xml_macro_rc = l_element->set_attribute(
- name = 'language'
- namespace = xml_ns_prefix_sf
- value = l_language_str ).
- CALL FUNCTION 'SDIXML_DOM_TO_XML'
- EXPORTING
- document = xml_document
- * PRETTY_PRINT = ' '
- IMPORTING
- xml_as_string = gv_xml_xstring
- size = gv_size
- EXCEPTIONS
- no_document = 1
- OTHERS = 2.
- *== Convert XML to itab
- CALL FUNCTION 'SMUM_XML_PARSE'
- EXPORTING
- xml_input = gv_xml_xstring
- xml_table = sftab
- GeSHi ©