Skip to Content
Author's profile photo Former Member

Send an email in background with multi-sheet excel attachment

Multiple sheets in excel can be achieved through OLE, but if the file has to be sent in background we cannot access the presentation server to pick the file. This blog shows how to send an email in background with multiple worksheet excel attachment (Data -> XML -> Binary -> Email).

REPORT  zemail_bg NO STANDARD PAGE HEADING.

DATA: i_header          TYPE STANDARD TABLE OF vbak,
       i_detail          TYPE STANDARD TABLE OF vbap,
       i_xml             TYPE STANDARD TABLE OF solisti1,
       i_binary_content  TYPE solix_tab,
       wa_header         TYPE vbak,
       wa_detail         TYPE vbap,
       wa_xml            TYPE solisti1,
       gc_crlf           TYPE c VALUE cl_bcs_convert=>gc_crlf,
       v_string          TYPE string,
       v_size            TYPE so_obj_len,
       send_request      TYPE REF TO cl_bcs,
       document          TYPE REF TO cl_document_bcs,
       recipient         TYPE REF TO if_recipient_bcs,
       bcs_exception     TYPE REF TO cx_bcs,
       main_text         TYPE bcsy_text,
       sent_to_all       TYPE os_boolean,
       mailto            TYPE ad_smtpadr.

CONSTANTS:
   c_header1    TYPE char63 VALUE ‘<?xml version=”1.0″ encoding=”utf-8″?>’,
   c_header01   TYPE char63 VALUE ‘<?mso-application progid=”Excel.Sheet”?>’,
   c_header2    TYPE char63 VALUE ‘<Workbook xmlns=”urn:schemas-microsoft-com:office:spreadsheet”‘,
   c_header3    TYPE char63 VALUE ‘xmlns:x=”urn:schemas-microsoft-com:office:excel”‘,
   c_header4    TYPE char63 VALUE ‘xmlns:ss=”urn:schemas-microsoft-com:office:spreadsheet”‘,
   c_header5    TYPE char63 VALUE ‘xmlns:html=”http://www.w3.org/TR/REC-html40“>’,
   c_stylesbe   TYPE char63 VALUE ‘<Styles>’,
   c_stylesed   TYPE char63 VALUE ‘</Styles>’,
   c_stylebe    TYPE char63 VALUE ‘<Style ss:ID=”s1″>’,
   c_styleed    TYPE char63 VALUE ‘</Style>’,
   c_font       TYPE char63 VALUE ‘<Font x:Family=”Swiss” ss:Bold=”1″ />’,
   c_wrkshtbe   TYPE char20 VALUE ‘<Worksheet ss:Name=”‘,
   c_wrkshttg   TYPE char05 VALUE ‘”>’,
   c_wrkshted   TYPE char20 VALUE ‘</Worksheet>’,
   c_tablebe    TYPE char10 VALUE ‘<Table>’,
   c_tableed    TYPE char10 VALUE ‘</Table>’,
   c_rowbe      TYPE char10 VALUE ‘<Row>’,
   c_rowed      TYPE char10 VALUE ‘</Row>’,
   c_cellbe     TYPE char10 VALUE ‘<Cell>’,
   c_celled     TYPE char10 VALUE ‘</Cell>’,
   c_databe     TYPE char30 VALUE ‘<ss:Data ss:Type=”String”>’,
   c_dataed     TYPE char30 VALUE ‘</ss:Data>’,
   c_wrkbked    TYPE char30 VALUE ‘</Workbook>’,
   c_styleid    TYPE char30 VALUE ‘<Style ss:ID=”s65″>’,
   c_hdcol      TYPE char50 VALUE ‘<Interior ss:Color=”#BFBFBF” ss:Pattern=”Solid”/>’,
   c_hdr        TYPE char50 VALUE ‘<Cell ss:StyleID=”s65″><Data ss:Type=”String”>’,
   c_dtcell     TYPE char30 VALUE ‘</Data></Cell>’.

*– Fetch data
SELECT * FROM vbak INTO TABLE i_header UP TO 50 ROWS.
IF sy-subrc IS INITIAL.
   SELECT * FROM vbap INTO TABLE i_detail FOR ALL ENTRIES IN i_header WHERE vbeln = i_header-vbeln.
