Skip to Content
Technical Articles
Author's profile photo Vlad Kustov

Where my transport and what inside

Introduction

Transport objects list handling is very important on any project: first developer may make a correction and release the transport, than an object may be changed by another developer and be released again. Wrong customization in a transport may have impact on regular reporting. New OSS Note may also affect performance or conflict with Customer enhancements, Customer User-EXIT’s or Customer BADI’s implementation.

Checking the history of transports and their status in the target system from the transport domain could be useful when developers or business analysts would like to know where the transport is and what is inside.

Another point regarding transports with OSS Note Corrections: some of OSS Notes should only stay in a development system. For example, I keep all technical OSS Notes in Development system and all technical OSS Notes are updated in Development system only.

Transaction SE01 (Extended Transport Organizer) provides information on the current transport queue, but user has to select the status of transports and, if the user needs to find a particular object from the entire queue, he (or she) has to drill down into every single transport.

Very often transport in the next system could have errors due to broken sequence of transports. Object definition, for example, comes after object corrections.

The report below could help to monitor the history of object corrections and the sequence of transports and provide some information about implemented OSS Notes and show what went into Production:

(Used syntax ABAP 7.52)

*&---------------------------------------------------------------------*
*& Report Z_CHECK_TRANSPORT
*&---------------------------------------------------------------------*
*& This report will work if transport History of Target System updated
*&---------------------------------------------------------------------*
REPORT z_check_transport.
* ALV Output data structure
TYPES: BEGIN OF transp_str,
         trkorr     TYPE   e070-trkorr,     "Request/Task
         trfunction TYPE   e070-trfunction, "Type of request/task
         trstatus   TYPE   e070-trstatus,   "Status of request/task
         as4text    TYPE   e07t-as4text,    "Descr of Repository Obj
         tarsystem  TYPE   e070-tarsystem,  "Transport Target of Req
         korrdev    TYPE   e070-korrdev,    "Request or task category
         as4user    TYPE   e070-as4user,    "Owner of a Request or Task
         as4date    TYPE   e070-as4date,    "Last Changed On
         strkorr    TYPE   e070-strkorr,    "Higher-Level Request
         as4pos     TYPE   e071-as4pos,     "Dictionary: Line item
         pgmid      TYPE   e071-pgmid,      "Program ID
         object     TYPE   e071-object,     "Object Type
         obj_name   TYPE   e071-obj_name,   "Object Name in Obj List
         objfunc    TYPE   e071-objfunc,    "Object function
         lockflag   TYPE   e071-lockflag,   "Lock status or import status
         activity   TYPE   e071-activity,   "Activ. that wrote the entry
         devclass   TYPE   tadir-devclass,
         stext      TYPE   cwbntstxt-stext, "OSS NOTE Header Long Text
         prod       TYPE   e070-tarsystem,  "Target system
         ddtext     TYPE   dd07v-ddtext,    "Transport Status Value
         impdat_ts  TYPE   stmsiqreq-impdat, "Target system import date
       END OF transp_str.
DATA et_transport TYPE TABLE OF transp_str.
* Select Options TYPEs
DATA: as4date  TYPE e070-as4date,
      trkorr   TYPE e070-trkorr,
      impflg   TYPE tmsbufreq-impflg,
      object   TYPE e071-object,
      obj_name TYPE e071-obj_name,
      trstatus TYPE e070-trstatus,
      user     TYPE e070-as4user.
SELECT-OPTIONS: s_date   FOR  as4date,
                s_tran   FOR  trkorr,
                s_iflg   FOR  impflg,
                s_obj    FOR  object,
                s_obj_n  FOR  obj_name,
                s_tr_st  FOR  trstatus,
                s_user   FOR  user.
PARAMETERS: p_sys    TYPE e070-tarsystem,
            p_sys_d  AS CHECKBOX,
            p_layout TYPE slis_vari.

INITIALIZATION.

* Selection screen text elements
  %_s_date_%_app_%-text    = 'Last Changed On'.
  %_s_tran_%_app_%-text    = 'Transport'.
  %_s_obj_%_app_%-text     = 'Program Object type'.
  %_s_obj_n_%_app_%-text   = 'Program Object Name'.
  %_s_tr_st_%_app_%-text   = 'Transport status'.
  %_s_user_%_app_%-text    = 'User'.
  %_p_sys_%_app_%-text     = 'Transport Target of Request'.
  %_s_iflg_%_app_%-text    = 'Transport Import Flag'.
  %_p_layout_%_app_%-text  = 'Output Layout'.
  %_p_sys_d_%_app_%-text   = 'Target System => Source System'.

