Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[ABAP] Import Transport from ZIP

Report to import a ZIP file, containing the cofiles and data parts of a transport request. Related reports:
https://nocin.eu/abap-download-transport-as-zip/
https://nocin.eu/abap-create-toc-for-a-given-transport-release-it-and-download-it-as-zip/

This report can be handy, especially since S/4HANA 2023 seems to have restricted the “classic” import way by using TCode CG3Y and CG3Z. See note 1949906, where it is recommended to create a custom report.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
*&---------------------------------------------------------------------*
*& Report Z_IMPORT_TRANSPORT_FROM_ZIP
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT z_import_transport_from_zip.
 
SELECTION-SCREEN BEGIN OF BLOCK bl02 WITH FRAME TITLE TEXT-t02.
  PARAMETERS p_lcldir TYPE string  LOWER CASE OBLIGATORY DEFAULT 'C:\temp\'.
  PARAMETERS p_sapdir TYPE char255 LOWER CASE OBLIGATORY.
SELECTION-SCREEN END OF BLOCK bl02.
 
SELECTION-SCREEN BEGIN OF BLOCK bl03 WITH FRAME.
  PARAMETERS p_import TYPE boolean DEFAULT 'X' AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK bl03.
 
 
AT SELECTION-SCREEN OUTPUT.
 
  CALL 'C_SAPGPARAM' ID 'NAME' FIELD 'DIR_TRANS' ID 'VALUE' FIELD p_sapdir.
 
 
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_lcldir.
 
  DATA lt_files  TYPE filetable.
  DATA lv_rc     TYPE i.
  DATA lv_action TYPE i.
 
  TRY.
      cl_gui_frontend_services=>file_open_dialog( EXPORTING window_title      = 'Import'
                                                            default_extension = '.zip'
                                                            initial_directory = 'C:\temp\'
                                                            multiselection    = abap_false
                                                  CHANGING  file_table        = lt_files
                                                            rc                = lv_rc
                                                            user_action       = lv_action ).
      IF lv_action = cl_gui_frontend_services=>action_ok AND lines( lt_files ) > 0.
        p_lcldir = lt_files[ 1 ]-filename.
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'I'.
  ENDTRY.
 
 
