Skip to Content

Introduction

From time to time, the need to compare validation (transaction GGB0) & substitution (transaction GGB1) between two systems (usually development and quality or development and production), or between two client arises. This task is usually done manually, comparing step to step visually between two systems or clients. This is a slow and error prone task.
I was looking for some tool to automate this comparison task, but no succeed.
I propose here a validation & substitution comparison tool which is presented in this article. The advantage of using this tool is obvious: It is fast, and error free.

Result presentation

The presentation is done with an ALV, where the left part is the local system, and the right side is the remote system. In the middle of the ALV, icons are presented. The meaning of these icons is:

The entry is found in both systems, but the content is different.

The entry has been found in the local system, but not in the remote system.

The entry has been found in the remote system, but not in the local system.

Note that only the differences are presented. Equal rows are ommited.

Screenshots

Comparison of Validation prerequisites

Selection screen:

The user has to select the proper RFC destination and “Validation prerequisite” radio button.
Once executed, the system shows the remote login screen. The user has to log in. The program shows the result:

Comparison of Validation checks

Selection screen:

The user has to select the proper RFC destination and the “Validation Checks” radio button.
Once executed, the system shows the remote login screen. The user has to log in. The program shows the result:

Comparison of Substitution prerequisites

Selection screen:

The user has to select the proper RFC destination and the “Substitution Prerequisite” radio button.
Once executed, the system shows the remote login screen. The user has to log in. The program shows the result:

Comparison of Substitutions

Selection screen:

The user has to select the proper RFC destination and the “Substitutuin Substitution” radio button.
Once executed, the system shows the remote login screen. The user has to log in. The program shows the result:

Client comparison

To compare between clients, select a RFC destination which points to the same machine. At logon inform the client.

Code

*&---------------------------------------------------------------------*
*& Report  ZCOMPARE_VALIDATION_SUBST
*& Author: Jordi Escoda, April 2017. 
*& Coded in local classes: March 2018
*& Description: This program allows to compare the validation and
*& substitution steps between two systems or between clients of the
*& same system.
*& The result is presented in an ALV, where the left part is the local
*& system data, and the right part is the remote system data. In the
*& middle an icon is shown.
*& There are three types of record:
*&  -Different data between systems
*&  -Content which is present in the local system, but not in the
*&   remote system
*&  -Content which is present in the remote system, but not in the
*&   local system
*&
*& Related transactions:
*&  GGB0 (Validations)
*&  GGB1 (Substitutions)
*&---------------------------------------------------------------------*
*& Selection screen texts
*& P_RFC  RFC Destination
*& P_SCOND  Substitution. Prerequisite
*& P_SSUBS  Substitución. Substitution
*& P_VCHK	Validación. Check
*& P_VCOND  Validation. Prerequisite
*& SO_SUBST	Substitution
*& SO_VALID	Validation
*&
*& Text symbols
*& 001  Parameters
*& 002  Comparison
*&---------------------------------------------------------------------*
REPORT zutil_compare_validation_subst.

*--------------------------------------------------------------------*
* Tables and Types
*--------------------------------------------------------------------*
TABLES: gb921,
        gb931.

TYPE-POOLS: abap,
            icon.

*--------------------------------------------------------------------*
* SELECTION SCREEN
*--------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS: p_rfc TYPE rfcdes-rfcdest.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-002.
PARAMETERS: p_vcond RADIOBUTTON GROUP rb1 "Validation: Conditions
                                 USER-COMMAND rb,
            p_vchk  RADIOBUTTON GROUP rb1, "Validation: Checks
            p_scond RADIOBUTTON GROUP rb1, "Substitution: Conditions
            p_ssubs RADIOBUTTON GROUP rb1. "Substitution: Substitution
SELECT-OPTIONS: so_subst FOR gb921-substid.
SELECT-OPTIONS: so_valid FOR gb931-valid.
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN END OF BLOCK b1.