* Exclude system transports
  s_tran[]  = VALUE #( ( sign = 'I' option = 'CP' low = 'R*' ) ).
* Customer name space filter
  s_obj_n[] = VALUE #( ( sign = 'I' option = 'CP' low = 'Z*' ) ).

* Transport Import Flag range
* w -W request waiting for import
* k -K request waiting for import
* 2 -Request already imported
  s_iflg[]  = VALUE #( sign = 'I' option = 'EQ' ( low = '2' )
                                                ( low = 'k' )
                                                ( low = 'w' ) ).

* Exclude Objects with Header text *Generated test transport
  s_obj_n[] = VALUE #( ( sign = 'I' option = 'CP'   low = 'Z*' )
                         sign = 'E' option = 'CP' ( low = '*Generated*' )
                                                  ( low = 'Import Protection*' ) ).

  IF p_layout IS INITIAL.
    p_layout = '/DEF'.
  ENDIF.

* Get Variant ALV Output
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_layout.
  PERFORM select_layout.

START-OF-SELECTION.

  DATA ev_domain_name TYPE  tmsmconf-domnam.
  DATA ev_system_name TYPE  tmsmconf-sysnam.
* Read system config
  CALL FUNCTION 'TMS_CFG_READ_LOCAL_CONFIG'
    IMPORTING
      ev_system_name = ev_system_name
      ev_domain_name = ev_domain_name.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

* Get ALOG data (Target System)
  IF NOT p_sys IS INITIAL AND NOT s_date IS INITIAL.
    DATA ev_alog_linenr TYPE  flag.
    DATA et_tmstpalog   TYPE  tmstpalogs.
    DATA es_exception   LIKE  stmscalert.
    DATA iv_system      TYPE  tmssysnam.
    iv_system = p_sys(3).
    CALL FUNCTION 'TMS_TM_GET_HISTORY'
      EXPORTING
        iv_system      = iv_system
        iv_domain      = ev_domain_name
        iv_allcli      = 'X'
        iv_imports     = 'X'
        iv_monitor     = 'X'
      IMPORTING
        ev_alog_linenr = ev_alog_linenr
        et_tmstpalog   = et_tmstpalog
        es_exception   = es_exception
      CHANGING
        cv_start_date  = s_date-low
        cv_end_date    = s_date-high
*   EXCEPTIONS
*       ALERT          = 1
*       OTHERS         = 2
      .
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.
  ENDIF. "NOT p_sys IS INITIAL AND NOT s_date IS INITIAL.

  IF NOT s_date IS INITIAL OR NOT s_tran IS INITIAL AND p_sys_d IS INITIAL.
    PERFORM main_transport_data_select.
  ENDIF.
  IF p_sys_d = 'X'.
    DATA s_tran_l LIKE LINE OF s_tran.
    IF NOT et_tmstpalog IS INITIAL.
      IF s_tran[] IS INITIAL.
        LOOP AT et_tmstpalog ASSIGNING FIELD-SYMBOL(<qq>).
          s_tran_l-sign   = 'I'.
          s_tran_l-option = 'EQ'.
          s_tran_l-low    = <qq>-trkorr.
          COLLECT s_tran_l INTO s_tran.
        ENDLOOP.
      ELSE.
        LOOP AT et_tmstpalog ASSIGNING <qq> WHERE trkorr IN s_tran.
          s_tran_l-sign   = 'I'.
          s_tran_l-option = 'EQ'.
          s_tran_l-low    = <qq>-trkorr.
          COLLECT s_tran_l INTO s_tran.
        ENDLOOP.
      ENDIF.
    ENDIF.
    PERFORM main_transport_data_select.
  ENDIF.

END-OF-SELECTION.

* Retrive List of Transport Status values
  DATA dd07v_tab TYPE TABLE OF dd07v.
  CALL FUNCTION 'DDUT_DOMVALUES_GET'
    EXPORTING
      name      = 'TRSTATUS'
      langu     = sy-langu
    TABLES
      dd07v_tab = dd07v_tab.
  SORT dd07v_tab BY domvalue_l.
  IF sy-subrc <> 0.
* error handling here
  ENDIF.