START-OF-SELECTION.
 
  DATA lv_zip_size TYPE i.
  DATA lt_zip_data TYPE solix_tab.
  DATA lv_xstring  TYPE xstring.
 
  cl_gui_frontend_services=>gui_upload( EXPORTING filename   = p_lcldir
                                                  filetype   = 'BIN'
                                        IMPORTING filelength = lv_zip_size
                                        CHANGING  data_tab   = lt_zip_data ).
 
  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
    EXPORTING
      input_length = lv_zip_size
    IMPORTING
      buffer       = lv_xstring
    TABLES
      binary_tab   = lt_zip_data.
 
 
  " write zip content to filesystem
  DATA(lo_zipper)      = NEW cl_abap_zip( ).
  DATA(lt_zip_entries) = lo_zipper->splice( lv_xstring ).
  lo_zipper->load( lv_xstring ).
 
  LOOP AT lt_zip_entries INTO DATA(ls_zip_entry).
 
    lo_zipper->get( EXPORTING name    = ls_zip_entry-name
                    IMPORTING content = DATA(lv_data) ).
 
    DATA(lv_file) = COND #( WHEN ls_zip_entry-name(1) = 'K' THEN p_sapdir && '/cofiles/' && ls_zip_entry-name
                                                            ELSE p_sapdir && '/data/'    && ls_zip_entry-name ).
 
    TRY.
        OPEN DATASET  lv_file FOR OUTPUT IN BINARY MODE.
        TRANSFER      lv_data TO lv_file.
        CLOSE DATASET lv_file.
      CATCH cx_root INTO DATA(e_text).
        MESSAGE e_text->get_text( ) TYPE 'E'.
    ENDTRY.
 
  ENDLOOP.
 
 
  " now add transport to stms
  DATA lv_ret_code    TYPE trretcode.
  DATA ls_exception   TYPE stmscalert.
  DATA lt_logptr      TYPE TABLE OF tplogptr.
  DATA lt_stdout      TYPE TABLE OF tpstdout.
 
  DATA(lv_trkorr) = CONV trkorr( lt_zip_entries[ 1 ]-name+8(3) && 'K' && lt_zip_entries[ 1 ]-name+1(6) ).
  DATA(lv_system) = CONV tmssysnam( sy-sysid ).
  SELECT SINGLE domnam FROM tmscsys INTO @DATA(lv_transport_domain).
 
  " add transport to queue
  CALL FUNCTION 'TMS_MGR_FORWARD_TR_REQUEST'
    EXPORTING
      iv_request     = lv_trkorr
      iv_tarcli      = sy-mandt
      iv_target      = lv_system
      iv_source      = lv_system
      iv_tardom      = lv_transport_domain
      iv_srcdom      = lv_transport_domain
    IMPORTING
      ev_tp_ret_code = lv_ret_code
      es_exception   = ls_exception
    TABLES
      tt_stdout      = lt_stdout
    EXCEPTIONS
      OTHERS         = 99.
  IF sy-subrc <> 0 OR lv_ret_code <> 0.
    cl_demo_output=>display( lt_stdout ).
    MESSAGE 'Could not add transport to queue' TYPE 'E'.
  ENDIF.
 
  " also directly import if checked
  IF p_import = abap_true.
    CALL FUNCTION 'TMS_MGR_IMPORT_TR_REQUEST'
      EXPORTING
        iv_system                  = lv_system
        iv_request                 = lv_trkorr
        iv_client                  = sy-mandt
        iv_ignore_cvers            = abap_true "ignore invalid component version vector (CVERS)
      IMPORTING
        ev_tp_ret_code             = lv_ret_code
        es_exception               = ls_exception
      TABLES
        tt_logptr                  = lt_logptr
        tt_stdout                  = lt_stdout
      EXCEPTIONS
        read_config_failed         = 1
        table_of_requests_is_empty = 2
        OTHERS                     = 3.
    IF sy-subrc <> 0 OR lv_ret_code <> 0.
      cl_demo_output=>display( lt_stdout ).
      MESSAGE 'Could not import transport' TYPE 'E'.
    ENDIF.
  ENDIF.
 
  MESSAGE 'Transport successfully imported' TYPE 'S'.

[ABAP] Create ToC for a given transport, release it and download it as ZIP

Related Reports:
https://nocin.eu/abap-download-transport-as-zip/
https://nocin.eu/abap-import-transport-from-zip/

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
*&---------------------------------------------------------------------*
*& Report Z_ZIP_TOC
*&---------------------------------------------------------------------*
*& For the givin transport, this report creates a transport of copies (ToC),
*& releases it, and then download the ToC as ZIP file to your filesystem.
*& The given request can be in sate unreleased!
*&---------------------------------------------------------------------*
REPORT Z_ZIP_TOC.
 
INITIALIZATION.
 
  SELECTION-SCREEN BEGIN OF BLOCK bl01 WITH FRAME TITLE TEXT-t01.
  PARAMETERS p_trkorr LIKE e070-trkorr OBLIGATORY.
  PARAMETERS p_ttext  TYPE as4text.
  SELECTION-SCREEN END OF BLOCK bl01.
 
  SELECTION-SCREEN BEGIN OF BLOCK bl02 WITH FRAME TITLE TEXT-t02.
  PARAMETERS p_sapdir TYPE string LOWER CASE OBLIGATORY DEFAULT '/usr/sap/trans/'.
  PARAMETERS p_lcldir TYPE string LOWER CASE OBLIGATORY DEFAULT 'C:\temp\'.
  SELECTION-SCREEN END OF BLOCK bl02.
 
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_trkorr.
  CALL FUNCTION 'TR_F4_REQUESTS'
    EXPORTING
      iv_trkorr_pattern   = p_trkorr
    IMPORTING
      ev_selected_request = p_trkorr.
 
