ABAP – Export Transport request to local file system

SAPAll development or customizing in SAP is written into a transport request unless it is a local object not intended to be transported ($TMP package). Sometimes it might be useful to backup your development but in SAP this task is quite complicated to export all programs, classes, standard texts, …

Therefore there is an option to export the whole development encapsulated on a transport request level. And that’s what this article is about – exporting development encapsulated in a transport request to local file system.

Export of the whole transport is possible either manually(see Manual export) or using your own program (see Automatic export)

Manual Export

  1. Note down the name of your transport

    The name of transport request you are going to backup is in format XXXKYYYYYY (e.g. A1DK012ABC).You can find your transports using TCode SE09.

  2. Find the transfer directory of the SAP system

    Transport request consists of two parts:

    • one header field (co-file)
    • one body file (data-file)

    Once a transport is released, these files are written on SAP file system. To be able to download them, it’s necessary to know the path on SAP file system where they are placed.

    Using TCode AL11 you can access the directory parameters on your SAP system.

    The transport directory can be found under “Directory Parameter” called DIR_TRANS – note down the corresponding “Directory” (e.g. \usr\sap01\saptrans).

    The header and body files are stored in different directories on the server:

    • If you display details of the DIR_TRANS entry (double click on it) it shows its content.
      The entries we are looking for are two sub-directories called “cofiles” and “data”.
    • The header file with the naming syntax like KYYYYYY.XXX (e.g. K012ABC.A1D) should be placed in directory cofiles (double click to open the directory) .Now you have the cofiles directory (e.g. \usr\sap01\saptrans\cofiles) and the header file name (e.g. K012ABC.A1D)
    • Similarly you will find the body file of your transport in sibling directory data (e.g. \usr\sap01\saptrans\data) and the file name with prefix ‘R’ (e.g. R012ABC.A1D)

    If the files and directories mentioned above can’t be found, either there are different sub-directories defined in your system for transports or the transport request release failed.

  3. Download the files

    To download the two files mentioned in previous steps from SAP application server to local file system you can use the standard function module ARCHIVFILE_SERVER_TO_CLIENT which can be called/executed from TCode SE37.

    It takes two importing parameters:

    • source path including the file name (path to file on SAP file system)
    • target path (directory on the local file system where the downloaded file will be placed to)

    This means you have to call this FM twice – first to get the transport request header file and second to get the body file. These files can subsequently be used to be imported to another SAP system (this requires special authorization – most probably not granted to basic users/developers)

If such backup action needs to be performed more often or even needs to be automated it might be good idea to write own program for it – such program is available in the next section.

Automatic Export

Using the report code below you can automatically export desired list of transports to your local file system

REPORT  export_transports.

CLASS lcl_transport_export DEFINITION DEFERRED.

*-----------------------------------------------------------------*
*       CLASS lcl_transport_export DEFINITION
*-----------------------------------------------------------------*
CLASS lcl_transport_export DEFINITION.
  PUBLIC SECTION.
    TYPES:
      rng_transports TYPE RANGE OF trkorr.
    METHODS:
      execute
      IMPORTING
        e_output_path TYPE string
        et_transports TYPE rng_transports.

    CLASS-METHODS:
      transport_on_f4
        RETURNING value(result) TYPE trkorr,
      output_path_on_f4
        RETURNING value(result) TYPE string,
      class_constructor.

  PRIVATE SECTION.
    CONSTANTS:
      gc_data_path         TYPE string VALUE 'data',
      gc_cofiles_path      TYPE string VALUE 'cofiles',
      gc_trp_released      TYPE c        VALUE 'R',
      gc_dot               TYPE c        VALUE '.',
      gc_slash_win         TYPE c        VALUE '\',
      gc_slash_lin         TYPE c        VALUE '/',
      BEGIN OF gc_trp_type,
        cofile     TYPE c VALUE 'K',
        datafile   TYPE c VALUE 'R',
      END OF gc_trp_type.

    CLASS-DATA:
      g_trp_dir TYPE char255.

    DATA:
      m_output_path   TYPE string,
      mrng_transports TYPE rng_transports,
      mt_transports   TYPE TABLE OF e070.

    METHODS:
      check_status,
      check_directory,
      download
        IMPORTING
          e_transport TYPE e070
          e_type      TYPE c.
ENDCLASS.                    "lcl_transport_export DEFINITION