* Import Date (Target System), OSS Note Header Text,
* Transport Status Value
  SORT et_tmstpalog BY trkorr.
  LOOP AT et_transport ASSIGNING FIELD-SYMBOL(<rr>).
    READ TABLE et_tmstpalog ASSIGNING FIELD-SYMBOL(<tt>)
    WITH KEY trkorr = <rr>-trkorr BINARY SEARCH.
    IF sy-subrc = 0.
      <rr>-prod      = p_sys(3).
      <rr>-impdat_ts = <tt>-trtime(8).
    ENDIF.
* Populate Header text for Transport Object 'NOTE'
    IF <rr>-object = 'NOTE' AND <rr>-obj_name(10) CO '0123456789'.
      <rr>-obj_name+11 = <rr>-stext.
    ENDIF.
* Populate Transport Status Value
    READ TABLE dd07v_tab ASSIGNING FIELD-SYMBOL(<st>)
    WITH KEY domvalue_l(1) =  <rr>-trstatus BINARY SEARCH.
    IF sy-subrc = 0.
      <rr>-ddtext = <st>-ddtext.
    ENDIF.
  ENDLOOP.

  IF NOT et_transport IS INITIAL.

* Read Target System Transport History Log
    DATA tt_buffer_prod       TYPE TABLE OF tmsbuffer.
    DATA ev_collect_date      TYPE sy-datum.
    DATA iv_expiration_date   TYPE tmsactdat-actdat.
    DATA i_sys                TYPE tmscsys-sysnam.

    i_sys = sy-sysid.

    CALL FUNCTION 'TMS_MGR_READ_TRANSPORT_QUEUE'
      EXPORTING
        iv_system          = i_sys
        iv_domain          = ev_domain_name
        iv_collect_data    = 'X'
        iv_expiration_date = iv_expiration_date
      IMPORTING
        ev_collect_date    = ev_collect_date
      TABLES
        tt_buffer          = tt_buffer_prod.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

    TYPES: BEGIN OF prog_object,
             obj_name TYPE tadir-obj_name,
           END OF prog_object.
    DATA  prog_object TYPE SORTED TABLE OF prog_object WITH UNIQUE KEY obj_name.
    DATA  clas_object TYPE SORTED TABLE OF prog_object WITH UNIQUE KEY obj_name.
    DATA  func_object TYPE SORTED TABLE OF prog_object WITH UNIQUE KEY obj_name.
    DATA  ls_object   LIKE LINE OF prog_object.
*
    DATA s_obj_name TYPE RANGE OF tadir-obj_name.
    s_obj_name[] = VALUE #(   sign = 'I' option = 'CP' ( low = 'ZCL*'  )
                                                       ( low = '*/CL*' )
                                                       ( low = 'CL*' ) ).
*
    LOOP AT et_transport ASSIGNING <rr>.
* Check status of transport in target system (if exist) transport log
      LOOP AT tt_buffer_prod ASSIGNING FIELD-SYMBOL(<tt_buffer>)
        WHERE trkorr EQ <rr>-trkorr AND
              impflg IN s_iflg.
      ENDLOOP.
      IF sy-subrc = 0.
        <rr>-prod = p_sys.
      ENDIF.
* Create PROG Objects index
      IF ( <rr>-object EQ 'PROG' OR <rr>-object = 'REPS' ).
        ls_object-obj_name = <rr>-obj_name.
        COLLECT ls_object INTO prog_object.
      ENDIF.
      IF <rr>-obj_name IN s_obj_name.
        ls_object-obj_name = <rr>-obj_name(30).
        COLLECT ls_object INTO clas_object.
      ENDIF.
      IF ( <rr>-object EQ 'FUNC' ).
        ls_object-obj_name = <rr>-obj_name.
        COLLECT ls_object INTO func_object.
      ENDIF.
*
    ENDLOOP.
* Collect Program Object description
* Program Object types: PROG, REPS
    IF NOT prog_object IS INITIAL.
      SELECT name, text FROM trdirt
        INTO TABLE @DATA(prog_desc)
        FOR ALL ENTRIES IN @prog_object
        WHERE name     EQ @prog_object-obj_name     AND
              sprsl    EQ @sy-langu.
    ENDIF.
* Program Object type CLAS
    IF NOT clas_object IS INITIAL.
      SELECT clsname, descript FROM vseoclass
        INTO TABLE @DATA(clas_desc)
        FOR ALL ENTRIES IN @clas_object
        WHERE clsname  EQ @clas_object-obj_name(30) AND
              langu    EQ @sy-langu.
    ENDIF.
* Program Object type FUNC
    IF NOT func_object IS INITIAL.
      SELECT funcname, stext FROM tftit
        INTO TABLE @DATA(func_desc)
        FOR ALL ENTRIES IN @func_object
        WHERE funcname EQ @func_object-obj_name(30) AND
              spras    EQ @sy-langu.
    ENDIF.
