Skip to Content

Introduction

Did you ever get the request to ‘quickly check the transport list’ two days before Go-Live?

Only to discover that the list has hundreds of transports with thousands of objects?

And after going through the first few transports you find out that the list is a mess. Checking one object will indicate other transports that are not in the list, or transports that are ‘not needed anymore’ but with changes that were never rolled back, or emergency transports already in production… Etc. etc.

So how do you check the list? You know that there is no way that this list of transports can go to production without issues. Clearing up the mess is impossible, takes too long or is too costly.

There will be issues, but which? How serious will they be?

The next question you’ll get is ‘What is the risk?’. Do you dare to answer ‘The system could go KABOOOM’?

 

Yes, most issues can be prevented if the responsible user is careful when creating transports and organizes them properly before releasing them. However, nobody’s perfect. Mistakes will be made and corners will be cut. When the pressure from above increases, strict rules suddenly become flexible.

 

Some possible risks:

  • Loss of functionality in production (if a newer transport is overwritten),
  • Moving untested code to production (if an older transport exists for the same object, that is not included in the transport list),
  • Objects use DDIC objects that are in Development and Acceptance, but NOT in production (causing dumps),
  • After the list has been transported, different versions are active in Production and Acceptance.

 

In the past I ran into this problem. I had to check a list of transports for a project that lasted over a year. Multiple developers worked on it and each delivered a list of transports. This I had to check… I encountered so many problems that I decided to write a small program that would check for older and newer transports of all objects used and then give warnings. The program was far from perfect, but it did the trick. The project from hell went live with only minor issues. That was several years ago. Since that time the program has grown. More checks and functions were implemented.

 

I do not have the illusion that it is perfect. I tried to make it as flexible as possible, but there is always room for improvement.

 

Logo3.jpg

But if there are people who may have use for a tool like this, they can check it out and download it from Github: Transport Checking Tool (Object level). It is a local program, available as a SAPLINK nugget, that only has program text and documentation.

It does not make changes to the database, but runs as a straightforward report. The only thing the program can create, is transport documentation, if the user decides to do so. What the program aims to do is to highlight possible risks, allowing the user to add or remove transports and eventually produce a list of transport requests that can be moved to production with minimal or no conflicts.

 

Possible Limitations

This tool was written to be used in SAP ERP. The Transport Checking Tool uses Data Dictionary objects that existed in the system it was developed in. Of course, which DDIC types exist can be release dependant. All the Data Dictionary objects that I have used, should be available in the system the Transport Checking Tool is imported in. If not, a programmer will have to modify the program to correct this.

 

Description of the Tool

Below is a short description of the tool, input, output and functionality. For more detailed information, please have a look at the User Manual on Code Exchange.

 

Selection Screen

This is what the selection screen looks like:

SelectionScreen.jpg

Output

This screenshot is an example of the output.

Example_Output_Left.png

Interesting is the Application toolbar, which has buttons to:

  • Recheck selected rows,
  • Activate the DDIC check,
  • Add transports conflicting with selected rows,
  • Add a single transport,
  • Add another saved file (merge lists),
  • Remove selected transports (if you select one row, all rows for that transport will be removed)
  • Mark a transport that is in Production for Re-transport,
  • Jump to the next relevant Conflict,
  • Build a simple list (on header level, unique transport numbers only, no Object information).

 

Example

When a warning is given, the user can click on the warning icon. Let’s have a look at the example displayed below:

ExampleCheckWarning.jpg