START-OF-SELECTION.
 
  " Read description of provided transport
  DATA ls_request TYPE trwbo_request.
  CALL FUNCTION 'TR_READ_REQUEST'
    EXPORTING
      iv_read_e07t     = 'X'
      iv_trkorr        = p_trkorr
    CHANGING
      cs_request       = ls_request
    EXCEPTIONS
      error_occured    = 1
      no_authorization = 2
      OTHERS           = 3.
  IF sy-subrc <> 0.
    MESSAGE 'Could not read Transport description' TYPE 'E'.
  ENDIF.
 
 
  " Read all objects for provided transport
  DATA: lt_objects TYPE  tr_objects,
        lt_keys    TYPE  tr_keys.
  CALL FUNCTION 'TR_GET_OBJECTS_OF_REQ_AN_TASKS'
    EXPORTING
      is_request_header      = VALUE trwbo_request_header( trkorr = p_trkorr )
      iv_condense_objectlist = 'X'
    IMPORTING
      et_objects             = lt_objects
      et_keys                = lt_keys
    EXCEPTIONS
      invalid_input          = 1
      OTHERS                 = 2.
  IF sy-subrc <> 0.
    MESSAGE 'Could not read Transport objects' TYPE 'E'.
  ENDIF.
 
 
  " Create new ToC
  DATA ls_request_header TYPE trwbo_request_header.
  CALL FUNCTION 'TR_INSERT_REQUEST_WITH_TASKS'
    EXPORTING
      iv_type           = 'T'
      iv_text           = COND as4text( WHEN p_ttext IS INITIAL THEN ls_request-h-as4text
                                                                ELSE p_ttext )
      iv_owner          = sy-uname
      iv_target         = 'DUM'
    IMPORTING
      es_request_header = ls_request_header
    EXCEPTIONS
      insert_failed     = 1
      enqueue_failed    = 2
      OTHERS            = 3.
  IF sy-subrc <> 0.
    MESSAGE 'Transport creation failed' TYPE 'E'.
  ENDIF.
  DATA(lv_trkorr_toc) = ls_request_header-trkorr.
 
 
  " Add all object to the new ToC
  CALL FUNCTION 'TRINT_APPEND_COMM'
    EXPORTING
      wi_exclusive       = 'X'
      wi_sel_e071        = 'X'
      wi_sel_e071k       = 'X'
      wi_trkorr          = lv_trkorr_toc
    TABLES
      wt_e071            = lt_objects
      wt_e071k           = lt_keys
    EXCEPTIONS
      e071k_append_error = 1
      e071_append_error  = 2
      trkorr_empty       = 3
      OTHERS             = 4.
  IF sy-subrc <> 0.
    MESSAGE 'Could not append objects to ToC' TYPE 'E'.
  ENDIF.
 
 
  " Release ToC Transport
  DATA lt_messages TYPE ctsgerrmsgs.
  CALL FUNCTION 'TRINT_RELEASE_REQUEST'
    EXPORTING
      iv_trkorr                   = lv_trkorr_toc
*     IV_DIALOG                   = 'X'
*     IV_AS_BACKGROUND_JOB        = ' '
*     IV_SUCCESS_MESSAGE          = 'X'
*     IV_WITHOUT_OBJECTS_CHECK    = ' '
*     IV_CALLED_BY_ADT            = ' '
*     IV_CALLED_BY_PERFORCE       = ' '
*     IV_WITHOUT_DOCU             = ' '
      iv_without_locking          = 'X'