* Add Program Object description
    LOOP AT et_transport ASSIGNING <rr>.
      READ TABLE prog_desc ASSIGNING FIELD-SYMBOL(<prog_desc>)
      WITH KEY name = <rr>-obj_name.
      IF sy-subrc = 0.
        <rr>-stext = <prog_desc>-text.
      ENDIF.
      READ TABLE clas_desc ASSIGNING FIELD-SYMBOL(<clas_desc>)
      WITH KEY clsname = <rr>-obj_name.
      IF sy-subrc = 0.
        <rr>-stext = <clas_desc>-descript.
      ENDIF.
      READ TABLE func_desc ASSIGNING FIELD-SYMBOL(<func_desc>)
      WITH KEY funcname = <rr>-obj_name.
      IF sy-subrc = 0.
        <rr>-stext = <func_desc>-stext.
      ENDIF.
    ENDLOOP.
* ALV Output
    PERFORM output USING et_transport 'et_transport' .
  ENDIF.
*&---------------------------------------------------------------------*
*& Main Transport Data Selection
*&---------------------------------------------------------------------*
FORM main_transport_data_select.
  SELECT a~trkorr, a~trfunction, a~trstatus, c~as4text, a~tarsystem,
         a~korrdev, a~as4user, a~as4date, a~strkorr,
         b~as4pos, b~pgmid, b~object, b~obj_name, b~objfunc,
         b~lockflag, b~activity, d~devclass, e~stext
  FROM e070 AS a
  INNER JOIN e071     AS b ON a~trkorr    = b~trkorr
  INNER JOIN e07t     AS c ON c~trkorr    = a~trkorr
  LEFT JOIN tadir     AS d ON d~obj_name  = b~obj_name
  LEFT JOIN cwbntstxt AS e ON e~numm      = b~obj_name AND
                              e~langu     = @sy-langu
  INTO TABLE @et_transport
  WHERE a~as4date  IN @s_date  AND
        a~trkorr   IN @s_tran  AND
        a~trstatus IN @s_tr_st AND
        a~as4user  IN @s_user  AND
        b~object   IN @s_obj   AND
        b~obj_name IN @s_obj_n.
ENDFORM.
*&---------------------------------------------------------------------*
*& ALV Output
*&---------------------------------------------------------------------*
FORM output USING p1 p2.
  DATA: o_alv         TYPE REF TO cl_salv_table,
        key           TYPE salv_s_layout_key,
        lo_msg        TYPE REF TO cx_salv_msg,
        lo_layout     TYPE REF TO cl_salv_layout,
        lo_columns    TYPE REF TO cl_salv_columns_table,
        lo_column     TYPE REF TO cl_salv_column_table,
        lo_functions  TYPE REF TO cl_salv_functions_list,
        lo_selections TYPE REF TO cl_salv_selections,
        lo_display    TYPE REF TO cl_salv_display_settings.
  TRY.
      cl_salv_table=>factory( IMPORTING r_salv_table = o_alv
                              CHANGING  t_table      = p1 ).
    CATCH cx_salv_msg INTO lo_msg.
  ENDTRY.
  lo_functions  = o_alv->get_functions( ).
  lo_functions->set_all( abap_true ).
  lo_columns    = o_alv->get_columns( ).
* Set Column TRKORR Color
  DATA: color TYPE lvc_s_colo.
  TRY.
      lo_column ?= lo_columns->get_column( 'TRKORR' ).
      color-col = '4'.
*     color-int = '1'.
*     color-inv = '0'.
      lo_column->set_color( color ).
    CATCH cx_salv_not_found.
  ENDTRY.  
  lo_columns->set_optimize( abap_true ).
  lo_layout     = o_alv->get_layout( ).
  key-report    = sy-repid.
  lo_layout->set_key( key ).
  lo_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).
  lo_layout     = o_alv->get_layout( ).
  lo_selections = o_alv->get_selections( ).
  lo_selections->set_selection_mode( if_salv_c_selection_mode=>row_column ).
  lo_layout->set_default( abap_true ).
  lo_display = o_alv->get_display_settings( ).
  DATA date_range TYPE lvc_title.
  DATA: fr TYPE char10, to TYPE char10.
  PERFORM get_ext_date USING s_date-low  CHANGING fr.
  PERFORM get_ext_date USING s_date-high CHANGING to.
  IF p_sys_d = 'X'.
    DATA(dir) = 'Target System => Source System'.
  ENDIF.
  date_range = 'Last Changed On:' && fr  && ' - ' && to && | | && dir.
  lo_display->set_list_header( date_range ).