There is a warning (yellow triangle, stating that there is a previous version that is not in your list. Double-clicking on the icon will display the following popup:

ExampleCheckWarningPopup.jpg

Here you can see which transport was missed and it also becomes clear why. Another user changed this object as well. And now it becomes interesting. There are two options:

  1. You decide to add the transport to your list (click Okay). The other user’s transport is added to the list.
  2. You decide to go ahead without adding the transport (click Cancel). The list remains the same.

 

By clicking on the Okay icon, the selected transport will be added to your list. It would be nice if at this point you contact the user first, to ask if his transport can go to production or not (for obvious reasons, I hope). The transport of the other user will most likely contain other objects too…

But also if you choose NOT to add the transport you will still need to communicate the situation. The reason why you should communicate in the latter case, is that by moving only your transport, the changes of the other user made to this object will be transported with it. And if the other user later decides to move his changes, yours will be overwritten. Note that if the other user checks his transport list, he will see an error icon with the message that a newer version will be overwritten. The reason for that error message will be you…

 

The golden rule here is to COMMUNICATE.

 

Transport sequence: order and disorder

The order in which the transports should be moved to production is the order in which they were imported in the Acceptance environment.

This guarantees that the versions in Production will be the same as the versions in Acceptance at the time the User Acceptance Test was performed and signed off.

Determining the transport order is straightforward enough. The complicating factor will be other transports in acceptance, containing one or more objects that are the same as objects in your list.

These conflicting transports may belong to other projects or other people. Maybe those transports cannot yet go to production (code is untested) or may already have been transported to production (as emergency transports).

 

In general it is not the process to determine the transport sequence that will cause problems, but other transports that will cause disruptions to your list.

 

Preventing that these issues and risks arise is always better than trying to solve them. It all starts with a good understanding of which objects should be grouped together in the same transport and which objects should be transported separately.

 

The Developer or Functional consultant should always be very alert for these considerations.

As a rule, User-Exits should always be transported separately. The same rule would apply for DDIC elements that can/will be used in multiple objects.

Other considerations would be if the complete function group needs to be transported or only a single function. Should the complete Class be transported or only the implementation of a method? Should the complete program (including texts and documentation) be transported or only the Report code?

 

Keeping the transport list clean and simple may prevent a lot of hair-pulling later on.

 

Risks when transporting to Production

When transports are moved to production, there are several possible risks. The chance, severity and impact of issues on the system will increase with the number of transports involved and the number of objects in these transports.

Other complicating factors are the number of developers working on the same project, the runtime of the project, developers working on the same objects, transports being moved in case of production issues (disrupting the alignment) etc. etc.

Frequent problems encountered when NOT using a transport checking tool are described in the next two paragraphs.

 

Objects overwrite newer versions already in Production

Result: loss of recent changes/functionality.

OvershootingATransport.jpg

 

Objects go to Production with previous versions in Acceptance

Result: unwanted (or even incorrect) changes go to Production without being signed off.
Code can also contain data elements that are not yet in production. The used/required data elements might exist in Acceptance, in another transport, but not yet in Production. When developing and testing there will be no syntax error. There will be no warning at all because the data element exists in Development and Acceptance. Only after the transport to production has been done, dumps will occur.

RiskIgnoringPreviousVersions.jpg

 

Conclusion

In the end, the real trick is to be careful in the beginning. Check before releasing transports in the Development system. Organize them properly and try to think ahead. This prevents a lot of problems. But even so, it will always be necessary to check the transports that go to the Production system before actually moving them.

 

To do this, a transport checking tool will come in handy.

Still, keep in mind that the responsibility for the transports lies with the developers and the functional consultants who created them and who added the objects to them. They will have the best understanding of what was changed and why.

 

There isn’t a tool that can take away that responsibility and there isn’t a tool that a user can execute to analyze the problems and that comes with a ‘Fix errors’ button…

To report this post you need to login first.

30 Comments

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

  1. Fred Verheul

    Hi Edwin,

    Great to not only see you sharing code on code_exchange, but to see you also blogging here on SCN to explain what the tool does and what problems (and we both know these are very real problems 🙂 ) it solves.

    Looking forward to more valuable content…

    Cheers, Fred

    (0) 
  2. Nicolas Busson

    Hi Edwin,

    Thanks a lot for mentioning the Transport-Request-Dependencies-Analyzer: I’m still looking forward to testing ZTCT… and that will probably be a good idea to see if we can “merge” our programs together in the near future to give birth to the ultimate transport-issue-killer 😉 .

    Cheers,

    Nick.

    (0) 
  3. Jens Schwarz

    Hi Edwin,

    thanks a lot for the great tool!

    I have one hint for you and others using the tool.

    The tool ran very slow checking the object dependecies in table E071. So I created an index on table e071 with fields OBJECT and OBJ_NAME.

    The tool runs much faster now.

    Regards.

    Jens

    (0) 
    1. Edwin Vleeshouwers Post author
      Thanks Jens, it’s a good idea, and something I can add in the documentation as a tip to improve performance.  I never did this because I wanted the program to run as-is. Without making any additional changes to the development system of the customer. That is also the reason why it is a stand-alone program instead of classes. It makes it easier to implement and to remove…  But yes, an index is definately a great option! Thanks!
      (0) 
  4. Abdellatif EL GUAOUZI

    Hello,

    Thanks a lot for this wonderful post but all links are now inactive with the new “code exchange” url. Did you remove the abap or is it still available somwhere ?

    Thanks in advance,

    Best Regards,

    Cyril.

    (0) 
  5. Edwin Vleeshouwers Post author

    Thanks!

    I have updated the links…

    To be honest I do not know if I will ever be able to put the Nugget on any SCN CW again.

    Too much hassle regarding legal rights. Hosting ABAP Open sourceon a SAP site seems to be really difficult.

    (0) 
  6. Ricardo Monteiro

    Hello Edwin..

    This is a very helpful tool, but just one question:

    The tool just checks released transport requests ?

    I say this because i tried every transport request i have, and only those already released are found. All the others i get the message of no data found. I gather the “problem” is in selection JOIN of E070 to E071 that the requests are not found in E071.

    Thanx,

    Ricardo

    (0) 
    1. Edwin Vleeshouwers Post author

      Yes, only transports that have been released. The purpose of this tool is to check the transports that are in the acceptance environment before moving them to production.

      Transports that are not released and only exist in development, are not meant to go to production yet.

      The goal is that after the transports have been moved to production, the situation in production is exactly as it was in acceptance. That is the situation that was tested and approved by the test team (if there is one…).

      (0) 
  7. Martin Maruskin

    Just a hint for people installing this tool. Once you import nugget as instructed you may get an ABAP dump (UNCAUGHT_EXCEPTION CX_SALV_OBJECT_NOT_FOUND CL_SALV_MODEL_BASE) while you attempt to run the t-code/report.

    To fix this just browse for inactive ABAP objects. Go to SE38->ZEV_TP_CHECKTOOL and activate all inactive objects.

    hope this helps someone who face the dump.

    cheers

    m./

    (0) 
    1. Manish Kumar

      That is due to feature of SAPLink. It leaves the stuff inactive so that you can manually verify the contents of nugget before activating it.

      (0) 
  8. Jens Schwarz

    Hi Edwin,

    we realized that the tool is getting slower and slower processing many tps. The reason is that the function module  “TMS_MGR_READ_TRANSPORT_REQUEST” is called many times and this also for the same tps.

    We modified your report to buffer the results of the function module.

    Before we call the fm we read the buffer table and look if there is an entry.

    The buffer table look slike this:

    TYPES: BEGIN OF ty_tms_mgr_buffer,

                request        TYPE  tmsbuffertrkorr,

                target_system  TYPE  tmscsyssysnam,

                request_infos  TYPE  stms_wbo_requests,

                END   OF ty_tms_mgr_buffer.

         TYPES: tt_tms_mgr_buffer TYPE HASHED TABLE OF ty_tms_mgr_buffer

                                   WITH UNIQUE KEY request target_system.


    DATAtms_mgr_buffer             TYPE tt_tms_mgr_buffer.

         DATAtms_mgr_buffer_line        TYPE ty_tms_mgr_buffer.


    There are different places where the fm is called. We replaced every call with

    the following:

    READ TABLE tms_mgr_buffer INTO tms_mgr_buffer_line

                    WITH TABLE KEY request          = ls_newer_linetrkorr

                                   target_system    = lp_target.

               IF sysubrc = 0.

                 ta_stms_wbo_requests = tms_mgr_buffer_linerequest_infos.

               ELSE.

                 CALL FUNCTION ‘TMS_MGR_READ_TRANSPORT_REQUEST’

                   EXPORTING

                     iv_request                 = ls_newer_linetrkorr

                     iv_target_system           = lp_target

                     iv_header_only             = ‘X’

                     iv_monitor                 = ‘ ‘

                   IMPORTING

                     et_request_infos           = ta_stms_wbo_requests

                   EXCEPTIONS

                     read_config_failed         = 1

                     table_of_requests_is_empty = 2

                     system_not_available       = 3

                     OTHERS                     = 4.

                 IF sysubrc <> 0.

                   MESSAGE ID symsgid TYPE symsgty NUMBER symsgno

                           WITH symsgv1 symsgv2 symsgv3 symsgv4.

                 ENDIF.

                 tms_mgr_buffer_linerequest       = ls_newer_linetrkorr.

                 tms_mgr_buffer_linetarget_system = lp_target.

                 tms_mgr_buffer_linerequest_infos = ta_stms_wbo_requests.

                 INSERT tms_mgr_buffer_line INTO TABLE tms_mgr_buffer.

               ENDIF.

    Maybe you can check our modification and – if you like it – put in the the standard coding so we do not need to modify the report again if there is a new version.

    Thanks and regards

    Jens

    (0) 
  9. Pallavi Bhattacharyya

    I am trying to upload the nugget file that i downloaded from GIThub using program ZSAPLINK but i get the error ‘Plugin for object type TRAN is not installed on this system’. Which plugin do i need to install from SAPLINK for this upload? i have the plugin for Transactions but that did nbot help.

    Thanks,

    Pallavi.

    (0) 
  10. Mel Calucin

    Hi Edwin,

    Thank you for creating this program.

    I want to use this program on a SAP BW system, but it looks like this code is meant for R/3.  Lines 2022 and 2023 references the structure ‘UGMD_S_STOP_CONDITION’ and structure element ‘NUMBER_OF_RESULTS’.   The structure does not exist at all in BW.  Is it OK just to comment this section out?


    Thanks again.

    Regards,

    Mel Calucin

    (0) 
  11. David Knittle

    it seems no matter which options i choose, i see “No  transports found”. When released, our transports are automatically imported into QAS. Could this be a problem? I would like to try the tool, but it is not finding any of my transports whether they are released or not.

    (0) 
  12. Franck Bargmann

    Can anyone give me an help

    I tried to install SAPLINK then the Nugget file for ZTCT and I received too a message :

    “Plugin for object type TRAN is not installed on this system”

    Can anyone  tell me where to download this plugin on the web please ?

    Regards

    Franck

    (0) 
    1. Derek Barrett

      Hi Franck,

      I see this issue posted around online in a few places. I have also searched for TRAN but have had no luck.

      The best I could come up with was this thread, where it referred to “Transactions,” but I don’t think that’s it:

      SAPlink User Documentation

      To the original author, do you know where we can find the TRAN plugin for ZSAPLINK?

      I also tried installing all the plugins but no luck either:

      If anyone knows where the TRAN plugin is hiding, please let us know.

      Thanks,

      Derek

      (0) 
    2. Derek Barrett

      Okay I solved the issue It is probably intuitive for ABAPers, maybe not so much for a non developer (I’m Basis/DBA/Systems)

      Transactions is indeed the right plugin (TRAN), but after you install it with SAPLINK, you have to go activate the class in se80

      The class name is ZSAPLINK_TRANSACTIONS

      Once you do that, you’re good to go

      (0) 
        1. L. Niekerk, van

          I skipped the TRAN bit via debugging, is not needed anyway, you can add the transaction manually when needed.
          You could also remove the TRAN bit from the nugg XML file..

          (0) 
  13. Pablo Casamayor

    Thanks Edwin for this very helpful tool!

    as a  far from perfect developer i highly appreciate your contribution and thank you for this blog!

    (thanks for caring about others)

    Best regards,

    Pablo

    (0) 
  14. Tum Sem

    Hi Edwin,

    I installed your program using Saplink.

    Now the program dumps on “Error when reading from file “/usr/sap/trans/cofiles/.”

    Stack is

    6 FUNCTION STRF_READ_COFILE                                SAPLSTRF

    5 FUNCTION TR_READ_GLOBAL_INFO_OF_REQUEST  SAPLTR_LOG_OVERVIEW

    4 METHOD   GET_IMPORT_DATETIME_QAS                ZEV_TP_CHECKTOOL

    3 METHOD   CHECK_FOR_CONFLICTS             ZEV_TP_CHECKTOOL

    2 METHOD   EXECUTE                                   ZEV_TP_CHECKTOOL

    1 EVENT     END-OF-SELECTION                ZEV_TP_CHECKTOOL

    Thanks in advance

    Tum

    (0) 
  15. Stephane Gregoire

    Nice tool!

    There is an issue when the CTSPROJECT table is empty. 

    Existing logic:


     *   Create a range table containing all project transport numbers.
    *   When selecting transports, these can be skipped.
    st_project_trkorrssign ‘I’.
    st_project_trkorrsoption ‘EQ’.
    SELECT trkorr FROM ctsproject
    INTO st_project_trkorrslow.        “#EC CI_SGLSELECT
    APPEND st_project_trkorrs TO me->project_trkorrs.
    ENDSELECT.

     

    I solved adding this logic:

    *   IF the CTSPROJECT table is empty, then create a dummy entry
    *   to avoid all the transport to be excluded in the select with the syntax:
    *       NOT trkorr IN  me->project_trkorrs
    IF me->project_trkorrs[] IS INITIAL.
       APPEND st_project_trkorrs TO me->project_trkorrs.
    ENDIF.

     

     

    (0) 

Leave a Reply