*----------------------------------------------------------------------*
*       CLASS lcl_valid_susbt DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_valid_susbt DEFINITION FINAL.
  PUBLIC SECTION.
    CLASS-METHODS:
      execute.

  PRIVATE SECTION.
    TYPES: BEGIN OF ty_subst_cond,
      substid TYPE gb921-substid,
      subseqnr TYPE gb921-subseqnr,
      substext TYPE gb921t-substext,
      seqnr TYPE gb901-seqnr,
      boolexp TYPE gb901-boolexp,
    END OF ty_subst_cond.
    TYPES: BEGIN OF ty_subst_sust,
      substid TYPE gb921-substid,
      subseqnr TYPE gb921-subseqnr,
      substext TYPE gb921t-substext,
      conseqnr TYPE gb922-conseqnr,
      substab TYPE gb922-substab,
      subsfield TYPE gb922-subsfield,
      subsval TYPE gb922-subsval,
      manipexp TYPE gb922-manipexp,
      exitsubst TYPE gb922-exitsubst,
      tabsubst TYPE gb922-tabsubst,
      filedsub TYPE gb922-filedsub,
    END OF ty_subst_sust.
    TYPES: BEGIN OF ty_subst_cond_out,
      local TYPE ty_subst_cond,
      icon TYPE iconname,
      remoto TYPE ty_subst_cond,
    END OF ty_subst_cond_out.
    TYPES: BEGIN OF ty_subst_sust_out,
      local TYPE ty_subst_sust,
      icon TYPE iconname,
      remoto TYPE ty_subst_sust,
    END OF ty_subst_sust_out.
    TYPES: BEGIN OF ty_valid_cond,
      valid TYPE gb931-valid,
      valseqnr TYPE gb931-valseqnr,
      booltext TYPE gb90t-booltext,
      seqnr TYPE gb901-seqnr,
      boolexp TYPE gb901-boolexp,
    END OF ty_valid_cond.
    TYPES: BEGIN OF valid_cond_out_type,
      local TYPE ty_valid_cond,
      icon TYPE iconname,
      remoto TYPE ty_valid_cond,
    END OF valid_cond_out_type.
    TYPES: BEGIN OF ty_valid_chk,
      valid TYPE gb931-valid,
      valseqnr TYPE gb931-valseqnr,
      booltext TYPE gb90t-booltext,
      valsevere TYPE gb931-valsevere,
      valmsg TYPE gb931-valmsg,
      msgtab1 TYPE gb931-msgtab1,
      msgfield1 TYPE gb931-msgfield1,
      msgtab2 TYPE gb931-msgtab2,
      msgfield2 TYPE gb931-msgfield2,
      msgtab3 TYPE gb931-msgtab3,
      msgfield3 TYPE gb931-msgfield3,
      msgtab4 TYPE gb931-msgtab4,
      msgfield4 TYPE gb931-msgfield4,
      workflow TYPE gb931-workflow,
    END OF ty_valid_chk.
    TYPES: BEGIN OF ty_valid_chk_out,
      local TYPE ty_valid_chk,
      icon TYPE iconname,
      remoto TYPE ty_valid_chk,
    END OF ty_valid_chk_out.
    TYPES: ty_t_gb901 TYPE STANDARD TABLE OF gb901 WITH DEFAULT KEY.
    TYPES: ty_t_gb90t TYPE STANDARD TABLE OF gb90t WITH DEFAULT KEY.
    TYPES: ty_t_gb931 TYPE STANDARD TABLE OF gb931 WITH DEFAULT KEY.
    TYPES: ty_t_gb921 TYPE STANDARD TABLE OF gb921 WITH DEFAULT KEY.
    TYPES: ty_t_gb921t TYPE STANDARD TABLE OF gb921t WITH DEFAULT KEY.
    TYPES: ty_t_gb922 TYPE STANDARD TABLE OF gb922 WITH DEFAULT KEY.
    TYPES: ty_t_valid_cond TYPE STANDARD TABLE OF ty_valid_cond WITH DEFAULT KEY.
    TYPES: ty_t_valid_chk TYPE STANDARD TABLE OF ty_valid_chk WITH DEFAULT KEY.
    TYPES: ty_t_subst_cond TYPE STANDARD TABLE OF ty_subst_cond WITH DEFAULT KEY.
    TYPES: ty_t_subst_subst TYPE STANDARD TABLE OF ty_subst_sust WITH DEFAULT KEY.

    CLASS-DATA:
*         Boolean formula
          attr_t_gb901_rfc TYPE STANDARD TABLE OF gb901,
          attr_t_gb901 TYPE STANDARD TABLE OF gb901,
*         Boolean formula texts
          attr_t_gb90t_rfc TYPE STANDARD TABLE OF gb90t,
          attr_t_gb90t TYPE STANDARD TABLE OF gb90t,
*         Substitution conditions
          attr_t_gb921_rfc TYPE STANDARD TABLE OF gb921,
          attr_t_gb921 TYPE STANDARD TABLE OF gb921,
*         Substitution step texts
          attr_t_gb921t_rfc TYPE STANDARD TABLE OF gb921t,
          attr_t_gb921t TYPE STANDARD TABLE OF gb921t,
*         Substitution constants
          attr_t_gb922_rfc TYPE STANDARD TABLE OF gb922,
          attr_t_gb922 TYPE STANDARD TABLE OF gb922,
