Thursday, May 14, 2026

How to analyze the dependency of one transport to other transports

 



*&---------------------------------------------------------------------*
*& Report ZTR_DEPENDENCY_ANALYZER
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
*  Program    : ZTR_DEPENDENCY_ANALYZER                           *
*  Title      : A report to Analyze all transports for monthly release *
*             : and check them for dependency and sequence             *
*----------------------------------------------------------------------*
*  Author     :  GB                                                    *
*  Created    :  DDMMYYYY                                              *
*  Description:  The program reads transport details and finds objects *
*             :  present in other transports. This is dependency check *
*             :  It also performs sequence check by sorting and then   *
*             :  using sap versioning                                  *
*             :                                                        *
*----------------------------------------------------------------------*

REPORT ztr_dependency_analyzer.

TABLESe071.

*deep structure example

TYPESBEGIN OF lty_trans,
         trans  TYPE trkorr,
         versno TYPE numc5,
       END OF lty_trans.

TYPESltt_trans TYPE STANDARD TABLE OF lty_trans.

TYPESBEGIN OF lty_e071,
         trkorr     TYPE trkorr,
         trfunction TYPE trfunction,
         object     TYPE trobjtype,
         obj_name   TYPE trobj_name,
         strkorr    TYPE strkorr,
         task_tr    TYPE trkorr,
         trans      TYPE char100,
         depend     TYPE char100,
         ver_exist  TYPE char1,
       END OF lty_e071.

TYPESBEGIN OF lty_details,
         trkorr     TYPE trkorr,
         trfunction TYPE trfunction,
         object     TYPE trobjtype,
         obj_name   TYPE trobj_name,
         strkorr    TYPE strkorr,
         task_tr    TYPE trkorr,
         trans_tab  TYPE STANDARD TABLE OF lty_trans WITH EMPTY KEY"with empty key required for deep structure
       END OF lty_details.

DATAlt_e071 TYPE STANDARD TABLE OF lty_e071.
DATAls_e071 TYPE lty_e071.

DATAlt_details TYPE STANDARD TABLE OF lty_details.
DATAls_details TYPE lty_details.

DATAlt_ver TYPE STANDARD TABLE OF vrsd.

DATAlv_depend TYPE boole_d.

