DYNAMIC SELECTION PROGRAMMING (COMPARISON OF TWO SYSTEMS)

First, we’ll take a deep dive into dynamic programming in our article. While addressing this issue, I will go through an example that would be very useful for us. We will be comparing each data which belongs to different specific systems. In this way, there will be advantages to us as follows.

  • Analyzing the differences in the received data after changes in 3rd party systems sending data to our systems.
  • Analyzing the different behaviors of specific systems despite the codes are the same (by checking the customizing tables)
  • Periodically scanning the data stored in customizing tables of specific systems to make sure that they are the same.

Dynamic Internal Table

Let’s take a look at our application.

First of all, we will give the name of table as the selection parameter as below.

PARAMETERS : p_tabnam TYPE ddobjname.

Second, the field information of the table is obtained.

FORM get_table_info USING im_table_name TYPE ddobjname
                 CHANGING ch_key_length TYPE i
                          ch_dfies_tab  TYPE dfies_table.

  DATA lv_tab_name TYPE ddobjname.

  DATA lv_uclen TYPE unicodelg VALUE 'X'.

  CLEAR : ch_key_length, ch_dfies_tab.

  lv_tab_name = im_table_name.

  CALL FUNCTION 'DDIF_NAMETAB_GET'
    EXPORTING
      tabname   = lv_tab_name
      uclen     = lv_uclen
    TABLES
      dfies_tab = ch_dfies_tab
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.

  LOOP AT ch_dfies_tab INTO DATA(ls_field) WHERE keyflag EQ abap_true.

    ch_key_length = ch_key_length + ls_field-leng.

  ENDLOOP.

ENDFORM.

Then, internal table variables belonging to the relevant table are created.

CREATE DATA : lo_dref_current TYPE STANDARD TABLE OF (p_tabnam),
                lo_dref_target  TYPE STANDARD TABLE OF (p_tabnam).

  UNASSIGN : <lfs_table_current>, <lfs_table_target>.

  ASSIGN : lo_dref_current->* TO <lfs_table_current>,
           lo_dref_target->*  TO <lfs_table_target>.

Data is taken from the table as follows and the data is transferred to the internal table we created above. If we want, we can dynamically give the selection conditions by giving the relevant fields and values to our lt_conditions_current internal table.

SELECT *
    FROM (p_tabnam)
    INTO TABLE <lfs_table_current>
   WHERE (lt_options_current).

Now we dynamically pull our data from the target system.

CLEAR lv_xml_tab.

  CALL FUNCTION 'Z_GET_TARGET_DATA' DESTINATION 'TARGET_SYSTEM'
    EXPORTING
      im_table_name     = p_tabnam
      im_where_cond_tab = lt_options_target
    IMPORTING
      ex_tab_data       = lv_xml_tab
    EXCEPTIONS
      data_not_found    = 1
      OTHERS            = 2.

  IF sy-subrc = 0.

    CALL TRANSFORMATION id SOURCE XML lv_xml_tab RESULT mydata = <lfs_table_target>.

  ELSE.
    WRITE / 'data not found on target system'.
    RETURN.
  ENDIF.

RFC is created in the target system as follows, and we write our dynamic query in it and get the result as XML.

FUNCTION z_get_target_data.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(IM_TABLE_NAME) TYPE  RSRD1-TBMA_VAL
*"     VALUE(IM_WHERE_COND_TAB) TYPE  ESH_T_CO_RFCRT_OPTIONS
*"  EXPORTING
*"     VALUE(EX_TAB_DATA) TYPE  STRING
*"  EXCEPTIONS
*"      DATA_NOT_FOUND
*"----------------------------------------------------------------------
  DATA : lo_dref TYPE REF TO data.

  FIELD-SYMBOLS : <lfs_dyn_table> TYPE STANDARD TABLE.

  CREATE DATA lo_dref TYPE STANDARD TABLE OF (im_table_name).

  ASSIGN lo_dref->* TO <lfs_dyn_table>.

  SELECT * FROM (im_table_name) INTO TABLE <lfs_dyn_table> WHERE (im_where_cond_tab).

  IF sy-subrc <> 0.
    RAISE data_not_found.
  ELSE.
    CALL TRANSFORMATION id SOURCE mydata = <lfs_dyn_table> RESULT XML ex_tab_data OPTIONS data_refs = 'heap-or-create'.
  ENDIF.

ENDFUNCTION.

Each record in the current system and each field belonging to these records are checked one by one.

LOOP AT <lfs_table_current> ASSIGNING <lfs_line_current>.

    UNASSIGN <lfs_key>.

    ASSIGN <lfs_line_current>(lv_key_count) TO <lfs_key>.

    READ TABLE <lfs_table_target> ASSIGNING <lfs_line_target> WITH KEY <lfs_key>.

    IF sy-subrc = 0.

      LOOP AT lt_field INTO DATA(ls_field).

        ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE : <lfs_line_current> TO <lfs_value_current>,
                                                           <lfs_line_target>  TO <lfs_value_target>.

        IF <lfs_value_current> NE <lfs_value_target>.

          WRITE / 'Different value found in field' && ` ` && ls_field-fieldname && ` ` && 'for related key' && ` ` && <lfs_key> .
          WRITE ' Current Value: ' && <lfs_value_current>.
          WRITE ' Target Value: '  && <lfs_value_target>.

        ENDIF.
      ENDLOOP.
    ELSE.
      WRITE / 'No records were found in the target system for related key data' && ` ` && <lfs_key>.
    ENDIF.
  ENDLOOP.