*         Table to process substitution conditions
          attr_t_subst_cond_rfc TYPE STANDARD TABLE OF ty_subst_cond,
          attr_t_subst_cond TYPE STANDARD TABLE OF ty_subst_cond,
*         Table to process substitutions
          attr_t_subst_subst_rfc TYPE STANDARD TABLE OF ty_subst_sust,
          attr_t_subst_subst TYPE STANDARD TABLE OF ty_subst_sust,
*         Output table for substitutions conditions
          attr_t_subst_cond_out TYPE STANDARD TABLE OF ty_subst_cond_out,
*         Output table for substitutions
          attr_t_subst_sust_out TYPE STANDARD TABLE OF ty_subst_sust_out,
*         Validation operations
          attr_t_gb931_rfc TYPE STANDARD TABLE OF gb931,
          attr_t_gb931 TYPE STANDARD TABLE OF gb931,
*         Tables to process validation conditions
          attr_t_valid_cond_rfc TYPE STANDARD TABLE OF ty_valid_cond,
          gt_valid_cond TYPE STANDARD TABLE OF ty_valid_cond,
*         Tables to proces validation checks
          attr_t_valid_chk_rfc TYPE STANDARD TABLE OF ty_valid_chk,
          attr_t_valid_chk TYPE STANDARD TABLE OF ty_valid_chk,
*         Output table for validation conditions
          attr_t_valid_cond_out TYPE STANDARD TABLE OF valid_cond_out_type,
*         Output table for validation checks
          attr_t_valid_chk_out TYPE STANDARD TABLE OF ty_valid_chk_out.

    CLASS-METHODS:
      execute_subst_conditions,
      execute_subst_substitutions,
      execute_valid_conditions,
      execute_valid_check,
      load_validation_tables,
      load_substitution_tables,
      load_table_rfc
        IMPORTING im_tablename TYPE tabname
        RETURNING value(re_table) TYPE REF TO data,
      load_table_local
        IMPORTING im_tablename TYPE tabname
        RETURNING value(re_table) TYPE REF TO data,
      fill_valid_cond
        IMPORTING im_gb901 TYPE ty_t_gb901
                  im_gb90t TYPE ty_t_gb90t
                  im_gb931 TYPE ty_t_gb931
        RETURNING value(re_valid_cond) TYPE ty_t_valid_cond,
      fill_valid_chk
        IMPORTING im_gb901 TYPE ty_t_gb901
                  im_gb90t TYPE ty_t_gb90t
                  im_gb931 TYPE ty_t_gb931
        RETURNING value(re_valid_chk) TYPE ty_t_valid_chk,
      fill_subst_cond
        IMPORTING im_gb921 TYPE ty_t_gb921
                  im_gb921t TYPE ty_t_gb921t
                  im_gb901 TYPE ty_t_gb901
        RETURNING value(re_subst_cond) TYPE ty_t_subst_cond,
      fill_subst_subst
        IMPORTING im_gb921 TYPE ty_t_gb921
                  im_gb921t TYPE ty_t_gb921t
                  im_gb922 TYPE ty_t_gb922
        RETURNING value(re_subst_subst) TYPE ty_t_subst_subst,
      compare_valid_cond,
      compare_valid_chk,
      compare_subst_cond,
      compare_subst_subst,
      show_alv
       IMPORTING im_table TYPE REF TO data,
      set_alv_columns
       IMPORTING im_salv_table TYPE REF TO cl_salv_table,
      set_alv_functions
       IMPORTING im_salv_table TYPE REF TO cl_salv_table.