* Set Variant of ALV
  lo_layout->set_initial_layout( p_layout ).
  o_alv->display( ).
ENDFORM.
*&---------------------------------------------------------------------*
*& ALV Output: Get Variant
*&---------------------------------------------------------------------*
FORM select_layout.
  DATA: ls_layout_key  TYPE salv_s_layout_key,
        ls_layout_info TYPE salv_s_layout_info.
  ls_layout_key-report = sy-repid.
  ls_layout_info = cl_salv_layout_service=>f4_layouts( ls_layout_key ).
  p_layout = ls_layout_info-layout.
ENDFORM.
*&---------------------------------------------------------------------*
*& Convert Internal Date to External Date
*&---------------------------------------------------------------------*
FORM get_ext_date USING p1 CHANGING p2.
  CALL FUNCTION 'CONVERT_DATE_TO_EXTERNAL'
    EXPORTING
      date_internal = p1
    IMPORTING
      date_external = p2.
ENDFORM.

Selections screen

 

When Check Box Target System => Source system = X

Transport History Log of Target system become main index of transports.

Output

When Transport has been moved to Target System.

For Object Type = NOTE

The first run with filter by object type ‘NOTE’ returns the list of transports with List of implemented Notes, the second run could be for particular transport or range transports with OSS Note objects.

List of objects for OSS Note 2399707 Simplification Item Check

Conclusion

The report lists the objects released into next system and date when transport promoted to Production, it also shows the objects that are still in development and as well in the handling transport queue.

Assigned Tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michelle Crapo
      Michelle Crapo

      Nice first blog.  Keep blogging!

      Although it "sounded" like one that I had read before, it really isn't.

      There are a lot of ways to get something similar to this blog with different functionality.  I'm going to add a couple here.

      An add to this - it is not duplicating this at all but since we are on the subject of transports:

      transport tracking made easier.

      Something to think about

      You might also want to run a search in github.com.   There are some nice ones out there.  There is this on about dependencies.   It just depends on what you are looking for.

       

      Author's profile photo Vlad Kustov
      Vlad Kustov
      Blog Post Author

      Hi Michelle

      Thank you for links. for transport tracking I am looking for something simple

      This is simple report with one SQL only. On 'release' time with this report I was able to find answers for some questions about transport content and target 'Import Date' during development release time.

      Vlad

      Author's profile photo Michelle Crapo
      Michelle Crapo

      Perfect. That makes a lot of sense

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Nice, but "(Used syntax ABAP 7.52)" is only partially true. You've got a lot of obsolete keywords in your code - like TABLES, FORM,...  If you use SORTED/HASHED tables, then you don't need binary search.

      You can replace

        s_obj_n-option = 'CP'.
        s_obj_n-sign   = 'I'.
      * Customer name space filter
        s_obj_n-low    = 'Z*'.
        APPEND s_obj_n.

      With

      s_obj_n = VALUE #( ( sign = 'I' option = 'CP' low = 'Z*' ) ).

       

       

      Author's profile photo Vlad Kustov
      Vlad Kustov
      Blog Post Author

      Hi Matthew,
      Thank you for comments.

      If in TABLES statement table not declare then SELECT-OPTIONS declaration for this table stop working (not always but ...) .

      Not sure syntax s_obj_n = VALUE #( ( sign = 'I' option = 'CP' low = 'Z*' ) ) will work for select-options table.

      For Function Call,  EXPORT data declaration taken from called Function interface AS-IS. (This is About 'Sorted Table' declaration)

      Syntax FORM is absolute but still work and will work, for some cases this option give me simple option for code modularization.

      Thank you again.

      Vlad

       

      Author's profile photo Sandra Rossi
      Sandra Rossi

      SELECT-OPTIONS only requires a global variable for typing the selection table. You may declare a global variable with DATA. TABLES is not required at all for this.

      s_obj_n[] will work:

      s_obj_n[] = VALUE #( ( sign = 'I' option = 'CP' low = 'Z*' ) ).

       

      Author's profile photo Michał Badura
      Michał Badura

      Or even better a constant with initial value.

      Author's profile photo Vlad Kustov
      Vlad Kustov
      Blog Post Author

      Hi Sandra,

      Thank you for comment, it's works.

      Kind Regards

      Vlad