[ABAP] Transportauftrag als ZIP-Datei speichern

SELECTION-SCREEN BEGIN OF LINE.
  SELECTION-SCREEN COMMENT (20) lbl1 FOR FIELD p_trkorr.
  PARAMETERS: p_trkorr LIKE e070-trkorr OBLIGATORY.
SELECTION-SCREEN END OF LINE.

INITIALIZATION.

  lbl1 = 'Transport-Auftrag:'.

START-OF-SELECTION.
  TRY.
      DATA: lv_req 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       = lv_req
        EXCEPTIONS
          error_occured    = 1
          no_authorization = 2
          OTHERS           = 3.

      IF sy-subrc = 0.
*D Änderbar
*L Änderbar, geschützt
*O Freigabe gestartet
*R Freigegeben
*N Freigegeben (Importschutz für reparierte Objekte aktiv)
        IF lv_req-h-trstatus = 'R'.

* SAP-Dir
          DATA(lv_sap_dir) = |/usr/sap/trans/|.

* Name
          DATA(lv_syst) = |{ p_trkorr(3) }|.
          DATA(lv_num) = |{ p_trkorr+4 }|.
          DATA(lv_name) = |{ lv_num }.{ lv_syst }|.

* Cofile
          DATA: lv_xstr_cofile TYPE xstring.
          DATA(lv_cofile) = |{ lv_sap_dir }cofiles/K{ lv_name }|.

          OPEN DATASET lv_cofile FOR INPUT IN BINARY MODE.
          READ DATASET lv_cofile INTO lv_xstr_cofile.
          CLOSE DATASET lv_cofile.

* Data
          DATA: lv_xstr_data TYPE xstring.
          DATA(lv_data) = |{ lv_sap_dir }data/R{ lv_name }|.

          OPEN DATASET lv_data FOR INPUT IN BINARY MODE.
          READ DATASET lv_data INTO lv_xstr_data.
          CLOSE DATASET lv_data.

* Zip
          DATA(o_zip) = NEW cl_abap_zip( ).

          o_zip->add( name    = |K{ lv_name }|
                      content = lv_xstr_cofile ).

          o_zip->add( name    = |R{ lv_name }|
                      content = lv_xstr_data ).

          DATA(lv_xstr_zip) = o_zip->save( ).

* SOLIX
          DATA(it_raw_data) = cl_bcs_convert=>xstring_to_solix( EXPORTING iv_xstring = lv_xstr_zip ).

          DATA: lv_action TYPE i.
          DATA: lv_filename TYPE string.
          DATA: lv_fullpath TYPE string.
          DATA: lv_path TYPE string.

          DATA(lv_default) = |{ lv_req-h-as4text }_{ p_trkorr }|.

* alle Vorkommen, die nicht [a-zA-Z0-9_] entsprechen, durch '_' ersetzen
          REPLACE ALL OCCURRENCES OF REGEX '[^\w]+' IN lv_default WITH '_'.

* Save-Dialog
          cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                        default_file_name = lv_default
                                                        default_extension = 'zip'
                                                        file_filter       = |{ cl_gui_frontend_services=>filetype_all }|
                                                      CHANGING
                                                        filename          = lv_filename
                                                        path              = lv_path
                                                        fullpath          = lv_fullpath
                                                        user_action       = lv_action ).

          IF lv_action EQ cl_gui_frontend_services=>action_ok.

* Datei lokal speichern
            cl_gui_frontend_services=>gui_download( EXPORTING
                                                      filename     = lv_fullpath
                                                      filetype     = 'BIN'
                                                      bin_filesize = xstrlen( lv_xstr_zip )
                                                    CHANGING
                                                      data_tab     = it_raw_data ).
          ENDIF.
        ELSE.
          WRITE: / |Auftrag { p_trkorr } nicht frei gegeben.|.
        ENDIF.
      ELSE.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO DATA(lv_msg).
        WRITE: / lv_msg.
      ENDIF.
    CATCH cx_root INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.