* Selection Screen

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-b01.
  SELECT-OPTIONS:
  so_tr FOR e071-trkorr NO INTERVALS.
  PARAMETERScb_dep AS CHECKBOX DEFAULT 'X'.
  PARAMETERScb_con AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK b1.

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-b02.
  SELECTION-SCREEN COMMENT /1(75TEXT-t01.
  SELECTION-SCREEN COMMENT /1(75TEXT-t02.
  SELECTION-SCREEN COMMENT /1(75TEXT-t03.
  SELECTION-SCREEN COMMENT /1(75TEXT-t04.
  SELECTION-SCREEN COMMENT /1(75TEXT-t05.
SELECTION-SCREEN END OF BLOCK b2.

* Start Of Selection
START-OF-SELECTION.

  SELECT a1~trkorr,
         a~trfunction,
         a1~object,
         a1~obj_name,
         a0~strkorr
    FROM e071 AS a1 "Get from subtasks
    INNER JOIN e070 AS a0
    INNER JOIN e070 AS a
    ON a0~strkorr a~trkorr
    ON a1~trkorr a0~trkorr
    INTO TABLE @lt_e071
    WHERE a0~strkorr IN @so_tr.

  SELECT a1~trkorr,
         a~trfunction,
         a1~object,
         a1~obj_name
    FROM e071 AS a1
      INNER JOIN e070 AS a
      ON a~trkorr a1~trkorr
    APPENDING TABLE @lt_e071
    WHERE a1~trkorr IN @so_tr.

*End of Selection
END-OF-SELECTION.

*COPY PARENT TR TO TR FIELD
  LOOP AT lt_e071 ASSIGNING FIELD-SYMBOL(<lfs_e071_c>).
    <lfs_e071_c>-task_tr <lfs_e071_c>-trkorr.
    IF <lfs_e071_c>-strkorr IS NOT INITIAL.
      <lfs_e071_c>-trkorr <lfs_e071_c>-strkorr.
    ENDIF.
  ENDLOOP.

  SORT lt_e071 BY trkorr object obj_name.
  DELETE ADJACENT DUPLICATES FROM lt_e071 COMPARING trkorr object obj_name.

* Workbench TR only
  DELETE lt_e071 WHERE trfunction NE 'K'.

  LOOP AT lt_e071 ASSIGNING FIELD-SYMBOL(<lfs_e071>).
    CLEAR ls_details.
    MOVE-CORRESPONDING <lfs_e071> TO ls_details.

    LOOP AT lt_e071 INTO ls_e071 WHERE object <lfs_e071>-object AND obj_name <lfs_e071>-obj_name.
      IF <lfs_e071>-trkorr NE ls_e071-trkorr.
        IF <lfs_e071>-trans IS INITIAL.
          <lfs_e071>-trans ls_e071-trkorr.
        ELSE.
          CONCATENATE <lfs_e071>-trans ',' ls_e071-trkorr INTO <lfs_e071>-trans.
        ENDIF.
        APPEND ls_e071-trkorr TO ls_details-trans_tab[].
      ENDIF.
    ENDLOOP.
    APPEND ls_details TO lt_details.
  ENDLOOP.

  IF cb_dep IS NOT INITIAL OR cb_con IS NOT INITIAL.
* Delete Records without dependency
    DELETE lt_e071 WHERE trans IS INITIAL.
    DELETE lt_details WHERE trans_tab IS INITIAL.
  ENDIF.

  LOOP AT lt_details ASSIGNING FIELD-SYMBOL(<lfs_details>).

*  Add the main tr
    APPEND <lfs_details>-trkorr TO <lfs_details>-trans_tab.

*  By Default, sort it by ascending order
    SORT <lfs_details>-trans_tab BY trans.

    " It is also possible to move it outside the loop by using FAE from lt_details and using read table to remove ATC P1
    SELECT FROM vrsd INTO TABLE lt_ver WHERE objtype <lfs_details>-object AND objname <lfs_details>-obj_name.

    IF sy-subrc EQ 0.
      SORT lt_ver BY datum zeit.
    ENDIF.

    LOOP AT lt_ver ASSIGNING FIELD-SYMBOL(<lfs_vers>WHERE versno IS INITIAL.
      IF <lfs_vers>-lastversno IS NOT INITIAL.
        <lfs_vers>-versno <lfs_vers>-lastversno + 1.
      ENDIF.
    ENDLOOP.

* If version history is found then use version history to get version number
    LOOP AT <lfs_details>-trans_tab ASSIGNING FIELD-SYMBOL(<lfs_trans>).
      READ TABLE lt_ver ASSIGNING FIELD-SYMBOL(<lfs_ver>WITH KEY korrnum <lfs_trans>-trans.
      IF sy-subrc EQ 0.
        <lfs_trans>-versno <lfs_ver>-versno.
      ENDIF.
    ENDLOOP.

* Sort by version number
    SORT <lfs_details>-trans_tab BY versno.

  ENDLOOP.

* Prepare the output table in sequence
  CLEARlt_e071[].
  LOOP AT lt_details ASSIGNING <lfs_details>.
    CLEARls_e071lv_depend.
    MOVE-CORRESPONDING <lfs_details> TO ls_e071.

    LOOP AT <lfs_details>-trans_tab ASSIGNING <lfs_trans>.

      IF cb_con IS INITIAL.
        CONCATENATE ls_e071-trans <lfs_trans>-trans '(' <lfs_trans>-versno '),INTO ls_e071-trans.
        IF <lfs_trans>-trans NE <lfs_details>-trkorr AND lv_depend IS INITIAL.
          CONCATENATE ls_e071-depend <lfs_trans>-trans '(' <lfs_trans>-versno '),INTO ls_e071-depend.
        ENDIF.
      ELSE.
        CONCATENATE ls_e071-trans <lfs_trans>-trans ',INTO ls_e071-trans.
        IF <lfs_trans>-trans NE <lfs_details>-trkorr AND lv_depend IS INITIAL.
          CONCATENATE ls_e071-depend <lfs_trans>-trans ',INTO ls_e071-depend.
        ENDIF.
      ENDIF.
      IF <lfs_trans>-versno GT 0.
        ls_e071-ver_exist 'X'.
      ENDIF.
      IF <lfs_trans>-trans EQ <lfs_details>-trkorr.
        lv_depend 'X'.
      ENDIF.
    ENDLOOP.

    APPEND ls_e071 TO lt_e071.
  ENDLOOP.

  IF cb_con IS NOT INITIAL.
    SORT lt_e071 BY trkorr trans ver_exist.
    DELETE ADJACENT DUPLICATES FROM lt_e071 COMPARING trkorr trans ver_exist.
  ENDIF.

*==============Display ALV==================*
  DATAgr_table TYPE REF TO cl_salv_table.

* Edit fields displayed
  DATA:
    gr_columns TYPE REF TO cl_salv_columns_table,
    gr_column  TYPE REF TO cl_salv_column_table.
*============== Enable ALV Toolbar Functions =================*
  DATAlr_functions TYPE REF TO cl_salv_functions_list.

  TRY.
      CALL METHOD cl_salv_table=>factory
        IMPORTING
          r_salv_table gr_table
        CHANGING
          t_table      lt_e071" Provide the table name

*============== Enable ALV Toolbar Functions =================*
      lr_functions gr_table->get_functions).
      lr_functions->set_allabap_true )" This enables Export, Sort, Filter, etc.


      " 1. Get all columns
      gr_columns gr_table->get_columns).
      gr_columns->set_optimizeabap_true )" Optional: Auto-fit column widths

      IF cb_con IS NOT INITIAL.
        " 2. Remove a field (e.g., 'TRKORR')
        TRY.
            gr_column ?= gr_columns->get_column'TRFUNCTION' ).
            gr_column->set_visibleabap_false ).

            gr_column ?= gr_columns->get_column'OBJECT' ).
            gr_column->set_visibleabap_false ).

            gr_column ?= gr_columns->get_column'OBJ_NAME' ).
            gr_column->set_visibleabap_false ).

            gr_column ?= gr_columns->get_column'STRKORR' ).
            gr_column->set_visibleabap_false ).

            gr_column ?= gr_columns->get_column'TASK_TR' ).
            gr_column->set_visibleabap_false ).

          CATCH cx_salv_not_found.
        ENDTRY.
      ELSE.
        TRY.
            gr_column ?= gr_columns->get_column'STRKORR' ).
            gr_column->set_visibleabap_false ).

            gr_column ?= gr_columns->get_column'TASK_TR' ).
            gr_column->set_visibleabap_false ).

          CATCH cx_salv_not_found.
        ENDTRY.
      ENDIF.

      " 3. Change text description (e.g., 'AS4USER')
      TRY.
          gr_column ?= gr_columns->get_column'TRANS' ).
          gr_column->set_long_text'TR Sequence' ).
          gr_column->set_medium_text'TR Seq' ).
          gr_column->set_short_text'Seq' ).

          gr_column ?= gr_columns->get_column'DEPEND' ).
          gr_column->set_long_text'Dependency' ).
          gr_column->set_medium_text'Depend' ).
          gr_column->set_short_text'Dep' ).

          gr_column ?= gr_columns->get_column'VER_EXIST' ).
          gr_column->set_long_text'Versions Exist' ).
          gr_column->set_medium_text'Versions' ).
          gr_column->set_short_text'Ver' ).

        CATCH cx_salv_not_found.
      ENDTRY.

    CATCH cx_salv_msg.

  ENDTRY.
*... Display Table
  gr_table->display).

No comments:

Post a Comment

Search SAPMV45A includes for Constants and Statics

 This report can find CONSTANTS and STATICS in SAPMV45A Z-includes. We know that Constants and Statics consume global variables so identifyi...