ENDIF.

*– Writing the XML Header tags into a global internal table
MOVE c_header1 TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_header01 TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_header2 TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_header3 TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_header4 TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_header5 TO wa_xml-line.
APPEND wa_xml TO i_xml.

*– Creating a global style in which we mention about font
*   that will be followed across the workbook.
MOVE c_stylesbe TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_stylebe TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_font TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_styleed TO wa_xml-line.
APPEND wa_xml TO i_xml.

wa_xml-line = c_styleid.
APPEND wa_xml TO i_xml.
wa_xml-line = c_hdcol.
APPEND wa_xml TO i_xml.
wa_xml-line = c_styleed.
APPEND wa_xml TO i_xml.

MOVE c_stylesed TO wa_xml-line.
APPEND wa_xml TO i_xml.

*– Preparing ‘Header’ sheet
CONCATENATE c_wrkshtbe ‘Header’ c_wrkshttg
             INTO wa_xml-line
             SEPARATED BY ‘ ‘.
APPEND wa_xml TO i_xml.

MOVE c_tablebe TO wa_xml-line.
APPEND wa_xml TO i_xml.

wa_xml-line = ‘<Column ss:Width=”62″/>’.
APPEND wa_xml TO i_xml.

wa_xml-line = ‘<Column ss:Width=”81″/>’.
APPEND wa_xml TO i_xml.

LOOP AT i_header INTO wa_header.
   IF sy-tabix = 1.
     MOVE c_rowbe TO wa_xml-line.
     APPEND wa_xml TO i_xml.

     CONCATENATE c_hdr ‘Sales Document’ c_dtcell INTO wa_xml-line.
     APPEND wa_xml TO i_xml.

     CONCATENATE c_hdr ‘Create Date’ c_dtcell INTO wa_xml-line.
     APPEND wa_xml TO i_xml.

     MOVE c_rowed TO wa_xml-line.
     APPEND wa_xml TO i_xml.
   ENDIF.

*– Writing the XML code to start a row in the table inserted above
*   to the particular sheet.
   MOVE c_rowbe TO wa_xml-line.
   APPEND wa_xml TO i_xml.

*– Writing the XML code for transferring the data cell by cell
*   in the row created above .
   CONCATENATE c_cellbe c_databe wa_header-vbeln c_dataed c_celled
       INTO wa_xml-line
       SEPARATED BY ‘ ‘.
   APPEND wa_xml TO i_xml.

   CONCATENATE c_cellbe c_databe wa_header-kunnr c_dataed c_celled
       INTO wa_xml-line
       SEPARATED BY ‘ ‘.
   APPEND wa_xml TO i_xml.

*– Writing the XML code for ending a row after
*   writing data for all the columns.
   MOVE c_rowed TO wa_xml-line.
   APPEND wa_xml TO i_xml.
ENDLOOP.

*– Close the table and the sheet.
MOVE c_tableed TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_wrkshted TO wa_xml-line.
APPEND wa_xml TO i_xml.

*– Preparing ‘Detail data’ work sheet
CONCATENATE c_wrkshtbe ‘Detail’ c_wrkshttg
             INTO wa_xml-line
             SEPARATED BY ‘ ‘.
APPEND wa_xml TO i_xml.

*– Writing the XML code for inserting a table.
MOVE c_tablebe TO wa_xml-line.
APPEND wa_xml TO i_xml.

wa_xml-line = ‘<Column ss:Width=”62″/>’.
APPEND wa_xml TO i_xml.
wa_xml-line = ‘<Column ss:Width=”81″/>’.
APPEND wa_xml TO i_xml.

*– Populate ‘Detail’ sheet data
LOOP AT i_detail INTO wa_detail.
   IF sy-tabix = 1.
     MOVE c_rowbe TO wa_xml-line.
     APPEND wa_xml TO i_xml.

     CONCATENATE c_hdr ‘Sales Document’ c_dtcell INTO wa_xml-line.
     APPEND wa_xml TO i_xml.

     CONCATENATE c_hdr ‘Item Number’ c_dtcell INTO wa_xml-line.
     APPEND wa_xml TO i_xml.

     MOVE c_rowed TO wa_xml-line.
     APPEND wa_xml TO i_xml.
   ENDIF.