*     IV_DISPLAY_EXPORT_LOG       = 'X'
*     IV_IGNORE_WARNINGS          = ' '
*     IV_SIMULATION               = ' '
    IMPORTING
      et_messages                 = lt_messages
    EXCEPTIONS
      cts_initialization_failure  = 1
      enqueue_failed              = 2
      no_authorization            = 3
      invalid_request             = 4
      request_already_released    = 5
      repeat_too_early            = 6
      object_lock_error           = 7
      object_check_error          = 8
      docu_missing                = 9
      db_access_error             = 10
      action_aborted_by_user      = 11
      export_failed               = 12
      execute_objects_check       = 13
      release_in_bg_mode          = 14
      release_in_bg_mode_w_objchk = 15
      error_in_export_methods     = 16
      object_lang_error           = 17
      OTHERS                      = 18.
  IF sy-subrc <> 0.
    MESSAGE 'Could not release ToC' TYPE 'E'.
    cl_demo_output=>display( lt_messages ).
  ENDIF.
 
 
  " Download released ToC as ZIP
  DATA lv_xcontent_k TYPE xstring.
  DATA lv_xcontent_r TYPE xstring.
 
  DATA(lv_transdir_k) = |{ p_sapdir }cofiles/K{ lv_trkorr_toc+4 }.{ lv_trkorr_toc(3) }|.
  DATA(lv_transdir_r) = |{ p_sapdir }data/R{    lv_trkorr_toc+4 }.{ lv_trkorr_toc(3) }|.
 
 
  TRY.
 
      " K
      OPEN  DATASET lv_transdir_k FOR INPUT IN BINARY MODE.
      READ  DATASET lv_transdir_k INTO lv_xcontent_k.
      CLOSE DATASET lv_transdir_k.
 
      " R
      OPEN  DATASET lv_transdir_r FOR INPUT IN BINARY MODE.
      READ  DATASET lv_transdir_r INTO lv_xcontent_r.
      CLOSE DATASET lv_transdir_r.
 
 
      " Add to ZIP
      DATA(lo_zipper) = NEW cl_abap_zip( ).
 
      lo_zipper->add( name    = |K{ lv_trkorr_toc+4 }.{ lv_trkorr_toc(3) }|
                      content = lv_xcontent_k ).
 
      lo_zipper->add( name    = |R{ lv_trkorr_toc+4 }.{ lv_trkorr_toc(3) }|
                      content = lv_xcontent_r ).
 
 
      " Download ZIP
      DATA(lv_xzip) = lo_zipper->save( ).
 
      " Convert to raw data
      DATA(lt_data) = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_xzip ).
 
      " Set zip filename
      DATA(lv_zip_name) = COND #( WHEN p_ttext IS INITIAL THEN |{ ls_request-h-as4text }_{ lv_trkorr_toc }|
                                                          ELSE |{ p_ttext              }_{ lv_trkorr_toc }| ).
 
      " Replace every character that is not [a-zA-Z0-9_] with '_'.
      REPLACE ALL OCCURRENCES OF REGEX '[^\w]+' IN lv_zip_name WITH '_'.
 
      cl_gui_frontend_services=>gui_download( EXPORTING filename = p_lcldir && lv_zip_name && '.zip'
                                                        filetype = 'BIN'
                                              CHANGING  data_tab = lt_data ).
 
    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'E'.
  ENDTRY.
 
  MESSAGE |{ lv_zip_name }.zip created and downloaded to { p_lcldir }| TYPE 'S'.

[ABAP] Download Transport as ZIP

Related Reports:
https://nocin.eu/abap-import-transport-from-zip/
https://nocin.eu/abap-create-toc-for-a-given-transport-release-it-and-download-it-as-zip/

This report can be handy, especially since S/4HANA 2023 seems to have restricted the “classic” import way by using TCode CG3Y and CG3Z. See note 1949906, where it is recommended to create a custom report.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
*&---------------------------------------------------------------------*
*& Report ZIP_TRANSPORT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zip_transport.
 