RESULTS

If our application cannot find data in the target system, it will return as follows.

It shows the different values between the current system and the target system as follows.

In addition, if data cannot be found in the target system for the relevant record in the current system, the following warning is shown.

Source code of the sample application:

REPORT z_exercise_dynamic.

PARAMETERS : p_tabnam TYPE ddobjname.

PERFORM scan_the_differences.

FORM get_table_info USING im_table_name TYPE ddobjname 
                 CHANGING ch_key_length TYPE i
                          ch_dfies_tab  TYPE dfies_table.

  DATA lv_tab_name TYPE ddobjname.

  DATA lv_uclen TYPE unicodelg VALUE 'X'.

  CLEAR : ch_key_length, ch_dfies_tab.

  lv_tab_name = im_table_name.

  CALL FUNCTION 'DDIF_NAMETAB_GET'
    EXPORTING
      tabname   = lv_tab_name
      uclen     = lv_uclen
    TABLES
      dfies_tab = ch_dfies_tab
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.

  LOOP AT ch_dfies_tab INTO DATA(ls_field) WHERE keyflag EQ abap_true.

    ch_key_length = ch_key_length + ls_field-leng.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SCAN_THE_DIFFERENCES
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM scan_the_differences .

  FIELD-SYMBOLS : <lfs_table_current> TYPE STANDARD TABLE,
                  <lfs_table_target>  TYPE STANDARD TABLE,
                  <lfs_line_current>,
                  <lfs_line_target>,
                  <lfs_key>,
                  <lfs_value_current>,
                  <lfs_value_target>.

  DATA : lo_dref_current TYPE REF TO data,
         lo_dref_target  TYPE REF TO data.

  DATA : lt_options_current TYPE esh_t_co_rfcrt_options,
         lt_options_target  TYPE esh_t_co_rfcrt_options,
         lt_field           TYPE TABLE OF dfies,
         lt_cond            TYPE RANGE OF rfc_db_opt-text.

  DATA : lv_xml_tab      TYPE string,
         lv_key_count    TYPE i,
         lv_where_clause TYPE string.

  CLEAR : lv_key_count, lt_field, lt_options_current, lt_options_target.

  PERFORM get_table_info
    USING
      p_tabnam
    CHANGING
      lv_key_count
      lt_field.

  CREATE DATA : lo_dref_current TYPE STANDARD TABLE OF (p_tabnam),
                lo_dref_target  TYPE STANDARD TABLE OF (p_tabnam).

  UNASSIGN : <lfs_table_current>, <lfs_table_target>.

  ASSIGN : lo_dref_current->* TO <lfs_table_current>,
           lo_dref_target->*  TO <lfs_table_target>.

*      lv_rfc_where_str = 'MTART' && ' EQ ''' && 'HALB' && ''''.
*      APPEND lv_rfc_where_str TO lt_options.

  SELECT *
    FROM (p_tabnam)
    INTO TABLE <lfs_table_current>
   WHERE (lt_options_current).

*      lv_rfc_where_str = 'MTART' && ' EQ ''' && 'HALB' && ''''.
*      APPEND lv_rfc_where_str TO lt_options_target.

  CLEAR lv_xml_tab.

  CALL FUNCTION 'Z_GET_TARGET_DATA' DESTINATION 'TARGET_SYSTEM'
    EXPORTING
      im_table_name     = p_tabnam
      im_where_cond_tab = lt_options_target
    IMPORTING
      ex_tab_data       = lv_xml_tab
    EXCEPTIONS
      data_not_found    = 1
      OTHERS            = 2.

  IF sy-subrc = 0.

    CALL TRANSFORMATION id SOURCE XML lv_xml_tab RESULT mydata = <lfs_table_target>.

  ELSE.
    WRITE / 'data not found on target system'.
    RETURN.
  ENDIF.

  LOOP AT <lfs_table_current> ASSIGNING <lfs_line_current>.

    UNASSIGN <lfs_key>.

    ASSIGN <lfs_line_current>(lv_key_count) TO <lfs_key>.

    READ TABLE <lfs_table_target> ASSIGNING <lfs_line_target> WITH KEY <lfs_key>.

    IF sy-subrc = 0.

      LOOP AT lt_field INTO DATA(ls_field).

        ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE : <lfs_line_current> TO <lfs_value_current>,
                                                           <lfs_line_target>  TO <lfs_value_target>.

        IF <lfs_value_current> NE <lfs_value_target>.

          WRITE / 'Different value found in field' && ` ` && ls_field-fieldname && ` ` && 'for related key' && ` ` && <lfs_key> .
          WRITE ' Current Value: ' && <lfs_value_current>.
          WRITE ' Target Value: '  && <lfs_value_target>.

        ENDIF.
      ENDLOOP.
    ELSE.
      WRITE / 'No records were found in the target system for related key data' && ` ` && <lfs_key>.
    ENDIF.
  ENDLOOP.


ENDFORM.
Translate »