ENDCLASS.                    "lcl_valid_susbt DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_valid_susbt IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_valid_susbt IMPLEMENTATION.
  METHOD execute.
    CASE abap_true.
      WHEN p_scond.
        execute_subst_conditions( ).
      WHEN p_ssubs.
        execute_subst_substitutions( ).
      WHEN p_vcond.
        execute_valid_conditions( ).
      WHEN p_vchk.
        execute_valid_check( ).
    ENDCASE.
  ENDMETHOD.                    "execute

  METHOD execute_subst_conditions.
    DATA: lr_dref TYPE REF TO data.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    DATA: ls_subst_cond_out TYPE ty_subst_cond_out.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    load_substitution_tables( ).

    attr_t_subst_cond_rfc = fill_subst_cond( im_gb921 = attr_t_gb921_rfc
                                         im_gb921t = attr_t_gb921t_rfc
                                         im_gb901 = attr_t_gb901_rfc ).
    SORT attr_t_subst_cond_rfc BY substid subseqnr seqnr.

    attr_t_subst_cond = fill_subst_cond( im_gb921 = attr_t_gb921
                                         im_gb921t = attr_t_gb921t
                                         im_gb901 = attr_t_gb901 ).
    SORT attr_t_subst_cond BY substid subseqnr seqnr.

    compare_subst_cond( ).

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_data( ls_subst_cond_out ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA lr_dref TYPE HANDLE lo_abap_tabledescr.
    ASSIGN lr_dref->* TO <lt_table>.
    <lt_table> = attr_t_subst_cond_out.
    show_alv( lr_dref ).
  ENDMETHOD.                    "execute_subst_conditions

  METHOD execute_subst_substitutions.
    DATA: lr_dref TYPE REF TO data.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    DATA: ls_subst_subst_out TYPE ty_subst_sust_out.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    load_substitution_tables( ).

    attr_t_subst_subst_rfc = fill_subst_subst( im_gb921 = attr_t_gb921_rfc
                                         im_gb921t = attr_t_gb921t_rfc
                                         im_gb922 = attr_t_gb922_rfc ).
    SORT attr_t_subst_subst_rfc BY substid subseqnr.

    attr_t_subst_subst = fill_subst_subst( im_gb921 = attr_t_gb921
                                      im_gb921t = attr_t_gb921t
                                      im_gb922 = attr_t_gb922 ).
    SORT attr_t_subst_subst BY substid subseqnr.

    compare_subst_subst( ).

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_data( ls_subst_subst_out ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA lr_dref TYPE HANDLE lo_abap_tabledescr.
    ASSIGN lr_dref->* TO <lt_table>.
    <lt_table> = attr_t_subst_sust_out.
    show_alv( lr_dref ).
  ENDMETHOD.                    "execute_subst_substitutions

  METHOD execute_valid_conditions.
    DATA: lr_dref TYPE REF TO data.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    DATA: ls_valid_cond_out TYPE valid_cond_out_type.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    load_validation_tables( ).

    attr_t_valid_cond_rfc = fill_valid_cond( im_gb901 = attr_t_gb901_rfc
                                         im_gb90t = attr_t_gb90t_rfc
                                         im_gb931 = attr_t_gb931_rfc ).
    SORT attr_t_valid_cond_rfc BY valid valseqnr seqnr.

    gt_valid_cond = fill_valid_cond( im_gb901 = attr_t_gb901
                                     im_gb90t = attr_t_gb90t
                                     im_gb931 = attr_t_gb931 ).
    SORT gt_valid_cond BY valid valseqnr seqnr.

    compare_valid_cond( ).

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_data( ls_valid_cond_out ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA lr_dref TYPE HANDLE lo_abap_tabledescr.
    ASSIGN lr_dref->* TO <lt_table>.
    <lt_table> = attr_t_valid_cond_out.
    show_alv( lr_dref ).
  ENDMETHOD.                    "execute_subst_substitutions

  METHOD execute_valid_check.
    DATA: lr_dref TYPE REF TO data.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    DATA: ls_valid_chk_out TYPE ty_valid_chk_out.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    load_validation_tables( ).

    attr_t_valid_chk_rfc = fill_valid_chk( im_gb901 = attr_t_gb901_rfc
                                       im_gb90t = attr_t_gb90t_rfc
                                       im_gb931 = attr_t_gb931_rfc ).
    SORT attr_t_valid_chk_rfc BY valid valseqnr.

    attr_t_valid_chk = fill_valid_chk( im_gb901 = attr_t_gb901
                                   im_gb90t = attr_t_gb90t
                                   im_gb931 = attr_t_gb931 ).
    SORT attr_t_valid_chk BY valid valseqnr.

    compare_valid_chk( ).

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_data( ls_valid_chk_out ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA lr_dref TYPE HANDLE lo_abap_tabledescr.
    ASSIGN lr_dref->* TO <lt_table>.
    <lt_table> = attr_t_valid_chk_out.
    show_alv( lr_dref ).

  ENDMETHOD.                    "execute_subst_substitutions

  METHOD load_validation_tables.
    DATA: lr_dref TYPE REF TO data.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = 'Loading rfc tables...'.

    lr_dref = load_table_rfc( 'GB901' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb901_rfc = <lt_table>.

    lr_dref = load_table_rfc( 'GB90T' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb90t_rfc = <lt_table>.
*   Leave only current language
    DELETE attr_t_gb90t_rfc WHERE langu <> sy-langu.

    lr_dref = load_table_rfc( 'GB931' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb931_rfc = <lt_table>.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = 'Loading local tables...'.

    lr_dref = load_table_local( 'GB901' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb901 = <lt_table>.

    lr_dref = load_table_local( 'GB90T' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb90t = <lt_table>.
*   Leave only current language
    DELETE attr_t_gb90t WHERE langu <> sy-langu.

    lr_dref = load_table_local( 'GB931' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb931 = <lt_table>.

  ENDMETHOD.                    "load_validation_tables

  METHOD load_substitution_tables.
    DATA: lr_dref TYPE REF TO data.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = 'Loading rfc tables...'.

    lr_dref = load_table_rfc( 'GB901' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb901_rfc = <lt_table>.

    lr_dref = load_table_rfc( 'GB921' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb921_rfc = <lt_table>.

    lr_dref = load_table_rfc( 'GB922' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb922_rfc = <lt_table>.

    lr_dref = load_table_rfc( 'GB921T' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb921t_rfc = <lt_table>.
*   Leave only current language
    DELETE attr_t_gb921t_rfc WHERE langu <> sy-langu.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = 'Loading local tables...'.

    lr_dref = load_table_local( 'GB901' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb901 = <lt_table>.

    lr_dref = load_table_local( 'GB921' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb921 = <lt_table>.

    lr_dref = load_table_local( 'GB922' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb922 = <lt_table>.

    lr_dref = load_table_local( 'GB921T' ).
    ASSIGN lr_dref->* TO <lt_table>.
    attr_t_gb921t = <lt_table>.
*   Leave only current language
    DELETE attr_t_gb921t WHERE langu <> sy-langu.

  ENDMETHOD.                    "load_substitution_tables

  METHOD fill_valid_cond.
    DATA: ls_gb931 TYPE gb931,
          ls_gb901 TYPE gb901,
          ls_gb90t TYPE gb90t,
          ls_valid TYPE ty_valid_cond.

    LOOP AT im_gb931 INTO ls_gb931
                            WHERE valid IN so_valid.
      CLEAR ls_valid.
      MOVE-CORRESPONDING ls_gb931 TO ls_valid.
      READ TABLE im_gb90t WITH KEY boolid = ls_gb931-condid
                             INTO ls_gb90t.
      IF sy-subrc = 0.
        ls_valid-booltext = ls_gb90t-booltext.
      ENDIF.
      LOOP AT im_gb901 INTO ls_gb901
                         WHERE boolid = ls_gb931-condid.
        MOVE-CORRESPONDING ls_gb901 TO ls_valid.
        APPEND ls_valid TO re_valid_cond.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.                    "fill_valid_cond

  METHOD fill_valid_chk.
    DATA: ls_gb931 TYPE gb931,
          ls_gb901 TYPE gb901,
          ls_gb90t TYPE gb90t,
          ls_valid TYPE ty_valid_chk.

    LOOP AT im_gb931 INTO ls_gb931
                     WHERE valid IN so_valid.
      CLEAR ls_valid.
      MOVE-CORRESPONDING ls_gb931 TO ls_valid.
      READ TABLE im_gb90t WITH KEY boolid = ls_gb931-condid
                              INTO ls_gb90t.
      IF sy-subrc = 0.
        ls_valid-booltext = ls_gb90t-booltext.
      ENDIF.
      LOOP AT im_gb901 INTO ls_gb901
                       WHERE boolid = ls_gb931-checkid.
        MOVE-CORRESPONDING ls_gb901 TO ls_valid.
        APPEND ls_valid TO re_valid_chk.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.                    "fill_valid_chk

  METHOD fill_subst_cond.
    DATA: ls_gb921 TYPE gb921,
          ls_gb901 TYPE gb901,
          ls_gb921t TYPE gb921t,
          ls_subst TYPE ty_subst_cond.

*   Para todos los pasos de substitución...
    LOOP AT im_gb921 INTO ls_gb921 WHERE substid IN so_subst.
*     Buscamos el texto del paso
      CLEAR ls_gb921t.
      READ TABLE im_gb921t WITH KEY subsid = ls_gb921-substid
                                    subseqnr = ls_gb921-subseqnr
                                    INTO ls_gb921t.
*     Buscamos la condición booleana
      LOOP AT im_gb901 INTO ls_gb901 WHERE boolid = ls_gb921-condid.
        CLEAR ls_subst.
        MOVE-CORRESPONDING ls_gb921 TO ls_subst.
        MOVE-CORRESPONDING ls_gb921t TO ls_subst.
        MOVE-CORRESPONDING ls_gb901 TO ls_subst.
        APPEND ls_subst TO re_subst_cond.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.                    "fill_subst_cond

  METHOD fill_subst_subst.
    DATA: ls_gb921 TYPE gb921,
          ls_gb922 TYPE gb922,
          ls_gb921t TYPE gb921t,
          ls_subst TYPE ty_subst_sust.

*   For each substitution step...
    LOOP AT im_gb921 INTO ls_gb921 WHERE substid IN so_subst.
*     Look for step text
      CLEAR ls_gb921t.
      READ TABLE im_gb921t WITH KEY subsid = ls_gb921-substid
                                    subseqnr = ls_gb921-subseqnr
                                    INTO ls_gb921t.
*     Look for substitution value
      LOOP AT im_gb922 INTO ls_gb922 WHERE substid = ls_gb921-substid
                                       AND subseqnr = ls_gb921-subseqnr.
        CLEAR ls_subst.
        MOVE-CORRESPONDING ls_gb921 TO ls_subst.
        MOVE-CORRESPONDING ls_gb921t TO ls_subst.
        MOVE-CORRESPONDING ls_gb922 TO ls_subst.
        APPEND ls_subst TO re_subst_subst.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.                    "fill_subst_subst

  METHOD compare_valid_cond.
    DATA: ls_valid_rfc TYPE ty_valid_cond,
          ls_valid TYPE ty_valid_cond,
          ls_valid_cond_out TYPE valid_cond_out_type.

*   Difference between rfc and local
    LOOP AT attr_t_valid_cond_rfc INTO ls_valid_rfc.
      LOOP AT gt_valid_cond INTO ls_valid
                             WHERE valid = ls_valid_rfc-valid
                                AND valseqnr = ls_valid_rfc-valseqnr
                                AND seqnr = ls_valid_rfc-seqnr.

        IF ls_valid_rfc <> ls_valid.
          ls_valid_cond_out-local = ls_valid.
          ls_valid_cond_out-icon = icon_not_equal_red.
          ls_valid_cond_out-remoto = ls_valid_rfc.
          APPEND ls_valid_cond_out TO attr_t_valid_cond_out.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

*   Exists in rfc but not in local
    LOOP AT attr_t_valid_cond_rfc INTO ls_valid_rfc.
      READ TABLE gt_valid_cond WITH KEY valid = ls_valid_rfc-valid
                                   valseqnr = ls_valid_rfc-valseqnr
                                   seqnr = ls_valid_rfc-seqnr
                                   INTO ls_valid.
      IF sy-subrc <> 0.
        CLEAR ls_valid_cond_out-local.
        ls_valid_cond_out-icon = icon_page_left.
        ls_valid_cond_out-remoto = ls_valid_rfc.
        APPEND ls_valid_cond_out TO attr_t_valid_cond_out.
      ENDIF.
    ENDLOOP.

*   Exists in local but not in rfc
    LOOP AT gt_valid_cond INTO ls_valid.
      READ TABLE attr_t_valid_cond_rfc WITH KEY valid = ls_valid-valid
                                   valseqnr = ls_valid-valseqnr
                                   seqnr = ls_valid-seqnr
                                   INTO ls_valid_rfc.
      IF sy-subrc <> 0.
        ls_valid_cond_out-local = ls_valid.
        ls_valid_cond_out-icon = icon_page_right.
        CLEAR ls_valid_cond_out-remoto.
        APPEND ls_valid_cond_out TO attr_t_valid_cond_out.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.                    "compare_valid_cond

  METHOD compare_valid_chk.
    DATA: ls_valid_rfc TYPE ty_valid_chk,
          ls_valid TYPE ty_valid_chk,
          ls_valid_chk_out TYPE ty_valid_chk_out.

*   Difference between rfc and local
    LOOP AT attr_t_valid_chk_rfc INTO ls_valid_rfc.
      LOOP AT attr_t_valid_chk INTO ls_valid
                             WHERE valid = ls_valid_rfc-valid
                               AND valseqnr = ls_valid_rfc-valseqnr.

        IF ls_valid_rfc <> ls_valid.
          ls_valid_chk_out-local = ls_valid.
          ls_valid_chk_out-icon = icon_not_equal_red.
          ls_valid_chk_out-remoto = ls_valid_rfc.
          APPEND ls_valid_chk_out TO attr_t_valid_chk_out.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

*   Exists in rfc but not in local
    LOOP AT attr_t_valid_chk_rfc INTO ls_valid_rfc.
      READ TABLE attr_t_valid_chk WITH KEY valid = ls_valid_rfc-valid
                                       valseqnr = ls_valid_rfc-valseqnr
                                  INTO ls_valid.
      IF sy-subrc <> 0.
        CLEAR ls_valid_chk_out-local.
        ls_valid_chk_out-icon = icon_page_left.
        ls_valid_chk_out-remoto = ls_valid_rfc.
        APPEND ls_valid_chk_out TO attr_t_valid_chk_out.
      ENDIF.
    ENDLOOP.

*   Exists in local but not in rfc
    LOOP AT attr_t_valid_chk INTO ls_valid.
      READ TABLE attr_t_valid_chk_rfc WITH KEY valid = ls_valid-valid
                                           valseqnr = ls_valid-valseqnr
                                      INTO ls_valid_rfc.
      IF sy-subrc <> 0.
        ls_valid_chk_out-local = ls_valid.
        ls_valid_chk_out-icon = icon_page_right.
        CLEAR ls_valid_chk_out-remoto.
        APPEND ls_valid_chk_out TO attr_t_valid_chk_out.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.                    "compare_valid_chk

  METHOD compare_subst_cond.
    DATA: ls_subst_cond_rfc TYPE ty_subst_cond,
          ls_subst_cond TYPE ty_subst_cond,
          ls_subst_cond_out TYPE ty_subst_cond_out.

*   Difference between rfc and local
    LOOP AT attr_t_subst_cond_rfc INTO ls_subst_cond_rfc.
      LOOP AT attr_t_subst_cond INTO ls_subst_cond
                         WHERE substid = ls_subst_cond_rfc-substid
                           AND subseqnr = ls_subst_cond_rfc-subseqnr
                           AND seqnr = ls_subst_cond_rfc-seqnr.
        IF ls_subst_cond_rfc <> ls_subst_cond.
          ls_subst_cond_out-local = ls_subst_cond.
          ls_subst_cond_out-icon = icon_not_equal_red.
          ls_subst_cond_out-remoto = ls_subst_cond_rfc.
          APPEND ls_subst_cond_out TO attr_t_subst_cond_out.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

*   Exists in rfc but not in local
    LOOP AT attr_t_subst_cond_rfc INTO ls_subst_cond_rfc.
      READ TABLE attr_t_subst_cond
                     WITH KEY substid = ls_subst_cond_rfc-substid
                              subseqnr = ls_subst_cond_rfc-subseqnr
                              seqnr = ls_subst_cond_rfc-seqnr
                     INTO ls_subst_cond.
      IF sy-subrc <> 0.
        CLEAR ls_subst_cond_out-local.
        ls_subst_cond_out-remoto = ls_subst_cond_rfc.
        ls_subst_cond_out-icon = icon_page_left.
        APPEND ls_subst_cond_out TO attr_t_subst_cond_out.
      ENDIF.
    ENDLOOP.

*   Exists in local but not in rfc
    LOOP AT attr_t_subst_cond INTO ls_subst_cond.
      READ TABLE attr_t_subst_cond_rfc
                     WITH KEY substid = ls_subst_cond-substid
                              subseqnr = ls_subst_cond-subseqnr
                              seqnr = ls_subst_cond-seqnr
                     INTO ls_subst_cond_rfc.
      IF sy-subrc <> 0.
        ls_subst_cond_out-local = ls_subst_cond.
        ls_subst_cond_out-icon = icon_page_right.
        CLEAR ls_subst_cond_out-remoto.
        APPEND ls_subst_cond_out TO attr_t_subst_cond_out.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.                    "compare_subst_cond


  METHOD compare_subst_subst.
    DATA: ls_subst_sust_rfc TYPE ty_subst_sust,
          ls_subst_sust TYPE ty_subst_sust,
          ls_subst_sust_out TYPE ty_subst_sust_out.

*   Difference between rfc and local
    LOOP AT attr_t_subst_subst_rfc INTO ls_subst_sust_rfc.
      LOOP AT attr_t_subst_subst INTO ls_subst_sust
                         WHERE substid = ls_subst_sust_rfc-substid
                           AND subseqnr = ls_subst_sust_rfc-subseqnr
                           AND conseqnr = ls_subst_sust_rfc-conseqnr.
        IF ls_subst_sust_rfc <> ls_subst_sust.
          ls_subst_sust_out-local = ls_subst_sust.
          ls_subst_sust_out-icon = icon_not_equal_red.
          ls_subst_sust_out-remoto = ls_subst_sust_rfc.
          APPEND ls_subst_sust_out TO attr_t_subst_sust_out.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

*   Exists in rfc but not in local
    LOOP AT attr_t_subst_subst_rfc INTO ls_subst_sust_rfc.
      READ TABLE attr_t_subst_subst
                     WITH KEY substid = ls_subst_sust_rfc-substid
                              subseqnr = ls_subst_sust_rfc-subseqnr
                              conseqnr = ls_subst_sust_rfc-conseqnr
                     INTO ls_subst_sust.
      IF sy-subrc <> 0.
        CLEAR ls_subst_sust_out-local.
        ls_subst_sust_out-icon = icon_page_left.
        ls_subst_sust_out-remoto = ls_subst_sust_rfc.
        APPEND ls_subst_sust_out TO attr_t_subst_sust_out.
      ENDIF.
    ENDLOOP.

*   Exists in local but not in rfc
    LOOP AT attr_t_subst_subst INTO ls_subst_sust.
      READ TABLE attr_t_subst_subst_rfc
                     WITH KEY substid = ls_subst_sust-substid
                              subseqnr = ls_subst_sust-subseqnr
                              conseqnr = ls_subst_sust-conseqnr
                     INTO ls_subst_sust_rfc.
      IF sy-subrc <> 0.
        ls_subst_sust_out-local = ls_subst_sust.
        ls_subst_sust_out-icon = icon_page_right.
        CLEAR ls_subst_sust_out-remoto.
        APPEND ls_subst_sust_out TO attr_t_subst_sust_out.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.                    "compare_subst_subst


  METHOD load_table_rfc.
    DATA: lt_entries TYPE STANDARD TABLE OF tab512.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    CALL FUNCTION 'RFC_GET_TABLE_ENTRIES' DESTINATION p_rfc
      EXPORTING
        table_name            = im_tablename
      TABLES
        entries               = lt_entries
      EXCEPTIONS
        system_failure        = 1
        communication_failure = 2
        internal_error        = 3
        table_empty           = 4
        table_not_found       = 5
        OTHERS                = 6.

    IF sy-subrc <> 0.
      MESSAGE e398(00) WITH 'Table' im_tablename
                            'RFC_GET_TABLE_ENTRIES returned exception' sy-subrc.
    ENDIF.

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_name( im_tablename ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA re_table TYPE HANDLE lo_abap_tabledescr.
    ASSIGN re_table->* TO <lt_table>.
    <lt_table> = lt_entries.
  ENDMETHOD.                    "load_table_rfc

  METHOD load_table_local.
    DATA: lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
          lo_abap_tabledescr TYPE REF TO cl_abap_tabledescr.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    lo_abap_structdescr ?= cl_abap_typedescr=>describe_by_name( im_tablename ).
    lo_abap_tabledescr = cl_abap_tabledescr=>create( lo_abap_structdescr ).
    CREATE DATA re_table TYPE HANDLE lo_abap_tabledescr.
    ASSIGN re_table->* TO <lt_table>.

    SELECT *
       INTO TABLE <lt_table>
    FROM (im_tablename).

    IF sy-subrc <> 0.
      MESSAGE e398(00) WITH 'Table' im_tablename
                            'not found' space.
    ENDIF.
  ENDMETHOD.                    "load_table


  METHOD show_alv.
    DATA: lv_text_error TYPE string.
    DATA: lo_cx_root TYPE REF TO cx_root.
    DATA: lo_salv_table TYPE REF TO cl_salv_table.
    FIELD-SYMBOLS : <lt_table> TYPE ANY TABLE.

    ASSIGN im_table->* TO <lt_table>.

    TRY.
        cl_salv_table=>factory(
          IMPORTING
            r_salv_table = lo_salv_table
          CHANGING
            t_table      = <lt_table> ).

        set_alv_columns( lo_salv_table ).
        set_alv_functions( lo_salv_table ).
        lo_salv_table->display( ).
      CATCH cx_salv_msg INTO lo_cx_root.
        lv_text_error = lo_cx_root->get_text( ).
        MESSAGE e208(00) WITH lv_text_error.
    ENDTRY.
  ENDMETHOD.                    "show_alv

  METHOD set_alv_columns.
    DATA: lo_salv_columns TYPE REF TO cl_salv_columns.

    lo_salv_columns = im_salv_table->get_columns( ).
    lo_salv_columns->set_optimize( abap_true ).
  ENDMETHOD.                    "set_alv_columns

  METHOD set_alv_functions.
    DATA: lo_functions TYPE REF TO cl_salv_functions_list.

    lo_functions = im_salv_table->get_functions( ).
    lo_functions->set_all( abap_true ).
  ENDMETHOD.                    "set_alv_functions

ENDCLASS.                    "lcl_valid_susbt IMPLEMENTATION


*--------------------------------------------------------------------*
* START-OF-SELECTION.
*--------------------------------------------------------------------*
START-OF-SELECTION.
  lcl_valid_susbt=>execute( ).
To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply