SAP/ABAP

excel download ( OLE based )

Denise 2014. 2. 18. 13:54

ZEXCEL_T_HEADER

ZEXCEL_S_HEADER

ROW 1 Types ZDK_SEQ NUMC 3
TEXT 1 Types CHAR255 CHAR 255

 

ZEXCEL_T_COLOR

ZEXCEL_S_COLOR

FIELDNAME 1 Types FIELDNAME
COLOR 1 Types UAC_COLOR

 

FUNCTION zdk_download_excel .
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_TITLE) TYPE  CHAR255
*"     VALUE(IT_HEADER) TYPE  ZEXCEL_T_HEADER
*"     REFERENCE(IT_EXCEL) TYPE  STANDARD TABLE
*"     REFERENCE(IT_COLOR) TYPE  ZEXCEL_T_COLOR OPTIONAL
*"     REFERENCE(IV_TO_TEXT) TYPE  BOOLE_D DEFAULT 'X'
*"     REFERENCE(IV_NO_FILTER) TYPE  BOOLE_D DEFAULT 'X'
*"     VALUE(IT_FIELDCAT) TYPE  LVC_T_FCAT OPTIONAL
*"     REFERENCE(IV_VISIBLE) TYPE  BOOLEAN_FLG OPTIONAL
*"----------------------------------------------------------------------

  DATA lv_workbooks TYPE ole2_object,        " list of workbooks
         lv_workbook  TYPE ole2_object,        " Excel object
         lv_sheet     TYPE ole2_object,        " Excel object
         lv_excel     TYPE ole2_object.        " Excel object

  DATA lv_file     TYPE string,
         lv_path     TYPE string,
         lv_fullpath TYPE string,
         lv_action   TYPE i.

*--- Get Desktop Path
  CALL METHOD cl_gui_frontend_services=>get_desktop_directory
    CHANGING
      desktop_directory lv_path.

  CALL METHOD cl_gui_cfw=>flush.

*--- get file path.
  CALL METHOD cl_gui_frontend_services=>file_save_dialog
    EXPORTING
      window_title      'Download Path'
      file_filter       'Excel files|*.xlsx;*.xls'
      initial_directory lv_path
    CHANGING
      filename          lv_file
      path              lv_path
      fullpath          lv_fullpath
      user_action       lv_action.

  IF lv_action EQ cl_gui_frontend_services=>action_cancel.
    EXIT.
  ENDIF.

  PERFORM prepare_excel     USING   lv_excel
                                    lv_workbooks
                                    lv_workbook
                                    lv_sheet
                                    iv_title
                                    1              " Sheet Number
                                    lv_fullpath
                                    iv_visible.