*– Writing the XML code to start a row in the table inserted above
*   to the particular sheet
   MOVE c_rowbe TO wa_xml-line.
   APPEND wa_xml TO i_xml.

*– Writing the XML code for transferring the data cell by cell
*   in the row created above
   CONCATENATE c_cellbe c_databe wa_detail-vbeln c_dataed c_celled
       INTO wa_xml-line
       SEPARATED BY ‘ ‘.
   APPEND wa_xml TO i_xml.

   CONCATENATE c_cellbe c_databe wa_detail-posnr c_dataed c_celled
       INTO wa_xml-line
       SEPARATED BY ‘ ‘.
   APPEND wa_xml TO i_xml.

*– Writing the XML code for ending a row after
*   writing data for all the columns.
   MOVE c_rowed TO wa_xml-line.
   APPEND wa_xml TO i_xml.
ENDLOOP.

*– After transferring all the data to the rows of the table
*   inserted in the sheet we need to close the table and the sheet.
MOVE c_tableed TO wa_xml-line.
APPEND wa_xml TO i_xml.
MOVE c_wrkshted TO wa_xml-line.
APPEND wa_xml TO i_xml.

*– After transferring all the data in to the XML form
*   we need to end the XML workbook created.
MOVE c_wrkbked TO wa_xml-line.
APPEND wa_xml TO i_xml.

*– Convert the XML data into Binary data
LOOP AT i_xml INTO wa_xml.
   CONCATENATE v_string wa_xml gc_crlf INTO v_string.
ENDLOOP.

TRY.
     cl_bcs_convert=>string_to_solix(
       EXPORTING
         iv_string   = v_string
         iv_codepage = ‘4103’  “suitable for MS Excel, leave empty
         iv_add_bom  = ‘X’     “for other doc types
       IMPORTING
         et_solix  = i_binary_content
         ev_size   = v_size ).
   CATCH cx_bcs.
     MESSAGE e445(so).
ENDTRY.

*– Send email
TRY.
*– create persistent send request
     send_request = cl_bcs=>create_persistent( ).

*– create and set document with attachment
*     create document object from internal table with text
     APPEND ‘PFA, The report output’ TO main_text.
     document = cl_document_bcs=>create_document(
       i_type    = ‘RAW’
       i_text    = main_text
       i_subject = ‘Test’ ).

*– Add the spread sheet as attachment to document object
     document->add_attachment(
       i_attachment_type    = ‘xls’
       i_attachment_subject = ‘Output’
       i_attachment_size    = v_size
       i_att_content_hex    = i_binary_content ).

*– Add document object to send request
     send_request->set_document( document ).

*– Add recipient (e-mail address)
*     create recipient object
     mailto = ‘ENTER YOUR MAILID HERE’.
     recipient = cl_cam_address_bcs=>create_internet_address( mailto ).

*– Add recipient object to send request
     send_request->add_recipient( recipient ).

*– Set send immediately flag
     send_request->set_send_immediately( ‘X’ ).

*– send document
     sent_to_all = send_request->send( i_with_error_screen = ‘X’ ).
     COMMIT WORK.
     IF sent_to_all IS INITIAL.
       MESSAGE i500(sbcoms) WITH mailto.
     ELSE.
       MESSAGE s022(so).
     ENDIF.
*– exception handling
   CATCH cx_bcs INTO bcs_exception.
     MESSAGE i865(so) WITH bcs_exception->error_type.
ENDTRY.