*-----------------------------------------------------------------*
*       CLASS lcl_transport_export IMPLEMENTATION
*-----------------------------------------------------------------*
CLASS lcl_transport_export IMPLEMENTATION.
  METHOD class_constructor.
    CALL 'C_SAPGPARAM' ID 'NAME' FIELD 'DIR_TRANS' ID 'VALUE' FIELD g_trp_dir.
  ENDMETHOD.                    "class_constructor

  METHOD execute.
    FIELD-SYMBOLS:
      <fs_transport> TYPE e070.

    me->m_output_path   = e_output_path.
    me->mrng_transports = et_transports.

    me->check_status( ).
    me->check_directory( ).
    IF me->mt_transports[] IS NOT INITIAL.
      LOOP AT mt_transports ASSIGNING <fs_transport>.
        me->download(
          EXPORTING
            e_transport = <fs_transport>
            e_type      = gc_trp_type-cofile
          ).
        me->download(
          EXPORTING
            e_transport = <fs_transport>
            e_type      = gc_trp_type-datafile
        ).
      ENDLOOP.
    ENDIF.
  ENDMETHOD.                    "execute

  METHOD transport_on_f4.
    CALL FUNCTION 'TR_F4_REQUESTS'
      EXPORTING
        iv_trstatus         = gc_trp_released
      IMPORTING
        ev_selected_request = result.
  ENDMETHOD.                    "transport_on_f4

  METHOD output_path_on_f4.
    DATA:l_selected_folder TYPE string.

    CALL METHOD cl_gui_frontend_services=>directory_browse
      CHANGING
        selected_folder      = l_selected_folder
      EXCEPTIONS
        cntl_error           = 1
        error_no_gui         = 2
        not_supported_by_gui = 3
        OTHERS               = 4.

    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    result = l_selected_folder.
  ENDMETHOD.                    "output_path_on_f4

  METHOD check_status.
    DATA:
      lt_e070 TYPE TABLE OF e070 .
    FIELD-SYMBOLS:
      <fs_e070> LIKE LINE OF lt_e070.
    SELECT * INTO TABLE mt_transports FROM e070  WHERE trkorr IN me->mrng_transports.
    IF sy-subrc = 0.
      LOOP AT mt_transports ASSIGNING <fs_e070>
        WHERE trstatus NE gc_trp_released.
        WRITE:/ 'Transport ', <fs_e070>-trkorr, ' not exported because it is not released'.
        DELETE mt_transports WHERE trkorr = <fs_e070>-trkorr.
      ENDLOOP.
    ELSE.
      MESSAGE 'No suitable transport exists'(001) TYPE 'E'.
    ENDIF.
  ENDMETHOD.                    "check_status

  METHOD check_directory.
    DATA:
      l_result TYPE c,
      l_directory TYPE string.

    l_directory = me->m_output_path.

    CALL METHOD cl_gui_frontend_services=>directory_exist
      EXPORTING
        directory            = l_directory
      RECEIVING
        result               = l_result
      EXCEPTIONS
        cntl_error           = 1
        error_no_gui         = 2
        wrong_parameter      = 3
        not_supported_by_gui = 4
        OTHERS               = 5.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

    IF l_result IS INITIAL.
      MESSAGE 'The output directory does not exist!'(002) TYPE 'E'.
    ENDIF.
  ENDMETHOD.                    "check_directory

  METHOD download.
    DATA:
      l_dummy       TYPE string,
      l_path        TYPE saepfad,
      l_targetpath  TYPE saepfad,
      l_ot_filename TYPE string.

    CONCATENATE e_type e_transport-trkorr+4(6) gc_dot e_transport-trkorr(3) INTO l_ot_filename.
    CASE e_type.
      WHEN gc_trp_type-cofile.
        l_path = |{ me->g_trp_dir }{ gc_slash_lin }{ gc_cofiles_path }{ gc_slash_lin }|.
      WHEN gc_trp_type-datafile.
        l_path = |{ me->g_trp_dir }{ gc_slash_lin }{ gc_data_path }{ gc_slash_lin }|.
    ENDCASE.

    l_path = |{ l_path }{ l_ot_filename }|.
    l_targetpath = |{ m_output_path }{ gc_slash_win }{ e_transport-trkorr }{ gc_slash_win }{ l_ot_filename }|.
    CALL FUNCTION 'ARCHIVFILE_SERVER_TO_CLIENT'
      EXPORTING
        path       = l_path
        targetpath = l_targetpath
      EXCEPTIONS
        error_file = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO l_dummy.
    ELSE.
      l_dummy = |Transport { e_transport-trkorr } type: { e_type } exported successfully|.
    ENDIF.
    WRITE:/ l_dummy.
  ENDMETHOD.                    "download

ENDCLASS.                    "lcl_transport_export IMPLEMENTATION

DATA:
  l_transport TYPE trkorr,
  lrng_transports TYPE lcl_transport_export=>rng_transports,
  lo_trp_export TYPE REF TO lcl_transport_export.

SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE text-s01.
SELECT-OPTIONS: s_trp FOR l_transport DEFAULT 'XXXKYYYYYY'.
PARAMETERS: p_out TYPE string DEFAULT 'C:\temp' LOWER CASE.
SELECTION-SCREEN END OF BLOCK b01.

INITIALIZATION.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_trp-low.
  s_trp-low = lcl_transport_export=>transport_on_f4( ).

AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_trp-high.
  s_trp-high = lcl_transport_export=>transport_on_f4( ).

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_out.
  p_out = lcl_transport_export=>output_path_on_f4( ).

START-OF-SELECTION.
  CREATE OBJECT lo_trp_export.
  lrng_transports[] = s_trp[].
  lo_trp_export->execute(
    EXPORTING
      e_output_path = p_out
      et_transports = lrng_transports
  ).

Leave a Reply