SELECTION-SCREEN BEGIN OF BLOCK bl01 WITH FRAME TITLE TEXT-t01.
PARAMETERS p_trkorr LIKE e070-trkorr OBLIGATORY.
PARAMETERS p_ttext  TYPE as4text.
SELECTION-SCREEN END OF BLOCK bl01.
 
SELECTION-SCREEN BEGIN OF BLOCK bl02 WITH FRAME TITLE TEXT-t02.
PARAMETERS p_sapdir TYPE string LOWER CASE OBLIGATORY DEFAULT '/usr/sap/trans/'.
PARAMETERS p_lcldir TYPE string LOWER CASE OBLIGATORY DEFAULT 'C:\temp\'.
SELECTION-SCREEN END OF BLOCK bl02.
 
 
START-OF-SELECTION.
 
  " Check if Transport is released
  DATA ls_request TYPE trwbo_request.
  CALL FUNCTION 'TR_READ_REQUEST'
    EXPORTING
      iv_read_e070     = abap_true
      iv_read_e07t     = abap_true
      iv_trkorr        = p_trkorr
    CHANGING
      cs_request       = ls_request
    EXCEPTIONS
      error_occured    = 1
      no_authorization = 2
      OTHERS           = 3.
  IF ls_request-h-trstatus <> 'R'.
    MESSAGE 'Transport not yet released' TYPE 'E'.
  ENDIF.
 
 
  " Read released Transport
  DATA lv_xcontent_k TYPE xstring.
  DATA lv_xcontent_r TYPE xstring.
 
  DATA(lv_transdir_k) = |{ p_sapdir }cofiles/K{ p_trkorr+4 }.{ p_trkorr(3) }|.
  DATA(lv_transdir_r) = |{ p_sapdir }data/R{    p_trkorr+4 }.{ p_trkorr(3) }|.
 
 
  TRY.
 
      " K
      OPEN  DATASET lv_transdir_k FOR INPUT IN BINARY MODE.
      READ  DATASET lv_transdir_k INTO lv_xcontent_k.
      CLOSE DATASET lv_transdir_k.
 
      " R
      OPEN  DATASET lv_transdir_r FOR INPUT IN BINARY MODE.
      READ  DATASET lv_transdir_r INTO lv_xcontent_r.
      CLOSE DATASET lv_transdir_r.
 
      " Add to ZIP
      DATA(lo_zipper) = NEW cl_abap_zip( ).
 
      lo_zipper->add( name    = |K{ p_trkorr+4 }.{ p_trkorr(3) }|
                      content = lv_xcontent_k ).
 
      lo_zipper->add( name    = |R{ p_trkorr+4 }.{ p_trkorr(3) }|
                      content = lv_xcontent_r ).
 
 
      " Download ZIP
      DATA(lv_xzip) = lo_zipper->save( ).
 
      " Convert to raw data
      DATA(lt_data) = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_xzip ).
 
      " Set zip filename
      DATA(lv_zip_name) = COND #( WHEN p_ttext IS INITIAL THEN |{ ls_request-h-as4text }_{ p_trkorr }|
                                                          ELSE |{ p_ttext              }_{ p_trkorr }| ).
 
      " Replace every character that is not [a-zA-Z0-9_] with '_'.
      REPLACE ALL OCCURRENCES OF REGEX '[^\w]+' IN lv_zip_name WITH '_'.
 
      cl_gui_frontend_services=>gui_download( EXPORTING filename = p_lcldir && lv_zip_name && '.zip'
                                                        filetype = 'BIN'
                                              CHANGING  data_tab = lt_data ).
 
    CATCH cx_root INTO DATA(e_text).
      MESSAGE e_text->get_text( ) TYPE 'E'.
  ENDTRY.
 
  MESSAGE |{ lv_zip_name }.zip created and downloaded to { p_lcldir }| TYPE 'S'.