Run the program in background..

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Giriesh Chakaravarthy Mamurugan
      Giriesh Chakaravarthy Mamurugan

      Hi Goutham,

      First of all, thanks for the sharing the knowledge. I have tried your code and it works perfectly. But I am facing a weird issue. When I send the attachements to my mail id the attachment is opening in a fine way but when I send it to my client user id and try to open the attachment, the excel file is throwing an message that "This attachement was removed because it contains data that could pose security risk". Do you have any Idea why it behaves in such a way ?

      With Regards,

      Giriesh M

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Giriesh,

      I haven't faced such an issue. But i'm guessing this to be a security policy issue. please try to turn off macro's and give it a try

      Thanks,

      Goutham Bobba

      Author's profile photo Janagar Sundaramoorthy
      Janagar Sundaramoorthy

      Just added a few lines of code in this code to download the multi tabbed excel sheet in foreground using XML approach.

      PARAMETERS : p_down TYPE c AS CHECKBOX.

      DATA: i_header          TYPE STANDARD TABLE OF vbak,

             i_detail          TYPE STANDARD TABLE OF vbap,

             i_xml             TYPE STANDARD TABLE OF solisti1,

             i_binary_content  TYPE solix_tab,

             wa_header         TYPE vbak,

             wa_detail         TYPE vbap,

             wa_xml            TYPE solisti1,

             gc_crlf           TYPE c VALUE cl_bcs_convert=>gc_crlf,

             v_string          TYPE string,

             itab_string       TYPE STANDARD TABLE OF string,

             v_size            TYPE so_obj_len,

             send_request      TYPE REF TO cl_bcs,

             document          TYPE REF TO cl_document_bcs,

             recipient         TYPE REF TO if_recipient_bcs,

             bcs_exception     TYPE REF TO cx_bcs,

             main_text         TYPE bcsy_text,

             sent_to_all       TYPE os_boolean,

             mailto            TYPE ad_smtpadr.

      CONSTANTS:

         c_header1    TYPE char63 VALUE '<?xml version="1.0" encoding="utf-8"?>',

         c_header01   TYPE char63 VALUE '<?mso-application progid="Excel.Sheet"?>',

         c_header2    TYPE char63 VALUE '<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"',

         c_header3    TYPE char63 VALUE 'xmlns:x="urn:schemas-microsoft-com:office:excel"',

         c_header4    TYPE char63 VALUE 'xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"',

         c_header5    TYPE char63 VALUE 'xmlns:html="http://www.w3.org/TR/REC-html40">',

         c_stylesbe   TYPE char63 VALUE '<Styles>',

         c_stylesed   TYPE char63 VALUE '</Styles>',

         c_stylebe    TYPE char63 VALUE '<Style ss:ID="s1">',

         c_styleed    TYPE char63 VALUE '</Style>',

         c_font       TYPE char63 VALUE '<Font x:Family="Swiss" ss:Bold="1" />',

         c_wrkshtbe   TYPE char20 VALUE '<Worksheet ss:Name="',

         c_wrkshttg   TYPE char05 VALUE '">',

         c_wrkshted   TYPE char20 VALUE '</Worksheet>',

         c_tablebe    TYPE char10 VALUE '<Table>',

         c_tableed    TYPE char10 VALUE '</Table>',

         c_rowbe      TYPE char10 VALUE '<Row>',

         c_rowed      TYPE char10 VALUE '</Row>',

         c_cellbe     TYPE char10 VALUE '<Cell>',

         c_celled     TYPE char10 VALUE '</Cell>',

         c_databe     TYPE char30 VALUE '<ss:Data ss:Type="String">',

         c_dataed     TYPE char30 VALUE '</ss:Data>',

         c_wrkbked    TYPE char30 VALUE '</Workbook>',

         c_styleid    TYPE char30 VALUE '<Style ss:ID="s65">',

         c_hdcol      TYPE char50 VALUE '<Interior ss:Color="#BFBFBF" ss:Pattern="Solid"/>',

         c_hdr        TYPE char50 VALUE '<Cell ss:StyleID="s65"><Data ss:Type="String">',

         c_dtcell     TYPE char30 VALUE '</Data></Cell>'.

      *-- Fetch data

      SELECT * FROM vbak INTO TABLE i_header UP TO 50 ROWS.

      IF sy-subrc IS INITIAL.

        SELECT * FROM vbap INTO TABLE i_detail FOR ALL ENTRIES IN i_header WHERE vbeln = i_header-vbeln.

      ENDIF.

      *-- Writing the XML Header tags into a global internal table

      MOVE c_header1 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_header01 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_header2 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_header3 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_header4 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_header5 TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      *-- Creating a global style in which we mention about font

      *   that will be followed across the workbook.

      MOVE c_stylesbe TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_stylebe TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_font TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_styleed TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      wa_xml-line = c_styleid.

      APPEND wa_xml TO i_xml.

      wa_xml-line = c_hdcol.

      APPEND wa_xml TO i_xml.

      wa_xml-line = c_styleed.

      APPEND wa_xml TO i_xml.

      MOVE c_stylesed TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      *-- Preparing 'Header' sheet

      CONCATENATE c_wrkshtbe 'Header' c_wrkshttg

                   INTO wa_xml-line

                   SEPARATED BY ' '.

      APPEND wa_xml TO i_xml.

      MOVE c_tablebe TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      wa_xml-line = '<Column ss:Width="62"/>'.

      APPEND wa_xml TO i_xml.

      wa_xml-line = '<Column ss:Width="81"/>'.

      APPEND wa_xml TO i_xml.

      LOOP AT i_header INTO wa_header.

        IF sy-tabix = 1.

          MOVE c_rowbe TO wa_xml-line.

          APPEND wa_xml TO i_xml.

          CONCATENATE c_hdr 'Sales Document' c_dtcell INTO wa_xml-line.

          APPEND wa_xml TO i_xml.

          CONCATENATE c_hdr 'Create Date' c_dtcell INTO wa_xml-line.

          APPEND wa_xml TO i_xml.

          MOVE c_rowed TO wa_xml-line.

          APPEND wa_xml TO i_xml.

        ENDIF.

      *-- Writing the XML code to start a row in the table inserted above

      *   to the particular sheet.

        MOVE c_rowbe TO wa_xml-line.

        APPEND wa_xml TO i_xml.

      *-- Writing the XML code for transferring the data cell by cell

      *   in the row created above .

        CONCATENATE c_cellbe c_databe wa_header-vbeln c_dataed c_celled

            INTO wa_xml-line

            SEPARATED BY ' '.

        APPEND wa_xml TO i_xml.

        CONCATENATE c_cellbe c_databe wa_header-kunnr c_dataed c_celled

            INTO wa_xml-line

            SEPARATED BY ' '.

        APPEND wa_xml TO i_xml.

      *-- Writing the XML code for ending a row after

      *   writing data for all the columns.

        MOVE c_rowed TO wa_xml-line.

        APPEND wa_xml TO i_xml.

      ENDLOOP.

      *-- Close the table and the sheet.

      MOVE c_tableed TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_wrkshted TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      *-- Preparing 'Detail data' work sheet

      CONCATENATE c_wrkshtbe 'Detail' c_wrkshttg

                   INTO wa_xml-line

                   SEPARATED BY ' '.

      APPEND wa_xml TO i_xml.

      *-- Writing the XML code for inserting a table.

      MOVE c_tablebe TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      wa_xml-line = '<Column ss:Width="62"/>'.

      APPEND wa_xml TO i_xml.

      wa_xml-line = '<Column ss:Width="81"/>'.

      APPEND wa_xml TO i_xml.

      *-- Populate 'Detail' sheet data

      LOOP AT i_detail INTO wa_detail.

        IF sy-tabix = 1.

          MOVE c_rowbe TO wa_xml-line.

          APPEND wa_xml TO i_xml.

          CONCATENATE c_hdr 'Sales Document' c_dtcell INTO wa_xml-line.

          APPEND wa_xml TO i_xml.

          CONCATENATE c_hdr 'Item Number' c_dtcell INTO wa_xml-line.

          APPEND wa_xml TO i_xml.

          MOVE c_rowed TO wa_xml-line.

          APPEND wa_xml TO i_xml.

        ENDIF.

      *-- Writing the XML code to start a row in the table inserted above

      *   to the particular sheet

        MOVE c_rowbe TO wa_xml-line.

        APPEND wa_xml TO i_xml.

      *-- Writing the XML code for transferring the data cell by cell

      *   in the row created above

        CONCATENATE c_cellbe c_databe wa_detail-vbeln c_dataed c_celled

            INTO wa_xml-line

            SEPARATED BY ' '.

        APPEND wa_xml TO i_xml.

        CONCATENATE c_cellbe c_databe wa_detail-posnr c_dataed c_celled

            INTO wa_xml-line

            SEPARATED BY ' '.

        APPEND wa_xml TO i_xml.

      *-- Writing the XML code for ending a row after

      *   writing data for all the columns.

        MOVE c_rowed TO wa_xml-line.

        APPEND wa_xml TO i_xml.

      ENDLOOP.

      *-- After transferring all the data to the rows of the table

      *   inserted in the sheet we need to close the table and the sheet.

      MOVE c_tableed TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      MOVE c_wrkshted TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      *-- After transferring all the data in to the XML form

      *   we need to end the XML workbook created.

      MOVE c_wrkbked TO wa_xml-line.

      APPEND wa_xml TO i_xml.

      *-- Convert the XML data into Binary data

      LOOP AT i_xml INTO wa_xml.

        CONCATENATE v_string wa_xml gc_crlf INTO v_string.

      ENDLOOP.

      APPEND v_string TO itab_string.

      IF p_down IS INITIAL.

        TRY.

            cl_bcs_convert=>string_to_solix(

              EXPORTING

                iv_string   = v_string

                iv_codepage = '4103'  "suitable for MS Excel, leave empty

                iv_add_bom  = 'X'     "for other doc types

              IMPORTING

                et_solix  = i_binary_content

                ev_size   = v_size ).

          CATCH cx_bcs.

            MESSAGE e445(so).

        ENDTRY.

      *-- Send email

        TRY.

      *-- create persistent send request

            send_request = cl_bcs=>create_persistent( ).

      *-- create and set document with attachment

      *     create document object from internal table with text

            APPEND 'PFA, The report output' TO main_text.

            document = cl_document_bcs=>create_document(

              i_type    = 'RAW'

              i_text    = main_text

              i_subject = 'Test' ).

      *-- Add the spread sheet as attachment to document object

            document->add_attachment(

              i_attachment_type    = 'xls'

              i_attachment_subject = 'Output'

              i_attachment_size    = v_size

              i_att_content_hex    = i_binary_content ).

      *-- Add document object to send request

            send_request->set_document( document ).

      *-- Add recipient (e-mail address)

      *     create recipient object

            mailto = 'xxx@xmail.com'.

            recipient = cl_cam_address_bcs=>create_internet_address( mailto ).

      *-- Add recipient object to send request

            send_request->add_recipient( recipient ).

      *-- Set send immediately flag

            send_request->set_send_immediately( 'X' ).

      *-- send document

            sent_to_all = send_request->send( i_with_error_screen = 'X' ).

            COMMIT WORK.

            IF sent_to_all IS INITIAL.

              MESSAGE i500(sbcoms) WITH mailto.

            ELSE.

              MESSAGE s022(so).

            ENDIF.

      *-- exception handling

          CATCH cx_bcs INTO bcs_exception.

            MESSAGE i865(so) WITH bcs_exception->error_type.

        ENDTRY.

      ELSE.

        DATA: window_title TYPE string,

             fullpath TYPE string,

             path TYPE string,

             user_action TYPE i,

             default_extension TYPE string,

             default_file_name TYPE string,

             file_filter TYPE  string,

             filename TYPE string,

             initialpath TYPE string.

      *File selection

        MOVE '.XLS' TO default_extension.

        MOVE 'XLS files (.XLS)|.XLS' TO file_filter.

        CALL METHOD cl_gui_frontend_services=>file_save_dialog

          EXPORTING

            default_extension = default_extension

            default_file_name = default_file_name

            file_filter       = file_filter

            initial_directory = initialpath

          CHANGING

            filename          = filename

            path              = path

            fullpath          = fullpath

            user_action       = user_action

          EXCEPTIONS

            cntl_error        = 1

            error_no_gui      = 2

            OTHERS            = 3.

        IF sy-subrc <> 0.

          MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

                     WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

        ENDIF.

      *download file

        CALL FUNCTION 'GUI_DOWNLOAD'

          EXPORTING

            filename                = fullpath

            filetype                = 'ASC'

          TABLES

            data_tab                = itab_string

          EXCEPTIONS

            file_write_error        = 1

            no_batch                = 2

            gui_refuse_filetransfer = 3

            invalid_type            = 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.

      ENDIF.