*--- Set Style
  PERFORM set_excel_style   USING   lv_excel
                                    lv_sheet
                                    iv_to_text
                                    iv_no_filter
                                    it_header[]
                                    it_excel[]
                                    it_color[].

  PERFORM print_excel       USING   lv_excel
                                    lv_sheet
                                    iv_to_text
                                    iv_no_filter
                                    lv_fullpath
                                    it_header[]
                                    it_excel[]
                                    it_fieldcat[].

  PERFORM save_excel        USING   lv_excel
                                    lv_workbooks
                                    lv_workbook
                                    lv_fullpath.

  MESSAGE s001(00WITH '엑셀파일이 다운로드 되었습니다.'.
  PERFORM open_excel USING lv_fullpath.

  FREE OBJECT lv_sheetlv_workbooklv_workbookslv_excel.
  CLEAR lv_sheetlv_workbooklv_workbookslv_excel.

ENDFUNCTION.
*&---------------------------------------------------------------------*
*&      Form  prepare_excel
*&---------------------------------------------------------------------*
FORM prepare_excel  USING  pv_excel
                           pv_workbooks
                           pv_workbook
                           pv_sheet
                           pv_sheetname
                           pv_sheetnum TYPE i
                           pv_fullpath
                           pv_visible.

  DATA lv_sheets TYPE ole2_object,        " Excel object
         lv_sheet  TYPE ole2_object.        " Excel object

  CASE pv_sheetnum.
    WHEN 0.
    WHEN 1.
      CREATE OBJECT pv_excel 'Excel.Application' NO FLUSH.
      CALL METHOD OF pv_excel 'WORKBOOKS' pv_workbooks.
      CALL METHOD OF pv_workbooks 'Add'.

      IF pv_visible IS NOT INITIAL.
        SET PROPERTY OF pv_excel 'VISIBLE'        1.
      ELSE.
        SET PROPERTY OF pv_excel 'VISIBLE'        0.
      ENDIF.

      SET PROPERTY OF pv_excel 'DisplayAlerts'  0.
      GET PROPERTY OF pv_excel 'ActiveWorkbook' pv_workbook.

*      SET PROPERTY OF pv_workbook 'CheckCompatibility' = 1.

      CALL METHOD OF pv_workbook
          'Worksheets' pv_sheet
        EXPORTING
          #1           pv_sheetnum.

    WHEN OTHERS.
      GET PROPERTY OF pv_workbook 'Worksheets' lv_sheets.

*--- 활성화 된 Sheet의 앞에만 생성됨. 해결방안 찾을 수가 없네;;

      CALL METHOD OF pv_workbook
          'Worksheets' pv_sheet
        EXPORTING
          #1           pv_sheetnum.

      CALL METHOD OF pv_sheet 'Activate'.
      CALL METHOD OF lv_sheets 'Add' pv_sheet.
  ENDCASE.

  CALL METHOD OF pv_sheet 'Activate'.

  IF pv_sheetname IS NOT INITIAL.
    SET PROPERTY OF pv_sheet 'Name' pv_sheetname.
  ENDIF.

ENDFORM.                    "prepare_excel
*&---------------------------------------------------------------------*
*&      Form  print_excel
*&---------------------------------------------------------------------*
FORM print_excel  USING    pv_excel
                           pv_sheet
                           pv_to_text
                           pv_no_filter
                           pv_filename
                           pt_header   TYPE zexcel_t_header
                           pt_data     TYPE STANDARD TABLE
                           pt_fieldcat TYPE lvc_t_fcat.

  DATA lo_range      TYPE ole2_object.
  DATA lo_ole_obj    TYPE ole2_object.

  DATA lv_char_tab   TYPE abap_char1
                         VALUE cl_abap_char_utilities=>horizontal_tab,
         lt_excel_tab  TYPE truxs_t_text_data,
         ls_excel_line LIKE LINE OF lt_excel_tab.

  DATA lv_str        TYPE char255.

  DATA lt_comps      TYPE abap_component_tab WITH HEADER LINE.
  DATA ls_fieldcat   LIKE LINE OF pt_fieldcat.

  FIELD-SYMBOLS <ls_column> LIKE LINE OF pt_header,
                  <ls_line>   TYPE any,
                  <lv_value>  TYPE any,
                  <lv_waers>  TYPE any.

*--- Set header
  IF pt_header IS NOT INITIAL.

    SORT pt_header BY row DESCENDING.
    READ TABLE pt_header INDEX ASSIGNING <ls_column>.

    SORT pt_header BY row.

    LOOP AT pt_header ASSIGNING <ls_column>.

      IF ls_excel_line IS INITIAL.
        ls_excel_line <ls_column>-text.
      ELSE.
        CONCATENATE ls_excel_line lv_char_tab <ls_column>-text
               INTO ls_excel_line.
      ENDIF.
      AT END OF row.
        APPEND ls_excel_line TO lt_excel_tab.
        CLEAR  ls_excel_line.
      ENDAT.
    ENDLOOP.
  ENDIF.

*--- Get field list
  IF pt_data[] IS NOT INITIAL.
    PERFORM get_components_deep USING    pt_data
                                CHANGING lt_comps[].
  ENDIF.

  IF pt_fieldcat[] IS NOT INITIAL.
    SORT pt_fieldcat BY fieldname.
  ENDIF.

*--- Append data.
  LOOP AT pt_data ASSIGNING <ls_line>.
    LOOP AT lt_comps.
      CLEAR lv_str.
      ASSIGN COMPONENT lt_comps-name OF STRUCTURE <ls_line>
                    TO <lv_value>.
      CHECK <lv_value> IS ASSIGNED.

      CLEAR ls_fieldcat.
      READ TABLE pt_fieldcat INTO ls_fieldcat
                             WITH KEY fieldname lt_comps-name
                             BINARY SEARCH.
      CHECK sy-subrc IS INITIAL.
      CASE ls_fieldcat-datatype.
        WHEN 'CURR'.
          ASSIGN COMPONENT ls_fieldcat-cfieldname OF STRUCTURE <ls_line>
                        TO <lv_waers>.

          IF <lv_waers> IS ASSIGNED.
            WRITE <lv_value> TO lv_str CURRENCY <lv_waers>.
            UNASSIGN <lv_waers>.
          ELSE.
            lv_str <lv_value>.
          ENDIF.
          IF <lv_value> NE 0.
            CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
              CHANGING
                value lv_str.
          ENDIF.
        WHEN OTHERS.
          lv_str <lv_value>.
          CASE ls_fieldcat-inttype.
            WHEN 'P'.
              IF <lv_value> NE 0.
                CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
                  CHANGING
                    value lv_str.
              ENDIF.
          ENDCASE.
      ENDCASE.

      CONDENSE lv_str.

      IF ls_excel_line IS INITIAL.
        ls_excel_line lv_str.
      ELSE.
        CONCATENATE ls_excel_line
                    lv_str
               INTO ls_excel_line.
      ENDIF.

      CONCATENATE ls_excel_line
                  cl_abap_char_utilities=>horizontal_tab
             INTO ls_excel_line.

      UNASSIGN <lv_value>.
    ENDLOOP.
    CONDENSE ls_excel_line.
    APPEND ls_excel_line TO lt_excel_tab.
    CLEAR ls_excel_line.
  ENDLOOP.

  PERFORM excel_paste       USING   lt_excel_tab[]
                                    pv_sheet .

  GET PROPERTY OF pv_sheet 'UsedRange'  lo_range.

*--- Set Column Width
  GET PROPERTY OF lo_range  'Columns' lo_ole_obj.
  CALL METHOD OF lo_ole_obj 'AutoFit'.
  CLEARlo_ole_obj.

**--- Set Cursor initial location
*  PERFORM set_excel_range USING 1 1 1 1 pv_sheet
*                          CHANGING lo_range.
*
*  CALL METHOD OF lo_range
*    'SELECT'.

ENDFORM.                    " PRINT_EXCEL
*&---------------------------------------------------------------------*
*&      Form  SET_EXCEL_STYLE
*&---------------------------------------------------------------------*
FORM set_excel_style  USING   pv_excel
                              pv_sheet
                              pv_to_text
                              pv_no_filter
                              pt_header   TYPE zexcel_t_header
                              pt_data     TYPE STANDARD TABLE
                              pt_color    TYPE zexcel_t_color.

  DATA lo_range   TYPE ole2_object,
         lo_header  TYPE ole2_object,  " Font Object
         lo_ole_obj TYPE ole2_object,  " Font Object
         lo_window  TYPE ole2_object.  " Cell color

  DATA ls_color   LIKE LINE OF pt_color.
  DATA ls_header  LIKE LINE OF pt_header.
  DATA lt_header  TYPE zexcel_t_header WITH HEADER LINE.
  DATA lv_rows    TYPE i.
  DATA lv_cols    TYPE i.
  DATA lv_header  TYPE i.
  DATA lv_color   TYPE string.

  DATA lt_comps   TYPE abap_component_tab WITH HEADER LINE.

  lt_header[] pt_header[].

  SORT lt_header BY row.
  DELETE ADJACENT DUPLICATES FROM lt_header COMPARING row.

  LOOP AT lt_header.
    CLEAR lv_header.
    LOOP AT pt_header INTO ls_header
                      WHERE row lt_header-row.
      lv_header lv_header + 1.
    ENDLOOP.
    IF lv_cols < lv_header.
      lv_cols lv_header.
    ENDIF.
  ENDLOOP.

  DESCRIBE TABLE pt_data   LINES lv_rows.
  DESCRIBE TABLE lt_header LINES lv_header.

  lv_rows lv_rows + lv_header.

  PERFORM set_excel_range USING    lv_rows lv_cols pv_sheet
                          CHANGING lo_range.

*--- Header
  IF pt_header[] IS NOT INITIAL.
    GET PROPERTY OF lo_range    'Rows'  lo_header
    EXPORTING
      #1       1.

*--- FreezePane
    GET PROPERTY OF pv_excel   'ActiveWindow' lo_window.
    SET PROPERTY OF lo_window  'FreezePanes'  0.

    SET PROPERTY OF lo_window  'SplitColumn ' 0.
    SET PROPERTY OF lo_window  'SplitRow '    1.
    SET PROPERTY OF lo_window  'FreezePanes'  1.

    CALL METHOD OF lo_header 'Interior' lo_ole_obj.

* Color code Hex -> number https://www.htmlcsscolor.com/hex/DDEBBC

    CALL FUNCTION 'ZDK_RGB_TO_OLE_COLOR'
      EXPORTING
        iv_rgb        'DDEBBC'
      IMPORTING
        ev_color      lv_color
      EXCEPTIONS
        invalid_color 1
        OTHERS        2.
    IF sy-subrc IS INITIAL.
      SET PROPERTY OF lo_ole_obj 'Color'    lv_color.
    ENDIF.
  ENDIF.

*--- Set Range property 'number' -> 'text'
  IF pv_to_text IS NOT INITIAL.
    SET PROPERTY OF lo_range 'NumberFormat' '@'.
  ENDIF.

*--- Set Border
  GET PROPERTY OF lo_range   'Borders'   lo_ole_obj.
  SET PROPERTY OF lo_ole_obj 'Linestyle' '1'.
  CLEARlo_ole_obj.

*--- Set Font
  CALL METHOD OF lo_range 'FONT' lo_ole_obj.
  SET PROPERTY OF lo_ole_obj 'Size' '9'.
  CLEARlo_ole_obj.

*--- Set Filter
  IF pv_no_filter IS INITIAL.
    CALL METHOD OF lo_range 'AutoFilter'.
  ENDIF.

*--- Set Column color
  IF pt_color[] IS NOT INITIAL.
    CALL FUNCTION 'ZDK_GET_COMPONENTS'
      EXPORTING
        it_data  pt_data
      IMPORTING
        et_comps lt_comps[].

    lv_header lv_header + 1.
    LOOP AT pt_color INTO ls_color.
      READ TABLE lt_comps WITH KEY name ls_color-fieldname.
      CHECK sy-subrc IS INITIAL.
      lv_cols sy-tabix.

      PERFORM set_excel_range USING    lv_header lv_cols lv_rows lv_cols pv_sheet
                              CHANGING lo_range.

      CALL FUNCTION 'ZDK_RGB_TO_OLE_COLOR'
        EXPORTING
          iv_rgb        ls_color-color
        IMPORTING
          ev_color      lv_color
        EXCEPTIONS
          invalid_color 1
          OTHERS        2.
      IF sy-subrc IS INITIAL.
        CALL METHOD OF lo_range 'Interior' lo_ole_obj.
        SET PROPERTY OF lo_ole_obj 'Color'    lv_color.
      ENDIF.
    ENDLOOP.
  ENDIF.

ENDFORM.                    " SET_EXCEL_STYLE
*&---------------------------------------------------------------------*
*&      Form  SET_EXCEL_RANGE
*&---------------------------------------------------------------------*
FORM set_excel_range  USING    pv_row_fr  pv_col_fr
                               pv_row_to  pv_col_to
                               pv_sheet
                      CHANGING pv_range.

  DATA lo_cell_fr TYPE ole2_object,
         lo_cell_to TYPE ole2_object.

*--- set range
  CALL METHOD OF pv_sheet
      'Cells'  lo_cell_fr
    EXPORTING
      #1       pv_row_fr
      #2       pv_col_fr.

  CALL METHOD OF pv_sheet
      'Cells'  lo_cell_to
    EXPORTING
      #1       pv_row_to
      #2       pv_col_to.

  CALL METHOD OF pv_sheet
      'RANGE'  pv_range
    EXPORTING
      #1       lo_cell_fr
      #2       lo_cell_to.

ENDFORM.                    " SET_EXCElv_RANGE
*&---------------------------------------------------------------------*
*&      Form  EXCEl_PASTE
*&---------------------------------------------------------------------*
FORM excel_paste  USING    pt_excel TYPE STANDARD TABLE
                           pv_sheet.
  DATAlv_return TYPE i.

  CALL METHOD cl_gui_frontend_services=>clipboard_export
    IMPORTING
      data                 pt_excel
    CHANGING
      rc                   lv_return
    EXCEPTIONS
      cntl_error           1
      error_no_gui         2
      not_supported_by_gui 3
      no_authority         4
      OTHERS               5.

*--- paste data
  CALL METHOD OF pv_sheet
    'PASTE'.

ENDFORM.                    " EXCEL_PASTE
*&---------------------------------------------------------------------*
*&      Form  SAVE_EXCEL
*&---------------------------------------------------------------------*
FORM save_excel  USING    pv_excel
                          pv_workbooks
                          pv_sheet
                          pv_filename.

*--- Save Excel
  CALL METHOD OF pv_sheet
    'SAVEAS'
    EXPORTING
      #1 pv_filename
      #2 51.

*   https://docs.microsoft.com/en-us/office/vba/api/excel.xlfileformat
*  xlOpenXMLWorkbook  51  Open XML Workbook
*  xlOpenXMLStrictWorkbook  61 (&H3D) Strict Open XML

  CALL METHOD OF pv_workbooks
    'CLOSE'.
  CALL METHOD OF pv_excel
    'QUIT'.

ENDFORM.                    " SAVE_EXCEL
*&---------------------------------------------------------------------*
*&      Form  OPEN_EXCEL
*&---------------------------------------------------------------------*
FORM open_excel  USING    pv_fullpath.

  DATA lv_books TYPE ole2_object,        " list of workbooks
         lv_excel TYPE ole2_object.        " Excel object

  CREATE OBJECT lv_excel 'Excel.Application'.
  SET PROPERTY OF lv_excel 'VISIBLE'   1.

  CALL METHOD OF lv_excel
      'Workbooks' lv_books.

  CALL METHOD OF lv_books
    'OPEN'
    EXPORTING
      #1 pv_fullpath.

ENDFORM.                    "open_excel
*&---------------------------------------------------------------------*
*&      Form  get_components_deep
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_DATA    text
*      -->PT_COMPS   text
*----------------------------------------------------------------------*
FORM get_components_deep USING    pt_data
                         CHANGING pt_comps TYPE abap_component_tab.

  DATA lv_type      TYPE c,
         lo_tabledesc TYPE REF TO cl_abap_tabledescr,
         lo_strucdesc TYPE REF TO cl_abap_structdescr.

  DATA lt_comps     TYPE abap_component_tab WITH HEADER LINE,
         lt_temp      TYPE abap_component_tab WITH HEADER LINE,
         ls_component TYPE abap_compdescr.

  DATA lo_ref       TYPE REF TO data.

  DESCRIBE FIELD pt_data TYPE lv_type.

  CASE lv_type.
    WHEN 'u' OR 'v'.
      lo_strucdesc ?= cl_abap_typedescr=>describe_by_datapt_data ).
    WHEN 'h'.
      lo_tabledesc ?= cl_abap_typedescr=>describe_by_datapt_data ).
      lo_strucdesc ?= lo_tabledesc->get_table_line_type).
  ENDCASE.

  lt_comps[] lo_strucdesc->get_components).

  LOOP AT lt_comps.
    IF lt_comps-as_include IS NOT INITIAL.
      lo_strucdesc ?= lt_comps-type.
      lt_temp[] lo_strucdesc->get_components).
      APPEND LINES OF lt_temp TO pt_comps.
    ELSE.
      APPEND lt_comps TO pt_comps.
    ENDIF.
  ENDLOOP.

ENDFORM.                    "get_components_deep

 

 

XlFileFormat enumeration (Excel)

Office VBA reference topic

docs.microsoft.com

 

'SAP > ABAP' 카테고리의 다른 글

Get Structure/Table sub-components  (0) 2014.09.12
Excel DATEVALUE to DATE conversion  (0) 2014.08.29
[Macro] Range 선언  (0) 2014.02.18
Chartset 변경.  (0) 2014.01.15
MM 단위 환산.  (0) 2013.03.14