class ZCL_EXCEL_WORKSHEET definition public final create public . public section. *"* public components of class ZCL_EXCEL_WORKSHEET *"* do not include other source files here!!! type-pools ABAP . interfaces ZIF_EXCEL_SHEET_PROPERTIES . interfaces ZIF_EXCEL_SHEET_PROTECTION . interfaces ZIF_EXCEL_SHEET_VBA_PROJECT . constants C_BREAK_COLUMN type ZEXCEL_BREAK value 2. "#EC NOTEXT constants C_BREAK_NONE type ZEXCEL_BREAK value 0. "#EC NOTEXT constants C_BREAK_ROW type ZEXCEL_BREAK value 1. "#EC NOTEXT data EXCEL type ref to ZCL_EXCEL read-only . data PRINT_GRIDLINES type ZEXCEL_PRINT_GRIDLINES read-only value ABAP_FALSE. "#EC NOTEXT . data SHEET_CONTENT type ZEXCEL_T_CELL_DATA . data SHEET_CONTENT_MERGE type ZEXCEL_T_CELL_DATA_UNSORTED . data SHEET_SETUP type ref to ZCL_EXCEL_SHEET_SETUP . data SHOW_GRIDLINES type ZEXCEL_SHOW_GRIDLINES read-only value ABAP_TRUE. "#EC NOTEXT . data SHOW_ROWCOLHEADERS type ZEXCEL_SHOW_GRIDLINES read-only value ABAP_TRUE. "#EC NOTEXT . data STYLES type ZEXCEL_T_SHEET_STYLE . data TABCOLOR type ZEXCEL_S_TABCOLOR read-only . methods ADD_DRAWING importing !IP_DRAWING type ref to ZCL_EXCEL_DRAWING . methods ADD_NEW_CONDITIONAL_STYLE returning value(EO_CONDITIONAL_STYLE) type ref to ZCL_EXCEL_STYLE_CONDITIONAL . methods ADD_NEW_DATA_VALIDATION returning value(EO_DATA_VALIDATION) type ref to ZCL_EXCEL_DATA_VALIDATION . methods ADD_NEW_RANGE returning value(EO_RANGE) type ref to ZCL_EXCEL_RANGE . methods BIND_ALV importing !IO_ALV type ref to OBJECT !IT_TABLE type STANDARD TABLE !I_TOP type I default 1 !I_LEFT type I default 1 !TABLE_STYLE type ZEXCEL_TABLE_STYLE optional raising ZCX_EXCEL . type-pools SLIS . type-pools SOI . methods BIND_ALV_OLE2 importing !I_DOCUMENT_URL type CHAR255 default SPACE !I_XLS type C default SPACE !I_SAVE_PATH type STRING !IO_ALV type ref to CL_GUI_ALV_GRID !IT_LISTHEADER type SLIS_T_LISTHEADER optional !I_TOP type I default 1 !I_LEFT type I default 1 !I_COLUMNS_HEADER type C default 'X' !I_COLUMNS_AUTOFIT type C default 'X' !I_FORMAT_COL_HEADER type SOI_FORMAT_ITEM optional !I_FORMAT_SUBTOTAL type SOI_FORMAT_ITEM optional !I_FORMAT_TOTAL type SOI_FORMAT_ITEM optional exceptions MISS_GUIDE EX_TRANSFER_KKBLO_ERROR FATAL_ERROR INV_DATA_RANGE DIM_MISMATCH_VKEY DIM_MISMATCH_SEMA ERROR_IN_SEMA . methods BIND_TABLE importing !IP_TABLE type STANDARD TABLE !IT_FIELD_CATALOG type ZEXCEL_T_FIELDCATALOG optional !IS_TABLE_SETTINGS type ZEXCEL_S_TABLE_SETTINGS optional exporting !ES_TABLE_SETTINGS type ZEXCEL_S_TABLE_SETTINGS raising ZCX_EXCEL . methods CALCULATE_COLUMN_WIDTHS raising ZCX_EXCEL . methods CHANGE_CELL_STYLE importing !IP_COLUMN type SIMPLE !IP_ROW type ZEXCEL_CELL_ROW !IP_COMPLETE type ZEXCEL_S_CSTYLE_COMPLETE optional !IP_XCOMPLETE type ZEXCEL_S_CSTYLEX_COMPLETE optional !IP_FONT type ZEXCEL_S_CSTYLE_FONT optional !IP_XFONT type ZEXCEL_S_CSTYLEX_FONT optional !IP_FILL type ZEXCEL_S_CSTYLE_FILL optional !IP_XFILL type ZEXCEL_S_CSTYLEX_FILL optional !IP_BORDERS type ZEXCEL_S_CSTYLE_BORDERS optional !IP_XBORDERS type ZEXCEL_S_CSTYLEX_BORDERS optional !IP_ALIGNMENT type ZEXCEL_S_CSTYLE_ALIGNMENT optional !IP_XALIGNMENT type ZEXCEL_S_CSTYLEX_ALIGNMENT optional !IP_NUMBER_FORMAT_FORMAT_CODE type ZEXCEL_NUMBER_FORMAT optional !IP_PROTECTION type ZEXCEL_S_CSTYLE_PROTECTION optional !IP_XPROTECTION type ZEXCEL_S_CSTYLEX_PROTECTION optional !IP_FONT_BOLD type FLAG optional !IP_FONT_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_FONT_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_FONT_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_FONT_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_FONT_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_FONT_FAMILY type ZEXCEL_STYLE_FONT_FAMILY optional !IP_FONT_ITALIC type FLAG optional !IP_FONT_NAME type ZEXCEL_STYLE_FONT_NAME optional !IP_FONT_SCHEME type ZEXCEL_STYLE_FONT_SCHEME optional !IP_FONT_SIZE type ZEXCEL_STYLE_FONT_SIZE optional !IP_FONT_STRIKETHROUGH type FLAG optional !IP_FONT_UNDERLINE type FLAG optional !IP_FONT_UNDERLINE_MODE type ZEXCEL_STYLE_FONT_UNDERLINE optional !IP_FILL_FILLTYPE type ZEXCEL_FILL_TYPE optional !IP_FILL_ROTATION type ZEXCEL_ROTATION optional !IP_FILL_FGCOLOR type ZEXCEL_S_STYLE_COLOR optional !IP_FILL_FGCOLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_FILL_FGCOLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_FILL_FGCOLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_FILL_FGCOLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_FILL_BGCOLOR type ZEXCEL_S_STYLE_COLOR optional !IP_FILL_BGCOLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_FILL_BGCOLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_FILL_BGCOLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_FILL_BGCOLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_ALLBORDERS type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_ALLBORDERS type ZEXCEL_S_CSTYLEX_BORDER optional !IP_BORDERS_DIAGONAL type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_DIAGONAL type ZEXCEL_S_CSTYLEX_BORDER optional !IP_BORDERS_DIAGONAL_MODE type ZEXCEL_DIAGONAL optional !IP_BORDERS_DOWN type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_DOWN type ZEXCEL_S_CSTYLEX_BORDER optional !IP_BORDERS_LEFT type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_LEFT type ZEXCEL_S_CSTYLEX_BORDER optional !IP_BORDERS_RIGHT type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_RIGHT type ZEXCEL_S_CSTYLEX_BORDER optional !IP_BORDERS_TOP type ZEXCEL_S_CSTYLE_BORDER optional !IP_XBORDERS_TOP type ZEXCEL_S_CSTYLEX_BORDER optional !IP_ALIGNMENT_HORIZONTAL type ZEXCEL_ALIGNMENT optional !IP_ALIGNMENT_VERTICAL type ZEXCEL_ALIGNMENT optional !IP_ALIGNMENT_TEXTROTATION type ZEXCEL_TEXT_ROTATION optional !IP_ALIGNMENT_WRAPTEXT type FLAG optional !IP_ALIGNMENT_SHRINKTOFIT type FLAG optional !IP_ALIGNMENT_INDENT type ZEXCEL_INDENT optional !IP_PROTECTION_HIDDEN type ZEXCEL_CELL_PROTECTION optional !IP_PROTECTION_LOCKED type ZEXCEL_CELL_PROTECTION optional !IP_BORDERS_ALLBORDERS_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_ALLBORDERS_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_ALLBO_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_ALLBO_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_ALLBO_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_ALLBO_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_DIAGONAL_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_DIAGONAL_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_DIAGONAL_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_DIAGONAL_COLOR_INDE type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_DIAGONAL_COLOR_THEM type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_DIAGONAL_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_DOWN_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_DOWN_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_DOWN_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_DOWN_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_DOWN_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_DOWN_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_LEFT_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_LEFT_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_LEFT_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_LEFT_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_LEFT_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_LEFT_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_RIGHT_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_RIGHT_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_RIGHT_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_RIGHT_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_RIGHT_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_RIGHT_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional !IP_BORDERS_TOP_STYLE type ZEXCEL_BORDER optional !IP_BORDERS_TOP_COLOR type ZEXCEL_S_STYLE_COLOR optional !IP_BORDERS_TOP_COLOR_RGB type ZEXCEL_STYLE_COLOR_ARGB optional !IP_BORDERS_TOP_COLOR_INDEXED type ZEXCEL_STYLE_COLOR_INDEXED optional !IP_BORDERS_TOP_COLOR_THEME type ZEXCEL_STYLE_COLOR_THEME optional !IP_BORDERS_TOP_COLOR_TINT type ZEXCEL_STYLE_COLOR_TINT optional returning value(EP_GUID) type ZEXCEL_CELL_STYLE raising ZCX_EXCEL . methods CONSTRUCTOR importing !IP_EXCEL type ref to ZCL_EXCEL !IP_TITLE type ZEXCEL_SHEET_TITLE optional raising ZCX_EXCEL . methods DELETE_MERGE . methods FREEZE_PANES importing !IP_NUM_COLUMNS type I optional !IP_NUM_ROWS type I optional raising ZCX_EXCEL . methods GET_ACTIVE_CELL returning value(EP_ACTIVE_CELL) type STRING raising ZCX_EXCEL . methods GET_CELL importing !IP_COLUMN type SIMPLE !IP_ROW type ZEXCEL_CELL_ROW exporting !EP_VALUE type ZEXCEL_CELL_VALUE !EP_RC type SYSUBRC !EP_STYLE type ref to ZCL_EXCEL_STYLE !EP_GUID type ZEXCEL_CELL_STYLE raising ZCX_EXCEL . methods GET_COLUMN_DIMENSION importing !IP_COLUMN type SIMPLE returning value(R_COLUMN_DIMENSION) type ref to ZCL_EXCEL_WORKSHEET_COLUMNDIME raising ZCX_EXCEL . methods GET_COLUMN_DIMENSIONS returning value(R_COLUMN_DIMENSION) type ZEXCEL_T_WORKSHEET_COLUMNDIME . methods GET_COND_STYLES_ITERATOR returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_DATA_VALIDATIONS_ITERATOR returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_DATA_VALIDATIONS_SIZE returning value(EP_SIZE) type I . methods GET_DEFAULT_COLUMN_DIMENSION returning value(R_COLUMN_DIMENSION) type ref to ZCL_EXCEL_WORKSHEET_COLUMNDIME . methods GET_DEFAULT_EXCEL_DATE_FORMAT returning value(EP_DEFAULT_EXCEL_DATE_FORMAT) type ZEXCEL_NUMBER_FORMAT . methods GET_DEFAULT_EXCEL_TIME_FORMAT returning value(EP_DEFAULT_EXCEL_TIME_FORMAT) type ZEXCEL_NUMBER_FORMAT . methods GET_DEFAULT_ROW_DIMENSION returning value(R_ROW_DIMENSION) type ref to ZCL_EXCEL_WORKSHEET_ROWDIMENSI . methods GET_DIMENSION_RANGE returning value(EP_DIMENSION_RANGE) type STRING raising ZCX_EXCEL . methods GET_DRAWINGS importing !IP_TYPE type ZEXCEL_DRAWING_TYPE optional returning value(R_DRAWINGS) type ref to ZCL_EXCEL_DRAWINGS . methods GET_DRAWINGS_ITERATOR importing !IP_TYPE type ZEXCEL_DRAWING_TYPE returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_FREEZE_CELL exporting !EP_ROW type ZEXCEL_CELL_ROW !EP_COLUMN type ZEXCEL_CELL_COLUMN . methods GET_GUID returning value(EP_GUID) type OLTPGUID16 . methods GET_HIGHEST_COLUMN returning value(R_HIGHEST_COLUMN) type ZEXCEL_CELL_COLUMN raising ZCX_EXCEL . methods GET_HIGHEST_ROW returning value(R_HIGHEST_ROW) type INT4 raising ZCX_EXCEL . methods GET_HYPERLINKS_ITERATOR returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_HYPERLINKS_SIZE returning value(EP_SIZE) type I . methods GET_MERGE returning value(MERGE_RANGE) type STRING_TABLE raising ZCX_EXCEL . methods GET_RANGES_ITERATOR returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_ROW_DIMENSION importing !IP_ROW type INT4 returning value(R_ROW_DIMENSION) type ref to ZCL_EXCEL_WORKSHEET_ROWDIMENSI . methods GET_ROW_DIMENSIONS returning value(R_ROW_DIMENSION) type ZEXCEL_T_WORKSHEET_ROWDIMENSIO . methods GET_TABCOLOR returning value(EV_TABCOLOR) type ZEXCEL_S_TABCOLOR . methods GET_TABLES_ITERATOR returning value(EO_ITERATOR) type ref to CL_OBJECT_COLLECTION_ITERATOR . methods GET_TABLES_SIZE returning value(EP_SIZE) type I . methods GET_TITLE importing !IP_ESCAPED type FLAG default '' returning value(EP_TITLE) type ZEXCEL_SHEET_TITLE . methods SET_CELL importing !IP_COLUMN type SIMPLE !IP_ROW type ZEXCEL_CELL_ROW !IP_VALUE type SIMPLE optional !IP_FORMULA type ZEXCEL_CELL_FORMULA optional !IP_STYLE type ZEXCEL_CELL_STYLE optional !IP_HYPERLINK type ref to ZCL_EXCEL_HYPERLINK optional !IP_DATA_TYPE type ZEXCEL_CELL_DATA_TYPE optional !IP_ABAP_TYPE type ABAP_TYPEKIND optional raising ZCX_EXCEL . methods SET_CELL_STYLE importing !IP_COLUMN type SIMPLE !IP_ROW type ZEXCEL_CELL_ROW !IP_STYLE type ZEXCEL_CELL_STYLE raising ZCX_EXCEL . methods SET_COLUMN_WIDTH importing !IP_COLUMN type SIMPLE !IP_WIDTH_FIX type SIMPLE default 0 !IP_WIDTH_AUTOSIZE type FLAG default 'X' raising ZCX_EXCEL . methods SET_DEFAULT_EXCEL_DATE_FORMAT importing !IP_DEFAULT_EXCEL_DATE_FORMAT type ZEXCEL_NUMBER_FORMAT raising ZCX_EXCEL . methods SET_MERGE importing !IP_COLUMN_START type ZEXCEL_CELL_COLUMN_ALPHA optional !IP_COLUMN_END type ZEXCEL_CELL_COLUMN_ALPHA optional !IP_ROW type ZEXCEL_CELL_ROW optional !IP_ROW_TO type ZEXCEL_CELL_ROW optional raising ZCX_EXCEL . methods SET_PRINT_GRIDLINES importing !I_PRINT_GRIDLINES type ZEXCEL_PRINT_GRIDLINES . methods SET_ROW_HEIGHT importing !IP_ROW type SIMPLE !IP_HEIGHT_FIX type SIMPLE raising ZCX_EXCEL . methods SET_SHOW_GRIDLINES importing !I_SHOW_GRIDLINES type ZEXCEL_SHOW_GRIDLINES . methods SET_SHOW_ROWCOLHEADERS importing !I_SHOW_ROWCOLHEADERS type ZEXCEL_SHOW_ROWCOLHEADER . methods SET_TABCOLOR importing !IV_TABCOLOR type ZEXCEL_S_TABCOLOR . methods SET_TABLE importing !IP_TABLE type STANDARD TABLE !IP_HDR_STYLE type ZEXCEL_CELL_STYLE optional !IP_BODY_STYLE type ZEXCEL_CELL_STYLE optional !IP_TABLE_TITLE type STRING !IP_TOP_LEFT_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA default 'B' !IP_TOP_LEFT_ROW type ZEXCEL_CELL_ROW default 3 !IP_TRANSPOSE type XFELD optional !IP_NO_HEADER type XFELD optional raising ZCX_EXCEL . methods SET_TITLE importing !IP_TITLE type ZEXCEL_SHEET_TITLE raising ZCX_EXCEL . *"* protected components of class ZCL_EXCEL_WORKSHEET *"* do not include other source files here!!! protected section. private section. *"* private components of class ZCL_EXCEL_WORKSHEET *"* do not include other source files here!!! data ACTIVE_CELL type ZEXCEL_S_CELL_DATA . data CHARTS type ref to ZCL_EXCEL_DRAWINGS . data COLUMN_DIMENSIONS type ZEXCEL_T_WORKSHEET_COLUMNDIME . data CONDITIONAL_STYLES type ref to ZCL_EXCEL_STYLES_CONDITIONAL . data DATA_VALIDATIONS type ref to ZCL_EXCEL_DATA_VALIDATIONS . data DEFAULT_COLUMN_DIMENSION type ref to ZCL_EXCEL_WORKSHEET_COLUMNDIME . data DEFAULT_EXCEL_DATE_FORMAT type ZEXCEL_NUMBER_FORMAT . data DEFAULT_EXCEL_TIME_FORMAT type ZEXCEL_NUMBER_FORMAT . data DEFAULT_ROW_DIMENSION type ref to ZCL_EXCEL_WORKSHEET_ROWDIMENSI . data DRAWINGS type ref to ZCL_EXCEL_DRAWINGS . data FREEZE_PANE_CELL_COLUMN type ZEXCEL_CELL_COLUMN . data FREEZE_PANE_CELL_ROW type ZEXCEL_CELL_ROW . data GUID type OLTPGUID16 . data HYPERLINKS type ref to CL_OBJECT_COLLECTION . data LOWER_CELL type ZEXCEL_S_CELL_DATA . data RANGES type ref to ZCL_EXCEL_RANGES . data ROW_DIMENSIONS type ZEXCEL_T_WORKSHEET_ROWDIMENSIO . data TABLES type ref to CL_OBJECT_COLLECTION . data TITLE type ZEXCEL_SHEET_TITLE value 'Worksheet'. "#EC NOTEXT . data UPPER_CELL type ZEXCEL_S_CELL_DATA . methods CALCULATE_CELL_WIDTH importing !IP_COLUMN type SIMPLE !IP_ROW type ZEXCEL_CELL_ROW returning value(EP_WIDTH) type I raising ZCX_EXCEL . methods GENERATE_TITLE returning value(EP_TITLE) type ZEXCEL_SHEET_TITLE . methods GET_VALUE_TYPE importing !IP_VALUE type SIMPLE exporting !EP_VALUE type SIMPLE !EP_VALUE_TYPE type ABAP_TYPEKIND . methods UPDATE_DIMENSION_RANGE raising ZCX_EXCEL . *"* local class implementation for public class *"* use this source file for the implementation part of *"* local helper classes *&---------------------------------------------------------------------* *& Class (Implementation) C_OI_PROXY_ERROR *&---------------------------------------------------------------------* CLASS C_OI_PROXY_ERROR IMPLEMENTATION. method constructor. * IMPORTING object_name TYPE c * method_name TYPE c. error_nr = ret_call_not_flushed. me->i_oi_error~error_code = c_oi_errors=>ret_call_not_flushed. me->i_oi_error~is_flushed = ' '. me->i_oi_error~has_failed = 'X'. me->i_oi_error~has_succeeded = ' '. me->message_id = 'SOFFICEINTEGRATION'. me->message_nr = '899'. me->param1 = object_name. me->param2 = method_name. endmethod. "constructor method i_oi_error~flush_error. if error_nr eq 0. me->i_oi_error~error_code = c_oi_errors=>ret_ok. me->i_oi_error~is_flushed = 'X'. me->i_oi_error~has_failed = ' '. me->i_oi_error~has_succeeded = 'X'. me->message_id = ''. me->message_nr = '000'. call method c_oi_errors=>translate_proxy_error_code EXPORTING errorcode = error_nr IMPORTING retcode = me->i_oi_error~error_code. elseif error_nr eq ret_call_not_flushed. "call still not flushed call method c_oi_errors=>translate_proxy_error_code EXPORTING errorcode = error_nr errorstring = me->param2 "method name objectname = me->param1 IMPORTING retcode = me->i_oi_error~error_code. else. me->i_oi_error~is_flushed = 'X'. me->i_oi_error~has_succeeded = ' '. me->i_oi_error~has_failed = 'X'. call method c_oi_errors=>translate_proxy_error_code EXPORTING errorcode = error_nr errorstring = error_string IMPORTING retcode = me->i_oi_error~error_code. call method c_oi_errors=>get_message IMPORTING message_id = me->message_id message_number = me->message_nr param1 = me->param1 param2 = me->param2 param3 = me->param3 param4 = me->param4. endif. endmethod. "i_oi_error~flush_error method i_oi_error~raise_message. * IMPORTING type TYPE c. * EXCEPTIONS message_raised flush_failed. if me->i_oi_error~has_succeeded is initial. if not me->i_oi_error~is_flushed is initial. message id message_id type type number message_nr with param1 param2 param3 param4 raising message_raised. else. raise flush_failed. endif. endif. endmethod. "i_oi_error~raise_message method i_oi_error~get_message. * EXPORTING message_id TYPE c * message_number TYPE c * param1 TYPE c * param2 TYPE c * param3 TYPE c * param4 TYPE c. param1 = me->param1. param2 = me->param2. param3 = me->param3. param4 = me->param4. message_id = me->message_id. message_number = me->message_nr. endmethod. "i_oi_error~get_message ENDCLASS. "C_OI_PROXY_ERROR *&---------------------------------------------------------------------* *& Class (Implementation) CL_GRID_ACCESSION *&---------------------------------------------------------------------* CLASS lcl_gui_alv_grid IMPLEMENTATION. method get_alv_attributes. create data et_table like io_grid->mt_outtab. et_table = io_grid->mt_outtab. endmethod. "get_data ENDCLASS. "CL_GRID_ACCESSION *"* use this source file for any type declarations (class *"* definitions, interfaces or data types) you need for method *"* implementation or private method's signature type-pools: SYDES. type-pools: SLIS. *--------------------------------------------------------------------* * CLASS c_oi_proxy_error *--------------------------------------------------------------------* * use for method bind_ALV *--------------------------------------------------------------------* class c_oi_proxy_error definition. public section. interfaces: i_oi_error. data: error_nr type i. data: error_string type sy-msgv1. methods: constructor importing object_name type c method_name type c. private section. constants: ret_call_not_flushed type i value -999999. data: message_id type sy-msgid, message_nr type sy-msgno, param1 type sy-msgv1, param2 type sy-msgv2, param3 type sy-msgv3, param4 type sy-msgv4. endclass. *--------------------------------------------------------------------* * CLASS lcl_gui_alv_grid *--------------------------------------------------------------------* * to get protected attribute and method of cl_gui_alv_grid * use for method bind_ALV *--------------------------------------------------------------------* class lcl_gui_alv_grid definition inheriting from cl_gui_alv_grid. public section. * get ALV grid data methods: get_alv_attributes importing Io_grid type ref to cl_gui_alv_grid " ALV grid exporting ET_table type ref to data. " dta table endclass. *"* use this source file for any macro definitions you need *"* in the implementation part of the class ABAP SLIS SOI method ZIF_EXCEL_SHEET_PROPERTIES~GET_STYLE. IF zif_excel_sheet_properties~style IS NOT INITIAL. ep_style = zif_excel_sheet_properties~style. ELSE. ep_style = me->excel->get_default_style( ). ENDIF. endmethod. method ZIF_EXCEL_SHEET_PROPERTIES~INITIALIZE. zif_excel_sheet_properties~show_zeros = zif_excel_sheet_properties=>c_showzero. zif_excel_sheet_properties~summarybelow = zif_excel_sheet_properties=>c_below_on. zif_excel_sheet_properties~summaryright = zif_excel_sheet_properties=>c_right_on. * inizialize zoomscale values ZIF_EXCEL_SHEET_PROPERTIES~zoomscale = 100. ZIF_EXCEL_SHEET_PROPERTIES~zoomscale_normal = 100. ZIF_EXCEL_SHEET_PROPERTIES~zoomscale_pagelayoutview = 100 . ZIF_EXCEL_SHEET_PROPERTIES~zoomscale_sheetlayoutview = 100 . endmethod. method ZIF_EXCEL_SHEET_PROPERTIES~SET_STYLE. zif_excel_sheet_properties~style = ip_style. endmethod. method ZIF_EXCEL_SHEET_PROTECTION~INITIALIZE. me->zif_excel_sheet_protection~protected = zif_excel_sheet_protection=>c_unprotected. CLEAR me->zif_excel_sheet_protection~password. me->zif_excel_sheet_protection~auto_filter = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~delete_columns = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~delete_rows = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~format_cells = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~format_columns = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~format_rows = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~insert_columns = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~insert_hyperlinks = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~insert_rows = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~objects = zif_excel_sheet_protection=>c_noactive. * me->zif_excel_sheet_protection~password = zif_excel_sheet_protection=>c_noactive. "issue #68 me->zif_excel_sheet_protection~pivot_tables = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~protected = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~scenarios = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~select_locked_cells = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~select_unlocked_cells = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~sheet = zif_excel_sheet_protection=>c_noactive. me->zif_excel_sheet_protection~sort = zif_excel_sheet_protection=>c_noactive. endmethod. method ZIF_EXCEL_SHEET_VBA_PROJECT~SET_CODENAME. me->zif_excel_sheet_vba_project~codename = ip_codename. endmethod. method ZIF_EXCEL_SHEET_VBA_PROJECT~SET_CODENAME_PR. me->zif_excel_sheet_vba_project~codename_pr = ip_codename_pr. endmethod. method ADD_DRAWING. CASE ip_drawing->get_type( ). WHEN zcl_excel_drawing=>type_image. drawings->include( ip_drawing ). WHEN zcl_excel_drawing=>type_chart. charts->include( ip_drawing ). ENDCASE. endmethod. method ADD_NEW_CONDITIONAL_STYLE. CREATE OBJECT eo_conditional_style. conditional_styles->add( eo_conditional_style ). endmethod. method ADD_NEW_DATA_VALIDATION. CREATE OBJECT eo_data_validation. data_validations->add( eo_data_validation ). endmethod. method ADD_NEW_RANGE. * Create default blank range CREATE OBJECT eo_range. ranges->add( eo_range ). endmethod. method BIND_ALV. data: lo_converter type ref to zcl_excel_converter. create object lo_converter. try. lo_converter->convert( exporting io_alv = io_alv it_table = it_table i_row_int = i_top i_column_int = i_left i_table = abap_true i_style_table = table_style io_worksheet = me changing co_excel = excel ). catch zcx_excel . endtry. endmethod. method BIND_ALV_OLE2. *--------------------------------------------------------------------* * Method description: * Method use to export a CL_GUI_ALV_GRID object to xlsx/xls file * with list header and characteristics of ALV field catalog such as: * + Total, group's subtotal * + Quantity fields, amount fields (dependent fields) * + No_out, no_zero, ... * Technique use in method: * SAP Desktop Office Integration (DOI) *--------------------------------------------------------------------* * Data for session 0: DOI constructor * ------------------------------------------ data: lo_control type ref to I_OI_CONTAINER_CONTROL. data: lo_proxy type ref to I_OI_DOCUMENT_PROXY. data: lo_spreadsheet type ref to I_OI_SPREADSHEET. data: lo_error type ref to I_OI_ERROR. data: lc_retcode type SOI_RET_STRING. data: li_has type i. "Proxy has spreadsheet interface? data: l_is_closed type i. * Data for session 1: Get LVC data from ALV object * ------------------------------------------ data: l_has_activex, l_doctype_excel_sheet(11) type c. data: wa_DOC_HANDLE Type CNTL_HANDLE. * LVC data: lt_fieldcat_lvc type LVC_T_FCAT. data: wa_fieldcat_lvc type lvc_s_fcat. data: lt_sort_lvc type LVC_T_SORT. data: lt_filter_idx_lvc type LVC_T_FIDX. data: lt_GROUPLEVELS_LVC type LVC_T_GRPL. * KKBLO DATA: LT_FIELDCAT_KKBLO Type KKBLO_T_FIELDCAT. DATA: LT_SORT_KKBLO Type KKBLO_T_SORTINFO. DATA: LT_GROUPLEVELS_KKBLO Type KKBLO_T_GROUPLEVELS. DATA: LT_FILTER_IDX_KKBLO Type KKBLO_T_SFINFO. data: wa_listheader like line of it_listheader. * Subtotal data: lt_collect00 type ref to data. data: lt_collect01 type ref to data. data: lt_collect02 type ref to data. data: lt_collect03 type ref to data. data: lt_collect04 type ref to data. data: lt_collect05 type ref to data. data: lt_collect06 type ref to data. data: lt_collect07 type ref to data. data: lt_collect08 type ref to data. data: lt_collect09 type ref to data. * data table name data: l_tabname type kkblo_tabname. * local object data: lo_grid type ref to lcl_gui_alv_grid. * data table get from ALV data: lt_alv type ref to data. * total / subtotal data field-symbols: <f_collect00> type standard table. field-symbols: <f_collect01> type standard table. field-symbols: <f_collect02> type standard table. field-symbols: <f_collect03> type standard table. field-symbols: <f_collect04> type standard table. field-symbols: <f_collect05> type standard table. field-symbols: <f_collect06> type standard table. field-symbols: <f_collect07> type standard table. field-symbols: <f_collect08> type standard table. field-symbols: <f_collect09> type standard table. * table before append subtotal lines field-symbols: <f_alv_tab> type standard table. * data for session 2: sort, filter and calculate total/subtotal * ------------------------------------------ * table to save index of subotal / total line in excel tanle * this ideal to control index of subtotal / total line later * for ex, when get subtotal / total line to format types: begin of st_subtot_indexs, index type i, end of st_subtot_indexs. data: lt_subtot_indexs type table of st_subtot_indexs. data: wa_subtot_indexs like line of lt_subtot_indexs. * data table after append subtotal data: lt_excel type ref to data. data: l_tabix type i. data: l_save_index type i. * dyn subtotal table name data: l_collect type string. * subtotal range, to format subtotal (and total) data: subranges type soi_range_list. data: subrangeitem type soi_range_item. data: l_sub_index type i. * table after append subtotal lines field-symbols: <f_excel_tab> type standard table. field-symbols: <f_excel_line> type any. * dyn subtotal tables field-symbols: <f_collect_tab> type standard table. field-symbols: <f_collect_line> type any. field-symbols: <f_filter_idx_line> like line of LT_FILTER_IDX_KKBLO. field-symbols: <f_fieldcat_line> like line of LT_FIELDCAT_KKBLO. field-symbols: <f_grouplevels_line> like line of LT_GROUPLEVELS_KKBLO. field-symbols: <f_line> type any. * Data for session 3: map data to semantic table * ------------------------------------------ types: begin of st_column_index, fieldname type kkblo_fieldname, tabname type kkblo_tabname, col like sy-index, end of st_column_index. * columns index data: lt_column_index type table of st_column_index. data: wa_column_index like line of lt_column_index. * table of dependent field ( currency and quantity unit field) data: lt_fieldcat_depf type kkblo_t_fieldcat. data: wa_fieldcat_depf type kkblo_fieldcat. * XXL interface: * -XXL: contain exporting columns characteristic data: lt_sema type table of gxxlt_s initial size 0. data: wa_sema like line of lt_sema. * -XXL interface: header data: lt_hkey type table of gxxlt_h initial size 0. data: wa_hkey like line of lt_hkey. * -XXL interface: header keys data: lt_vkey type table of gxxlt_v initial size 0. data: wa_vkey like line of lt_vkey. * Number of H Keys: number of key columns data: l_n_hrz_keys type i. * Number of data columns in the list object: non-key columns no data: l_n_att_cols type i. * Number of V Keys: number of header row data: l_n_vrt_keys type i. * curency to format amount data: lt_tcurx type table of tcurx. data: wa_tcurx like line of lt_tcurx. data: l_def type flag. " currency / quantity flag data: wa_t006 type t006. " decimal place of unit data: l_num type i. " table columns number data: l_typ type c. " table type data: wa type ref to data. data: l_int type i. data: l_counter type i. field-symbols: <f_excel_column> type any. field-symbols: <f_fcat_column> type any. * Data for session 4: write to excel * ------------------------------------------ data: data_starting_at type i value 1. data: data_ending_at type i value -1. data: sema_type type c. data l_error type ref to c_oi_proxy_error. data count type i. data datac type i. data datareal type i. " exporting column number data vkeycount type i. data all type i. data mit type i value 1. " index of recent row? data li_col_pos type i value 1. " column position data li_col_num type i. " table columns number field-symbols: <line> type any. field-symbols: <item> type any. data td type sydes_desc. data: typ. data: ranges type soi_range_list. data: rangeitem type soi_range_item. data: contents type soi_generic_table. data: contentsitem type soi_generic_item. data: semaitem type gxxlt_s. data: hkeyitem type gxxlt_h. data: vkeyitem type gxxlt_v. data: li_commentary_rows type i. "row number of title lines + 1 data: lo_error_w type ref to i_oi_error. data: l_retcode type soi_ret_string. data: no_flush type c value 'X'. data: li_head_top type i. "header rows position * Data for session 5: Save and clode document * ------------------------------------------ data: li_document_size type i. data: ls_path type RLGRAP-FILENAME. * MACRO: Close_document *------------------------------------------- DEFINE close_document. clear: l_is_closed. IF lo_proxy is not initial. * check proxy detroyed adi call method lo_proxy->is_destroyed IMPORTING ret_value = l_is_closed. * if dun detroyed yet: close -> release proxy IF l_is_closed is initial. call method lo_proxy->close_document * EXPORTING * do_save = do_save IMPORTING error = lo_error retcode = lc_retcode. ENDIF. call method lo_proxy->release_document IMPORTING error = lo_error retcode = lC_retcode. else. lc_retcode = c_oi_errors=>ret_document_not_open. ENDIF. * Detroy control container IF lo_control is not initial. CALL METHOD lo_control->destroy_control. ENDIF. clear: lo_spreadsheet, lo_proxy, lo_control. * free local clear: l_is_closed. END-OF-DEFINITION. * Macro to catch DOI error *------------------------------------------- DEFINE error_doi. if lc_retcode ne c_oi_errors=>ret_ok. close_document. call method lo_error->raise_message EXPORTING type = 'E'. clear: lo_error. endif. END-OF-DEFINITION. *--------------------------------------------------------------------* * SESSION 0: DOI CONSTRUCTOR *--------------------------------------------------------------------* * check active windown call function 'GUI_HAS_ACTIVEX' IMPORTING return = l_has_activex. if l_has_activex is initial. raise MISS_GUIDE. endif. * Get Container Object of Screen call method c_oi_container_control_creator=>get_container_control IMPORTING control = lo_control retcode = lC_retcode. error_doi. * Initialize Container control CALL METHOD lo_control->init_control EXPORTING parent = CL_GUI_CONTAINER=>DEFAULT_SCREEN r3_application_name = '' inplace_enabled = 'X' no_flush = 'X' register_on_close_event = 'X' register_on_custom_event = 'X' IMPORTING error = lO_ERROR retcode = lc_retcode. error_doi. * Get Proxy Document: * check exist of document proxy, if exist -> close first if not lo_proxy is initial. close_document. endif. IF i_xls is not initial. * xls format, doctype = soi_doctype_excel97_sheet l_doctype_excel_sheet = 'Excel.Sheet.8'. else. * xlsx format, doctype = soi_doctype_excel_sheet l_doctype_excel_sheet = 'Excel.Sheet'. ENDIF. CALL METHOD lo_control->get_document_proxy EXPORTING document_type = l_doctype_excel_sheet register_container = 'X' IMPORTING document_proxy = lo_proxy error = lO_ERROR retcode = lc_retcode. error_doi. IF I_DOCUMENT_URL is initial. * create new excel document call method lo_proxy->create_document EXPORTING create_view_data = 'X' open_inplace = 'X' no_flush = 'X' IMPORTING ERROR = lO_ERROR retcode = lc_retcode. error_doi. else. * Read excel template for i_DOCUMENT_URL * this excel template can be store in local or server CALL METHOD lo_proxy->open_document EXPORTING document_url = i_document_url open_inplace = 'X' no_flush = 'X' IMPORTING error = lo_error retcode = lc_retcode. error_doi. endif. * Check Spreadsheet Interface of Document Proxy CALL METHOD lo_proxy->has_spreadsheet_interface IMPORTING is_available = li_has error = lO_ERROR retcode = lc_retcode. error_doi. * create Spreadsheet object CHECK li_has IS NOT INITIAL. CALL METHOD lo_proxy->get_spreadsheet_interface IMPORTING sheet_interface = lo_spreadsheet error = lO_ERROR retcode = lc_retcode. error_doi. *--------------------------------------------------------------------* * SESSION 1: GET LVC DATA FROM ALV OBJECT *--------------------------------------------------------------------* * data table create object lo_grid EXPORTING i_parent = CL_GUI_CONTAINER=>SCREEN0. call method lo_grid->get_alv_attributes EXPORTING io_grid = io_alv IMPORTING Et_table = lt_alv. assign lt_alv->* to <f_alv_tab>. * fieldcat CALL METHOD iO_alv->GET_FRONTEND_FIELDCATALOG IMPORTING ET_FIELDCATALOG = lt_fieldcat_LVC. * table name loop at lt_fieldcat_LVC into wa_fieldcat_lvc where not tabname is initial. l_tabname = wa_fieldcat_lvc-tabname. exit. endloop. if sy-subrc ne 0. l_tabname = '1'. endif. clear: wa_fieldcat_lvc. * sort table CALL METHOD IO_ALV->GET_SORT_CRITERIA IMPORTING ET_SORT = lt_sort_lvc. * filter index CALL METHOD IO_ALV->GET_FILTERED_ENTRIES IMPORTING ET_FILTERED_ENTRIES = lt_filter_idx_lvc. * group level + subtotal CALL METHOD IO_ALV->GET_SUBTOTALS IMPORTING EP_COLLECT00 = lt_collect00 EP_COLLECT01 = lt_collect01 EP_COLLECT02 = lt_collect02 EP_COLLECT03 = lt_collect03 EP_COLLECT04 = lt_collect04 EP_COLLECT05 = lt_collect05 EP_COLLECT06 = lt_collect06 EP_COLLECT07 = lt_collect07 EP_COLLECT08 = lt_collect08 EP_COLLECT09 = lt_collect09 ET_GROUPLEVELS = lt_GROUPLEVELS_LVC. assign lt_collect00->* to <f_collect00>. assign lt_collect01->* to <f_collect01>. assign lt_collect02->* to <f_collect02>. assign lt_collect03->* to <f_collect03>. assign lt_collect04->* to <f_collect04>. assign lt_collect05->* to <f_collect05>. assign lt_collect06->* to <f_collect06>. assign lt_collect07->* to <f_collect07>. assign lt_collect08->* to <f_collect08>. assign lt_collect09->* to <f_collect09>. * transfer to KKBLO struct CALL FUNCTION 'LVC_TRANSFER_TO_KKBLO' EXPORTING IT_FIELDCAT_LVC = lt_fieldcat_lvc IT_SORT_LVC = lt_sort_lvc IT_FILTER_INDEX_LVC = lt_filter_idx_lvc IT_GROUPLEVELS_LVC = lt_grouplevels_lvc IMPORTING ET_FIELDCAT_KKBLO = lt_fieldcat_kkblo ET_SORT_KKBLO = lt_sort_kkblo ET_FILTERED_ENTRIES_KKBLO = lt_filter_idx_kkblo ET_GROUPLEVELS_KKBLO = lt_grouplevels_kkblo TABLES IT_DATA = <f_alv_tab> EXCEPTIONS IT_DATA_MISSING = 1 IT_FIELDCAT_LVC_MISSING = 2 OTHERS = 3. IF SY-SUBRC <> 0. raise ex_transfer_KKBLO_ERROR. ENDIF. clear: wa_fieldcat_lvc, lt_fieldcat_lvc, lt_sort_lvc, lt_filter_idx_lvc, lt_GROUPLEVELS_LVC. clear: lo_grid. *--------------------------------------------------------------------* * SESSION 2: SORT, FILTER AND CALCULATE TOTAL / SUBTOTAL *--------------------------------------------------------------------* * append subtotal & total line create data lt_excel like <f_ALV_TAB>. assign lt_excel->* to <f_excel_tab>. loop at <f_alv_tab> assigning <f_line>. l_save_index = sy-tabix. * filter base on filter index table read table LT_FILTER_IDX_KKBLO assigning <f_filter_idx_line> with key index = l_save_index binary search. if sy-subrc ne 0. append <f_line> to <f_excel_tab>. endif. * append subtotal lines read table LT_GROUPLEVELS_KKBLO assigning <f_grouplevels_line> with key index_to = l_save_index binary search. if sy-subrc = 0. l_tabix = sy-tabix. do. if <f_grouplevels_line>-subtot eq 'X' and <f_grouplevels_line>-hide_level is initial and <f_grouplevels_line>-cindex_from ne 0. * dynamic append subtotal line to excel table base on grouplevel table * ex <f_GROUPLEVELS_line>-level = 1 * then <f_collect_tab> = '<F_COLLECT01>' l_collect = <f_grouplevels_line>-level. condense l_collect. concatenate '<F_COLLECT0' l_collect '>' * '->*' into l_collect. assign (l_collect) to <f_collect_tab>. * incase there're more than 1 total line of group, at the same level * for example: subtotal of multi currency LOOP AT <f_collect_tab> assigning <f_collect_line>. IF sy-tabix between <f_grouplevels_line>-cindex_from and <f_grouplevels_line>-cindex_to. append <f_collect_line> to <f_excel_tab>. * save subtotal lines index wa_subtot_indexs-index = sy-tabix. append wa_subtot_indexs to lt_subtot_indexs. * append sub total ranges table for format later add 1 to l_sub_index. subrangeitem-name = l_sub_index. condense subrangeitem-name. concatenate 'SUBTOT' subrangeitem-name into subrangeitem-name. subrangeitem-rows = wa_subtot_indexs-index. subrangeitem-columns = 1. " start col append subrangeitem to subranges. clear: subrangeitem. ENDIF. ENDLOOP. unassign: <f_collect_tab>. unassign: <f_collect_line>. clear: l_collect. endif. * check next subtotal level of group unassign: <f_grouplevels_line>. add 1 to l_tabix. read table LT_GROUPLEVELS_KKBLO assigning <f_grouplevels_line> index l_tabix. if sy-subrc ne 0 or <f_grouplevels_line>-index_to ne l_save_index. exit. endif. unassign: <f_collect_tab>, <f_collect_line>. enddo. endif. clear: l_tabix, l_save_index. unassign: <f_filter_idx_line>, <f_grouplevels_line>. endloop. * free local data unassign: <f_line>, <f_collect_tab>, <f_collect_line>, <f_fieldcat_line>. * append grand total line IF <f_collect00> is assigned. assign <f_collect00> to <f_collect_tab>. if <f_collect_tab> is not initial. LOOP AT <f_collect_tab> assigning <f_collect_line>. append <f_collect_line> to <f_excel_tab>. * save total line index wa_subtot_indexs-index = sy-tabix. append wa_subtot_indexs to lt_subtot_indexs. * append grand total range (to format) add 1 to l_sub_index. subrangeitem-name = l_sub_index. condense subrangeitem-name. concatenate 'TOTAL' subrangeitem-name into subrangeitem-name. subrangeitem-rows = wa_subtot_indexs-index. subrangeitem-columns = 1. " start col append subrangeitem to subranges. ENDLOOP. endif. ENDIF. clear: subrangeitem, LT_SORT_KKBLO, <f_collect00>, <f_collect01>, <f_collect02>, <f_collect03>, <f_collect04>, <f_collect05>, <f_collect06>, <f_collect07>, <f_collect08>, <f_collect09>. unassign: <f_collect00>, <f_collect01>, <f_collect02>, <f_collect03>, <f_collect04>, <f_collect05>, <f_collect06>, <f_collect07>, <f_collect08>, <f_collect09>, <f_collect_tab>, <f_collect_line>. *--------------------------------------------------------------------* * SESSION 3: MAP DATA TO SEMANTIC TABLE *--------------------------------------------------------------------* * get dependent field field: currency and quantity create data wa like line of <f_excel_tab>. assign wa->* to <f_excel_line>. describe field <f_excel_line> type l_typ components l_num. do l_num times. l_save_index = sy-index. assign component l_save_index of structure <f_excel_line> to <f_excel_column>. if sy-subrc ne 0. message e059(0k) with 'FATAL ERROR' raising fatal_error. endif. loop at LT_FIELDCAT_KKBLO assigning <f_fieldcat_line> where tabname = l_tabname. assign component <f_fieldcat_line>-fieldname of structure <f_excel_line> to <f_fcat_column>. describe distance between <f_excel_column> and <f_fcat_column> into l_int in byte mode. * append column index * this columns index is of table, not fieldcat if l_int = 0. wa_column_index-fieldname = <f_fieldcat_line>-fieldname. wa_column_index-tabname = <f_fieldcat_line>-tabname. wa_column_index-col = l_save_index. append wa_column_index to lt_column_index. endif. * append dependent fields (currency and quantity unit) if <f_fieldcat_line>-cfieldname is not initial. clear wa_fieldcat_depf. wa_fieldcat_depf-fieldname = <f_fieldcat_line>-cfieldname. wa_fieldcat_depf-tabname = <f_fieldcat_line>-ctabname. collect wa_fieldcat_depf into lt_fieldcat_depf. endif. if <f_fieldcat_line>-qfieldname is not initial. clear wa_fieldcat_depf. wa_fieldcat_depf-fieldname = <f_fieldcat_line>-qfieldname. wa_fieldcat_depf-tabname = <f_fieldcat_line>-qtabname. collect wa_fieldcat_depf into lt_fieldcat_depf. endif. * rewrite field data type if <f_fieldcat_line>-inttype = 'X' and <f_fieldcat_line>-datatype(3) = 'INT'. <f_fieldcat_line>-inttype = 'I'. endif. endloop. clear: l_save_index. unassign: <f_fieldcat_line>. enddo. * build semantic tables l_n_hrz_keys = 1. * Get keyfigures loop at LT_FIELDCAT_KKBLO assigning <f_fieldcat_line> where tabname = l_tabname and tech ne 'X' and no_out ne 'X'. clear wa_sema. clear wa_hkey. * Units belong to keyfigures -> display as str read table lt_fieldcat_depf into wa_fieldcat_depf with key fieldname = <f_fieldcat_line>-fieldname tabname = <f_fieldcat_line>-tabname. if sy-subrc = 0. wa_sema-col_typ = 'STR'. wa_sema-col_ops = 'DFT'. * Keyfigures else. case <f_fieldcat_line>-datatype. when 'QUAN'. wa_sema-col_typ = 'N03'. if <f_fieldcat_line>-no_sum ne 'X'. wa_sema-col_ops = 'ADD'. else. wa_sema-col_ops = 'NOP'. " no dependent field endif. when 'DATS'. wa_sema-col_typ = 'DAT'. wa_sema-col_ops = 'NOP'. when 'CHAR' OR 'UNIT' OR 'CUKY'. " Added fieldformats UNIT and CUKY - dd. 26-10-2012 Wouter Heuvelmans wa_sema-col_typ = 'STR'. wa_sema-col_ops = 'DFT'. " dependent field * incase numeric, ex '00120' -> display as '12' when 'NUMC'. wa_sema-col_typ = 'STR'. wa_sema-col_ops = 'DFT'. when others. wa_sema-col_typ = 'NUM'. if <f_fieldcat_line>-no_sum ne 'X'. wa_sema-col_ops = 'ADD'. else. wa_sema-col_ops = 'NOP'. endif. endcase. endif. l_counter = l_counter + 1. l_n_att_cols = l_n_att_cols + 1. wa_sema-col_no = l_counter. read table lt_column_index into wa_column_index with key fieldname = <f_fieldcat_line>-fieldname tabname = <f_fieldcat_line>-tabname. if sy-subrc = 0. wa_sema-col_src = wa_column_index-col. else. raise fatal_error. endif. * columns index of ref currency field in table if not <f_fieldcat_line>-cfieldname is initial. read table lt_column_index into wa_column_index with key fieldname = <f_fieldcat_line>-cfieldname tabname = <f_fieldcat_line>-ctabname. if sy-subrc = 0. wa_sema-col_cur = wa_column_index-col. endif. * quantities fields * treat as currency when display on excel elseif not <f_fieldcat_line>-qfieldname is initial. read table lt_column_index into wa_column_index with key fieldname = <f_fieldcat_line>-qfieldname tabname = <f_fieldcat_line>-qtabname. if sy-subrc = 0. wa_sema-col_cur = wa_column_index-col. endif. endif. * Treat of fixed currency in the fieldcatalog for column data: l_num_help(2) type n. if not <f_fieldcat_line>-currency is initial. select * from tcurx into table lt_tcurx. sort lt_tcurx. read table lt_tcurx into wa_tcurx with key currkey = <f_fieldcat_line>-currency. if sy-subrc = 0. l_num_help = wa_tcurx-currdec. concatenate 'N' l_num_help into wa_sema-col_typ. wa_sema-col_cur = sy-tabix * ( -1 ). endif. endif. wa_hkey-col_no = l_n_att_cols. wa_hkey-row_no = l_n_hrz_keys. wa_hkey-col_name = <f_fieldcat_line>-reptext. append wa_hkey to lt_hkey. append wa_sema to lt_sema. endloop. * free local data clear: lt_column_index, wa_column_index, lt_fieldcat_depf, wa_fieldcat_depf, lt_tcurx, wa_tcurx, l_num, l_typ, wa, l_int, l_counter. unassign: <f_fieldcat_line>, <f_excel_line>, <f_excel_column>, <f_fcat_column>. *--------------------------------------------------------------------* * SESSION 4: WRITE TO EXCEL *--------------------------------------------------------------------* clear: wa_tcurx. refresh: lt_tcurx. * if spreadsheet dun have proxy yet if li_has is initial. l_retcode = c_oi_errors=>ret_interface_not_supported. call method c_oi_errors=>create_error_for_retcode EXPORTING retcode = l_retcode no_flush = no_flush IMPORTING error = lo_error_w. exit. endif. create object l_error EXPORTING object_name = 'OLE_DOCUMENT_PROXY' method_name = 'get_ranges_names'. call method c_oi_errors=>add_error EXPORTING error = l_error. describe table lt_sema lines datareal. describe table <f_excel_tab> lines datac. describe table lt_vkey lines vkeycount. if datac = 0. raise inv_data_range. endif. if vkeycount ne l_n_vrt_keys. raise dim_mismatch_vkey. endif. all = l_n_vrt_keys + l_n_att_cols. if datareal ne all. raise dim_mismatch_sema. endif. data: decimal type c. * get decimal separator format ('.', ',', ...) in Office config call method lo_proxy->get_application_property EXPORTING property_name = 'INTERNATIONAL' subproperty_name = 'DECIMAL_SEPARATOR' CHANGING retvalue = decimal. data: wa_usr type usr01. select * from usr01 into wa_usr where bname = sy-uname. endselect. data: comma_elim(4) type c. data: help6 type i. field-symbols <g> type any. data search_item(4) value ' #'. concatenate ',' decimal '.' decimal into comma_elim. data help type i. " table (with subtotal) line number help = datac. data: rowmax type i value 1. " header row number data: columnmax type i value 0. " header columns number loop at lt_hkey into hkeyitem. if hkeyitem-col_no > columnmax. columnmax = hkeyitem-col_no. endif. if hkeyitem-row_no > rowmax. rowmax = hkeyitem-row_no. endif. endloop. data: hkeycolumns type i. " header columns no hkeycolumns = columnmax. if hkeycolumns < l_n_att_cols. hkeycolumns = l_n_att_cols. endif. columnmax = 0. loop at lt_vkey into vkeyitem. if vkeyitem-col_no > columnmax. columnmax = vkeyitem-col_no. endif. endloop. data overflow type i value 1. data testname(10) type c. data temp2 type i. " 1st item row position in excel data realmit type i value 1. data realoverflow type i value 1. " row index in content call method lo_spreadsheet->screen_update EXPORTING updating = ''. call method lo_spreadsheet->load_lib. data: str(40) type c. " range names of columns range (w/o col header) data: rows type i. " row postion of 1st item line in ecxel * calculate row position of data table describe table iT_LISTHEADER lines li_commentary_rows. * if grid had title, add 1 empy line between title and table if li_commentary_rows ne 0. add 1 to li_commentary_rows. endif. * add top position of block data li_commentary_rows = li_commentary_rows + i_top - 1. * write header (commentary rows) data: li_commentary_row_index type i value 1. data: li_content_index type i value 1. data: ls_index(10) type c. data ls_commentary_range(40) type c value 'TITLE'. data: li_font_bold type i. data: li_font_italic type i. data: li_font_size type i. loop at iT_LISTHEADER into wa_listheader. li_commentary_row_index = i_top + li_content_index - 1. ls_index = li_content_index. condense ls_index. concatenate ls_commentary_range(5) ls_index into ls_commentary_range. condense ls_commentary_range. * insert title range call method lo_spreadsheet->insert_range_dim EXPORTING name = ls_commentary_range top = li_commentary_row_index left = i_left rows = 1 columns = 1 no_flush = no_flush. * format range case wa_listheader-typ. when 'H'. "title li_font_size = 16. li_font_bold = 1. li_font_italic = -1. when 'S'. "subtile li_font_size = -1. li_font_bold = 1. li_font_italic = -1. when others. "'A' comment li_font_size = -1. li_font_bold = -1. li_font_italic = 1. endcase. call method lo_spreadsheet->set_font EXPORTING rangename = ls_commentary_range family = '' size = li_font_size bold = li_font_bold italic = li_font_italic align = 0 no_flush = no_flush. * title: range content rangeitem-name = ls_commentary_range. rangeitem-columns = 1. rangeitem-rows = 1. append rangeitem to ranges. contentsitem-row = li_content_index. contentsitem-column = 1. concatenate wa_listheader-key wa_listheader-info into contentsitem-value separated by space. condense contentsitem-value. append contentsitem to contents. add 1 to li_content_index. clear: rangeitem, contentsitem, ls_index. endloop. * set range data title call method lo_spreadsheet->set_ranges_data EXPORTING ranges = ranges contents = contents no_flush = no_flush. refresh: ranges, contents. rows = rowmax + li_commentary_rows + 1. all = wa_usr-datfm. all = all + 3. loop at lt_sema into semaitem. if semaitem-col_typ = 'DAT' or semaitem-col_typ = 'MON' or semaitem-col_typ = 'N00' or semaitem-col_typ = 'N01' or semaitem-col_typ = 'N01' or semaitem-col_typ = 'N02' or semaitem-col_typ = 'N03' or semaitem-col_typ = 'PCT' or semaitem-col_typ = 'STR' or semaitem-col_typ = 'NUM'. clear str. str = semaitem-col_no. condense str. concatenate 'DATA' str into str. mit = semaitem-col_no. li_col_pos = semaitem-col_no + i_left - 1. * range from data1 to data(n), for each columns of table call method lo_spreadsheet->insert_range_dim EXPORTING name = str top = rows left = li_col_pos rows = help columns = 1 no_flush = no_flush. data dec type i value -1. data typeinfo type sydes_typeinfo. loop at <f_excel_tab> assigning <line>. assign component semaitem-col_no of structure <line> to <item>. describe field <item> into td. read table td-types index 1 into typeinfo. if typeinfo-type = 'P'. dec = typeinfo-decimals. elseif typeinfo-type = 'I'. dec = 0. endif. describe field <line> type typ components count. mit = 1. do count times. if mit = semaitem-col_src. assign component sy-index of structure <line> to <item>. describe field <item> into td. read table td-types index 1 into typeinfo. if typeinfo-type = 'P'. dec = typeinfo-decimals. endif. exit. endif. mit = mit + 1. enddo. exit. endloop. * format for each columns of table (w/o columns headers) if semaitem-col_typ = 'DAT'. if semaitem-col_no > vkeycount. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = all no_flush = no_flush. else. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 0 no_flush = no_flush. endif. elseif semaitem-col_typ = 'STR'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 0 no_flush = no_flush. elseif semaitem-col_typ = 'MON'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 10 no_flush = no_flush. elseif semaitem-col_typ = 'N00'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 0 no_flush = no_flush. elseif semaitem-col_typ = 'N01'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 1 no_flush = no_flush. elseif semaitem-col_typ = 'N02'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 2 no_flush = no_flush. elseif semaitem-col_typ = 'N03'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 3 no_flush = no_flush. elseif semaitem-col_typ = 'N04'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 4 no_flush = no_flush. elseif semaitem-col_typ = 'NUM'. if dec eq -1. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = 2 no_flush = no_flush. else. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 1 decimals = dec no_flush = no_flush. endif. elseif semaitem-col_typ = 'PCT'. call method lo_spreadsheet->set_format EXPORTING rangename = str currency = '' typ = 3 decimals = 0 no_flush = no_flush. endif. endif. endloop. * get item contents for set_range_data method * get currency cell also mit = 1. data: currcells type soi_cell_table. data: curritem type soi_cell_item. curritem-rows = 1. curritem-columns = 1. curritem-front = -1. curritem-back = -1. curritem-font = ''. curritem-size = -1. curritem-bold = -1. curritem-italic = -1. curritem-align = -1. curritem-frametyp = -1. curritem-framecolor = -1. curritem-currency = ''. curritem-number = 1. curritem-input = -1. data: conv_exit(10) type c. data: const type i. * Change for Correction request * Initial 10000 lines are missing in Excel Export * if there are only 2 columns in exported List object. if datareal gt 2. const = 20000 / datareal. else. const = 20000 / ( datareal + 2 ). endif. data: lines type i. data: innerlines type i. data: counter type i. data: curritem2 like curritem. data: curritem3 like curritem. data: length type i. data: found. * append content table (for method set_range_content) loop at <f_excel_tab> assigning <line>. * save line index to compare with lt_subtot_indexs, * to discover line is a subtotal / totale line or not * ex use to set 'dun display zero in subtotal / total line' l_save_index = sy-tabix. do datareal times. read table lt_sema into semaitem with key col_no = sy-index. if semaitem-col_src ne 0. assign component semaitem-col_src of structure <line> to <item>. else. assign component sy-index of structure <line> to <item>. endif. contentsitem-row = realoverflow. if sy-subrc = 0. move semaitem-col_ops to search_item(3). search 'ADD#CNT#MIN#MAX#AVG#NOP#DFT#' for search_item. if sy-subrc ne 0. raise error_in_sema. endif. move semaitem-col_typ to search_item(3). search 'NUM#N00#N01#N02#N03#N04#PCT#DAT#MON#STR#' for search_item. if sy-subrc ne 0. raise error_in_sema. endif. contentsitem-column = sy-index. if semaitem-col_typ eq 'DAT' or semaitem-col_typ eq 'MON'. if semaitem-col_no > vkeycount. " Hinweis 512418 " EXCEL bezieht Datumsangaben " auf den 31.12.1899, behandelt " aber 1900 als ein Schaltjahr " d.h. ab 1.3.1900 korrekt " 1.3.1900 als Zahl = 61 data: genesis type d value '18991230'. data: number_of_days type p. * change for date in char format & sema_type = X data: temp_date type d. if not <item> is initial and not <item> co ' ' and not <item> co '0'. * change for date in char format & sema_type = X starts if sema_type = 'X'. describe field <item> type typ. if typ = 'C'. temp_date = <item>. number_of_days = temp_date - genesis. else. number_of_days = <item> - genesis. endif. else. number_of_days = <item> - genesis. endif. * change for date in char format & sema_type = X ends if number_of_days < 61. number_of_days = number_of_days - 1. endif. set country 'DE'. write number_of_days to contentsitem-value no-grouping left-justified. set country space. translate contentsitem-value using comma_elim. else. clear contentsitem-value. endif. else. move <item> to contentsitem-value. endif. elseif semaitem-col_typ eq 'NUM' or semaitem-col_typ eq 'N00' or semaitem-col_typ eq 'N01' or semaitem-col_typ eq 'N02' or semaitem-col_typ eq 'N03' or semaitem-col_typ eq 'N04' or semaitem-col_typ eq 'PCT'. set country 'DE'. describe field <item> type typ. if semaitem-col_cur is initial. if typ ne 'F'. write <item> to contentsitem-value no-grouping no-sign decimals 14. else. write <item> to contentsitem-value no-grouping no-sign. endif. else. * Treat of fixed curreny for column >>Y9CK007319 if semaitem-col_cur < 0. semaitem-col_cur = semaitem-col_cur * ( -1 ). select * from tcurx into table lt_tcurx. sort lt_tcurx. read table lt_tcurx into wa_tcurx index semaitem-col_cur. if sy-subrc = 0. if typ ne 'F'. write <item> to contentsitem-value no-grouping currency wa_tcurx-currkey no-sign decimals 14. else. write <item> to contentsitem-value no-grouping currency wa_tcurx-currkey no-sign. endif. endif. else. assign component semaitem-col_cur of structure <line> to <g>. * mit = index of recent row curritem-top = rowmax + mit + li_commentary_rows. li_col_pos = sy-index + i_left - 1. curritem-left = li_col_pos. * if filed is quantity field (qfieldname ne space) * or amount field (cfieldname ne space), then format decimal place * corresponding with config clear: l_def. read table LT_FIELDCAT_KKBLO assigning <f_fieldcat_line> with key tabname = l_tabname tech = space no_out = space col_pos = semaitem-col_no. IF sy-subrc = 0. IF <f_fieldcat_line>-cfieldname is not initial. l_def = 'C'. else."if <f_fieldcat_line>-qfieldname is not initial. l_def = 'Q'. ENDIF. ENDIF. * if field is amount field * exporting of amount field base on currency decimal table: TCURX IF l_def = 'C'. "field is amount field select single * from tcurx into wa_tcurx where currkey = <g>. * if amount ref to un-know currency -> default decimal = 2 if sy-subrc eq 0. curritem-decimals = wa_tcurx-currdec. else. curritem-decimals = 2. endif. append curritem to currcells. if typ ne 'F'. write <item> to contentsitem-value currency <g> no-sign no-grouping. else. write <item> to contentsitem-value decimals 14 currency <g> no-sign no-grouping. endif. * if field is quantity field * exporting of quantity field base on quantity decimal table: T006 else."if l_def = 'Q'. " field is quantity field clear: wa_t006. select single * from t006 into wa_t006 where MSEHI = <g>. * if quantity ref to un-know unit-> default decimal = 2 if sy-subrc eq 0. curritem-decimals = wa_t006-decan. else. curritem-decimals = 2. endif. append curritem to currcells. write <item> to contentsitem-value unit <g> no-sign no-grouping. condense contentsitem-value. ENDIF. endif. "Y9CK007319 endif. condense contentsitem-value. * add function fieldcat-no zero display loop at LT_FIELDCAT_KKBLO assigning <f_fieldcat_line> where tabname = l_tabname and tech ne 'X' and no_out ne 'X'. if <f_fieldcat_line>-col_pos = semaitem-col_no. if <f_fieldcat_line>-no_zero = 'X'. if <item> = '0'. clear: contentsitem-value. endif. * dun display zero in total/subtotal line too else. clear: wa_subtot_indexs. read table lt_subtot_indexs into wa_subtot_indexs with key index = l_save_index. IF sy-subrc = 0. if <item> = '0'. clear: contentsitem-value. endif. ENDIF. endif. endif. endloop. unassign: <f_fieldcat_line>. if <item> lt 0. search contentsitem-value for 'E'. if sy-fdpos eq 0. * bring negative sign to front of amount translate contentsitem-value using '- '. condense contentsitem-value no-gaps. concatenate '-' contentsitem-value into contentsitem-value. else. concatenate '-' contentsitem-value into contentsitem-value. endif. endif. set country space. * Hier wird nur die korrekte Kommaseparatierung gemacht, wenn die * Zeichen einer * Zahl enthalten sind. Das ist f#ƒÂ#r Timestamps, die auch ":" enthalten. * F#ƒÂ#r die * darf keine Kommaseparierung stattfinden. * Changing for correction request - Y6BK041073 if contentsitem-value co '0123456789.,-+E '. translate contentsitem-value using comma_elim. endif. else. clear contentsitem-value. * if type is not numeric -> dun display with zero write <item> to contentsitem-value no-zero. shift contentsitem-value left deleting leading space. endif. append contentsitem to contents. endif. enddo. realmit = realmit + 1. realoverflow = realoverflow + 1. mit = mit + 1. * overflow = current row index in content table overflow = overflow + 1. endloop. unassign: <f_fieldcat_line>. * set item range for set_range_data method testname = mit / const. condense testname. concatenate 'TEST' testname into testname. realoverflow = realoverflow - 1. realmit = realmit - 1. help = realoverflow. rangeitem-name = testname. rangeitem-columns = datareal. rangeitem-rows = help. append rangeitem to ranges. * insert item range dim temp2 = rowmax + 1 + li_commentary_rows + realmit - realoverflow. * items data call method lo_spreadsheet->insert_range_dim EXPORTING name = testname top = temp2 left = i_left rows = help columns = datareal no_flush = no_flush. * get columns header contents for set_range_data method * export columns header only if no columns header option = space data: rowcount type i. data: columncount type i. if i_columns_header = 'X'. * append columns header to contents: hkey rowcount = 1. do rowmax times. columncount = 1. do hkeycolumns times. loop at lt_hkey into hkeyitem where col_no = columncount and row_no = rowcount. endloop. if sy-subrc = 0. str = hkeyitem-col_name. contentsitem-value = hkeyitem-col_name. else. contentsitem-value = str. endif. contentsitem-column = columncount. contentsitem-row = rowcount. append contentsitem to contents. columncount = columncount + 1. enddo. rowcount = rowcount + 1. enddo. * incase columns header in multiline data: rowmaxtemp type i. if rowmax > 1. rowmaxtemp = rowmax - 1. rowcount = 1. do rowmaxtemp times. columncount = 1. do columnmax times. contentsitem-column = columncount. contentsitem-row = rowcount. contentsitem-value = ''. append contentsitem to contents. columncount = columncount + 1. enddo. rowcount = rowcount + 1. enddo. endif. * append columns header to contents: vkey columncount = 1. do columnmax times. loop at lt_vkey into vkeyitem where col_no = columncount. endloop. contentsitem-value = vkeyitem-col_name. contentsitem-row = rowmax. contentsitem-column = columncount. append contentsitem to contents. columncount = columncount + 1. enddo. *--------------------------------------------------------------------* * set header range for method set_range_data * insert header keys range dim li_head_top = li_commentary_rows + 1. li_col_pos = i_left. * insert range headers if hkeycolumns ne 0. rangeitem-name = 'TESTHKEY'. rangeitem-rows = rowmax. rangeitem-columns = hkeycolumns. append rangeitem to ranges. clear: rangeitem. call method lo_spreadsheet->insert_range_dim EXPORTING name = 'TESTHKEY' top = li_head_top left = li_col_pos rows = rowmax columns = hkeycolumns no_flush = no_flush. endif. endif. * format for columns header + total + subtotal * ------------------------------------------ help = rowmax + realmit. " table + header lines data: item type colxxl_t. data: lt_format type soi_format_table. data: wa_format like line of lt_format. data: wa_format_temp like line of lt_format. field-symbols: <f_source> type any. field-symbols: <f_des> type any. * columns header format wa_format-front = -1. wa_format-back = 15. "grey wa_format-font = space. wa_format-size = -1. wa_format-bold = 1. wa_format-align = 0. wa_format-frametyp = -1. wa_format-framecolor = -1. * get column header format from input record * -> map input format if i_columns_header = 'X'. wa_format-name = 'TESTHKEY'. if i_format_col_header is not initial. describe field i_format_col_header type l_typ components li_col_num. do li_col_num times. if sy-index ne 1. " dun map range name assign component sy-index of structure i_format_col_header to <f_source>. if <f_source> is not initial. assign component sy-index of structure wa_format to <f_des>. <f_des> = <f_source>. unassign: <f_des>. endif. unassign: <f_source>. endif. enddo. clear: li_col_num. endif. append wa_format to lt_format. endif. * Zusammenfassen der Spalten mit gleicher Nachkommastellenzahl * collect vertical cells (col) with the same number of decimal places * to increase perfomance in currency cell format describe table currcells lines lines. lines = lines - 1. do lines times. describe table currcells lines innerlines. innerlines = innerlines - 1. sort currcells by left top. clear found. do innerlines times. read table currcells index sy-index into curritem. counter = sy-index + 1. read table currcells index counter into curritem2. if curritem-left eq curritem2-left. length = curritem-top + curritem-rows. if length eq curritem2-top. if curritem-decimals eq curritem2-decimals. move curritem to curritem3. curritem3-rows = curritem3-rows + curritem2-rows. curritem-left = -1. modify currcells index sy-index from curritem. curritem2-left = -1. modify currcells index counter from curritem2. append curritem3 to currcells. found = 'X'. endif. endif. endif. enddo. if found is initial. exit. endif. delete currcells where left = -1. enddo. * Zusammenfassen der Zeilen mit gleicher Nachkommastellenzahl * collect horizontal cells (row) with the same number of decimal places * to increase perfomance in currency cell format describe table currcells lines lines. lines = lines - 1. do lines times. describe table currcells lines innerlines. innerlines = innerlines - 1. sort currcells by top left. clear found. do innerlines times. read table currcells index sy-index into curritem. counter = sy-index + 1. read table currcells index counter into curritem2. if curritem-top eq curritem2-top and curritem-rows eq curritem2-rows. length = curritem-left + curritem-columns. if length eq curritem2-left. if curritem-decimals eq curritem2-decimals. move curritem to curritem3. curritem3-columns = curritem3-columns + curritem2-columns. curritem-left = -1. modify currcells index sy-index from curritem. curritem2-left = -1. modify currcells index counter from curritem2. append curritem3 to currcells. found = 'X'. endif. endif. endif. enddo. if found is initial. exit. endif. delete currcells where left = -1. enddo. * Ende der Zusammenfassung * item data: format for currency cell, corresponding with currency call method lo_spreadsheet->cell_format EXPORTING cells = currcells no_flush = no_flush. * item data: write item table content call method lo_spreadsheet->set_ranges_data EXPORTING ranges = ranges contents = contents no_flush = no_flush. * whole table range to format all table if i_columns_header = 'X'. li_head_top = li_commentary_rows + 1. else. li_head_top = li_commentary_rows + 2. help = help - 1. endif. call method lo_spreadsheet->insert_range_dim EXPORTING name = 'WHOLE_TABLE' top = li_head_top left = i_left rows = help columns = datareal no_flush = no_flush. * columns width auto fix * this parameter = space in case use with exist template IF i_columns_autofit = 'X'. call method lo_spreadsheet->fit_widest EXPORTING name = 'WHOLE_TABLE' no_flush = no_flush. ENDIF. * frame * The parameter has 8 bits *0 Left margin *1 Top marginT *2 Bottom margin *3 Right margin *4 Horizontal line *5 Vertical line *6 Thinness *7 Thickness * here 127 = 1111111 6-5-4-3-2-1 mean Thin-ver-hor-right-bot-top-left * ( final DOI method call, set no_flush = space * equal to call method CL_GUI_CFW=>FLUSH ) call method lo_spreadsheet->set_frame EXPORTING rangename = 'WHOLE_TABLE' typ = 127 color = 1 no_flush = space IMPORTING error = lo_error retcode = lc_retcode. error_doi. * reformat subtotal / total line after format wholw table loop at subranges into subrangeitem. l_sub_index = subrangeitem-rows + li_commentary_rows + rowmax. call method lo_spreadsheet->insert_range_dim EXPORTING name = subrangeitem-name left = i_left top = l_sub_index rows = 1 columns = datareal no_flush = no_flush. wa_format-name = subrangeitem-name. * default format: * - clolor: subtotal = light yellow, subtotal = yellow * - frame: box IF subrangeitem-name(3) = 'SUB'. wa_format-back = 36. "subtotal line wa_format_temp = i_format_subtotal. else. wa_format-back = 27. "total line wa_format_temp = i_format_total. endif. wa_format-FRAMETYP = 79. wa_format-FRAMEcolor = 1. wa_format-number = -1. wa_format-align = -1. * get subtoal + total format from intput parameter * overwrite default format if wa_format_temp is not initial. describe field wa_format_temp type l_typ components li_col_num. do li_col_num times. if sy-index ne 1. " dun map range name assign component sy-index of structure wa_format_temp to <f_source>. if <f_source> is not initial. assign component sy-index of structure wa_format to <f_des>. <f_des> = <f_source>. unassign: <f_des>. endif. unassign: <f_source>. endif. enddo. clear: li_col_num. endif. append wa_format to lt_format. clear: wa_format-name. clear: l_sub_index. clear: wa_format_temp. endloop. if lt_format[] is not initial. call method lo_spreadsheet->set_ranges_format EXPORTING formattable = lt_format no_flush = no_flush. refresh: lt_format. endif. *--------------------------------------------------------------------* call method lo_spreadsheet->screen_update EXPORTING updating = 'X'. call method c_oi_errors=>flush_errors. lo_error_w = l_error. lc_retcode = lo_error_w->error_code. ** catch no_flush -> led to dump ( optional ) * go_error = l_error. * gc_retcode = go_error->error_code. * error_doi. clear: lt_sema, wa_sema, lt_hkey, wa_hkey, lt_vkey, wa_vkey, l_n_hrz_keys, l_n_att_cols, l_n_vrt_keys, count, datac, datareal, vkeycount, all, mit, li_col_pos, li_col_num, ranges, rangeitem, contents, contentsitem, semaitem, hkeyitem, vkeyitem, li_commentary_rows, l_retcode, li_head_top, <f_excel_tab>. clear: lo_error_w. unassign: <line>, <item>, <f_excel_tab>. *--------------------------------------------------------------------* * SESSION 5: SAVE AND CLOSE FILE *--------------------------------------------------------------------* * ex of save path: 'FILE://C:\temp\test.xlsx' concatenate 'FILE://' I_save_path into ls_path. call method lo_proxy->save_document_to_url EXPORTING no_flush = 'X' url = ls_path IMPORTING error = lo_error retcode = lc_retcode CHANGING document_size = li_document_size. error_doi. * if save successfully -> raise successful message * message i499(sy) with 'Document is Exported to ' p_path. message i499(sy) with 'Data has been exported successfully'. clear: ls_path, li_document_size. close_document. endmethod. METHOD bind_table. DATA: lv_row_int TYPE zexcel_cell_row, lv_first_row TYPE zexcel_cell_row, lv_last_row TYPE zexcel_cell_row, lv_column_int TYPE zexcel_cell_column, lv_column_alpha TYPE zexcel_cell_column_alpha, lt_field_catalog TYPE zexcel_t_fieldcatalog, lv_id TYPE i, lv_rows TYPE i, lv_formula TYPE string, ls_settings TYPE zexcel_s_table_settings, lo_table TYPE REF TO zcl_excel_table, lt_column_name_buffer TYPE SORTED TABLE OF string WITH UNIQUE KEY table_line, lv_value TYPE string, lv_syindex TYPE char3. DATA lv_columns TYPE i. DATA lt_columns TYPE zexcel_t_fieldcatalog. DATA lv_maxcol TYPE i. DATA lv_maxrow TYPE i. DATA lo_iterator TYPE REF TO cl_object_collection_iterator. DATA lo_curtable TYPE REF TO zcl_excel_table. CONSTANTS: lc_top_left_column TYPE zexcel_cell_column_alpha VALUE 'B', lc_top_left_row TYPE zexcel_cell_row VALUE '3'. FIELD-SYMBOLS: <ls_field_catalog> TYPE zexcel_s_fieldcatalog, <ls_field_catalog_custom> TYPE zexcel_s_fieldcatalog, <fs_table_line> TYPE any, <fs_fldval> TYPE any. ls_settings = is_table_settings. IF ls_settings-top_left_column IS INITIAL. ls_settings-top_left_column = lc_top_left_column. ENDIF. IF ls_settings-table_style IS INITIAL. ls_settings-table_style = zcl_excel_table=>builtinstyle_medium2. ENDIF. IF ls_settings-top_left_row IS INITIAL. ls_settings-top_left_row = lc_top_left_row. ENDIF. IF it_field_catalog IS NOT SUPPLIED. lt_field_catalog = zcl_excel_common=>get_fieldcatalog( ip_table = ip_table ). ELSE. lt_field_catalog = it_field_catalog. ENDIF. SORT lt_field_catalog BY position. "Get the number of columns for the current table lt_columns = lt_field_catalog. DELETE lt_columns WHERE dynpfld NE abap_true. DESCRIBE TABLE lt_columns LINES lv_columns. "Calculate the top left row of the current table lv_column_int = zcl_excel_common=>convert_column2int( ls_settings-top_left_column ). lv_row_int = ls_settings-top_left_row. "Get number of row for the current table DESCRIBE TABLE ip_table LINES lv_rows. "Calculate the bottom right row for the current table lv_maxcol = lv_column_int + lv_columns - 1. lv_maxrow = lv_row_int + lv_rows - 1. ls_settings-bottom_right_column = zcl_excel_common=>convert_column2alpha( lv_maxcol ). ls_settings-bottom_right_row = lv_maxrow. "Check if overlapping areas exist lo_iterator = me->tables->if_object_collection~get_iterator( ). WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. lo_curtable ?= lo_iterator->if_object_collection_iterator~get_next( ). IF ls_settings-top_left_row GE lo_curtable->settings-top_left_row AND ls_settings-top_left_row LE lo_curtable->settings-bottom_right_row OR ls_settings-bottom_right_row GE lo_curtable->settings-top_left_row AND ls_settings-bottom_right_row LE lo_curtable->settings-bottom_right_row. ELSEIF lv_column_int GE zcl_excel_common=>convert_column2int( lo_curtable->settings-top_left_column ) AND lv_column_int LE lo_curtable->settings-bottom_right_column OR lv_maxcol GE zcl_excel_common=>convert_column2int( lo_curtable->settings-top_left_column ) AND lv_maxcol LE lo_curtable->settings-bottom_right_column. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'It is not possible to bind two tables to an excelsheet with overlapping areas.'. ENDIF. ENDWHILE. CREATE OBJECT lo_table. lo_table->settings = ls_settings. lo_table->set_data( ir_data = ip_table ). lv_id = me->excel->get_next_table_id( ). lo_table->set_id( iv_id = lv_id ). * lo_table->fieldcat = lt_field_catalog[]. me->tables->add( lo_table ). * It is better to loop column by column (only visible column) LOOP AT lt_field_catalog ASSIGNING <ls_field_catalog> WHERE dynpfld EQ abap_true. lv_column_alpha = zcl_excel_common=>convert_column2alpha( lv_column_int ). " Due restrinction of new table object we cannot have two column with the same name " Check if a column with the same name exists, if exists add a counter " If no medium description is provided we try to use small or long * lv_value = <ls_field_catalog>-scrtext_m. IF <ls_field_catalog>-scrtext_m IS NOT INITIAL. lv_value = <ls_field_catalog>-scrtext_m. <ls_field_catalog>-scrtext_l = lv_value. ELSEIF <ls_field_catalog>-scrtext_s IS NOT INITIAL. lv_value = <ls_field_catalog>-scrtext_s. <ls_field_catalog>-scrtext_l = lv_value. ELSEIF <ls_field_catalog>-scrtext_l IS NOT INITIAL. lv_value = <ls_field_catalog>-scrtext_l. ELSE. lv_value = 'Column'. " default value as Excel does <ls_field_catalog>-scrtext_l = lv_value. ENDIF. WHILE 1 = 1. READ TABLE lt_column_name_buffer TRANSPORTING NO FIELDS WITH KEY table_line = lv_value BINARY SEARCH. IF sy-subrc <> 0. <ls_field_catalog>-scrtext_l = lv_value. INSERT lv_value INTO TABLE lt_column_name_buffer. EXIT. ELSE. lv_syindex = sy-index. CONCATENATE <ls_field_catalog>-scrtext_l lv_syindex INTO lv_value. ENDIF. ENDWHILE. " First of all write column header IF <ls_field_catalog>-style_header IS NOT INITIAL. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = lv_value ip_style = <ls_field_catalog>-style_header ). ELSE. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = lv_value ). ENDIF. ADD 1 TO lv_row_int. LOOP AT ip_table ASSIGNING <fs_table_line>. ASSIGN COMPONENT <ls_field_catalog>-fieldname OF STRUCTURE <fs_table_line> TO <fs_fldval>. IF <ls_field_catalog>-style IS NOT INITIAL. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = <fs_fldval> ip_style = <ls_field_catalog>-style ). ELSE. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = <fs_fldval> ). ENDIF. ADD 1 TO lv_row_int. ENDLOOP. IF sy-subrc <> 0. "create empty row if table has no data me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = space ). ADD 1 TO lv_row_int. ENDIF. " totals IF <ls_field_catalog>-totals_function IS NOT INITIAL. lv_formula = lo_table->get_totals_formula( ip_column = <ls_field_catalog>-scrtext_l ip_function = <ls_field_catalog>-totals_function ). IF <ls_field_catalog>-style_total IS NOT INITIAL. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_formula = lv_formula ip_style = <ls_field_catalog>-style_total ). ELSE. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_formula = lv_formula ). ENDIF. ENDIF. lv_row_int = ls_settings-top_left_row. ADD 1 TO lv_column_int. " conditional formatting IF <ls_field_catalog>-cond_style IS NOT INITIAL. lv_first_row = ls_settings-top_left_row + 1. " +1 to exclude header lv_last_row = ls_settings-top_left_row + lv_rows. <ls_field_catalog>-cond_style->set_range( ip_start_column = lv_column_alpha ip_start_row = lv_first_row ip_stop_column = lv_column_alpha ip_stop_row = lv_last_row ). ENDIF. ENDLOOP. " Set field catalog lo_table->fieldcat = lt_field_catalog[]. es_table_settings = ls_settings. es_table_settings-bottom_right_column = lv_column_alpha. es_table_settings-bottom_right_row = ls_settings-top_left_row + lv_rows + 1. "Last rows ENDMETHOD. method CALCULATE_CELL_WIDTH. DATA: cell_value TYPE zexcel_cell_value, guid TYPE zexcel_cell_style, stylemapping TYPE zexcel_s_stylemapping. me->get_cell( EXPORTING ip_column = ip_column " Cell Column ip_row = ip_row " Cell Row IMPORTING ep_value = cell_value ep_guid = guid )." Cell Value ). ep_width = STRLEN( cell_value ). TRY. stylemapping = me->excel->get_style_to_guid( guid ). CATCH zcx_excel. EXIT. " Do nothing if no style was found ENDTRY. IF stylemapping-complete_stylex-font-size = 'X'. ep_width = ep_width * stylemapping-complete_style-font-size / 11. ENDIF. endmethod. method CALCULATE_COLUMN_WIDTHS. TYPES: BEGIN OF t_auto_size, col_index TYPE int4, width TYPE float, END OF t_auto_size. TYPES: tt_auto_size TYPE TABLE OF t_auto_size. DATA: column_dimensions TYPE zexcel_t_worksheet_columndime. DATA: column_dimension TYPE REF TO zcl_excel_worksheet_columndime. DATA: auto_size TYPE flag. DATA: auto_sizes TYPE tt_auto_size. * DATA: col_alpha TYPE zexcel_cell_column_alpha." issue #155 - less restrictive typing for ip_column DATA: cell_value TYPE zexcel_cell_value. DATA: cell_style TYPE REF TO zcl_excel_style. DATA: count TYPE int4. DATA: highest_row TYPE int4. DATA: width TYPE i. FIELD-SYMBOLS: <column_dimension> LIKE LINE OF column_dimensions. FIELD-SYMBOLS: <auto_size> LIKE LINE OF auto_sizes. column_dimensions[] = me->get_column_dimensions( ). LOOP AT column_dimensions ASSIGNING <column_dimension>. auto_size = <column_dimension>-column_dimension->get_auto_size( ). IF auto_size = abap_true. APPEND INITIAL LINE TO auto_sizes ASSIGNING <auto_size>. <auto_size>-col_index = <column_dimension>-column_dimension->get_column_index( ). <auto_size>-width = -1. ENDIF. ENDLOOP. " There is only something to do if there are some auto-size columns IF NOT auto_sizes IS INITIAL. highest_row = me->get_highest_row( ). LOOP AT auto_sizes ASSIGNING <auto_size>. * col_alpha = zcl_excel_common=>convert_column2alpha( <auto_size>-col_index )." issue #155 - less restrictive typing for ip_column count = 1. WHILE count <= highest_row. * Start of change # issue 139 - Dateretention of cellstyles * IF cell_style IS BOUND. * CREATE OBJECT cell_style. * ENDIF. * me->get_cell( * EXPORTING * ip_column = col_alpha " Cell Column * ip_row = count " Cell Row * IMPORTING * ep_value = cell_value " Cell Value * ep_style = cell_style " Request Cell Style as well * ). * " For an easy start we just take the number of characters as the width * width = strlen( cell_value ). * " Addition to solve issue #120, contribution by Stefan Schm#ƒÂ#cker * " Calculate width using Font Size and Font Type * IF cell_style IS BOUND * AND cell_style->font IS BOUND. * width = cell_style->font->calculate_text_width( cell_value ). * ENDIF. * width = calculate_cell_width( ip_column = col_alpha " issue #155 - less restrictive typing for ip_column width = calculate_cell_width( ip_column = <auto_size>-col_index " issue #155 - less restrictive typing for ip_column ip_row = count ). * End of change # issue 139 - Dateretention of cellstyles IF width > <auto_size>-width. <auto_size>-width = width. ENDIF. count = count + 1. ENDWHILE. * column_dimension = me->get_column_dimension( col_alpha ). " issue #155 - less restrictive typing for ip_column column_dimension = me->get_column_dimension( <auto_size>-col_index ). " issue #155 - less restrictive typing for ip_column column_dimension->set_width( <auto_size>-width ). ENDLOOP. ENDIF. endmethod. method CHANGE_CELL_STYLE. " issue # 139 DATA: stylemapping TYPE zexcel_s_stylemapping, complete_style TYPE zexcel_s_cstyle_complete, complete_stylex TYPE zexcel_s_cstylex_complete, borderx TYPE zexcel_s_cstylex_border, l_guid type OLTPGUID16. "issue # 177 * We have a lot of parameters. Use some macros to make the coding more structured DEFINE clear_initial_colorxfields. if &1-rgb is initial. clear &2-rgb. endif. if &1-indexed is initial. clear &2-indexed. endif. if &1-theme is initial. clear &2-theme. endif. if &1-tint is initial. clear &2-tint. endif. END-OF-DEFINITION. DEFINE move_supplied_borders. if ip_&1 is supplied. " only act if parameter was supplied if ip_x&1 is supplied. " borderx = ip_x&1. " use supplied x-parameter else. clear borderx with 'X'. * clear in a way that would be expected to work easily if ip_&1-border_style is initial. clear borderx-border_style. endif. clear_initial_colorxfields ip_&1-border_color borderx-border_color. endif. move-corresponding ip_&1 to complete_style-&2. move-corresponding borderx to complete_stylex-&2. endif. END-OF-DEFINITION. * First get current stylsettings TRY. me->get_cell( EXPORTING ip_column = ip_column " Cell Column ip_row = ip_row " Cell Row IMPORTING ep_guid = l_guid )." Cell Value ). "issue # 177 stylemapping = me->excel->get_style_to_guid( l_guid ). "issue # 177 complete_style = stylemapping-complete_style. complete_stylex = stylemapping-complete_stylex. CATCH zcx_excel. * Error --> use submitted style ENDTRY. * move_supplied_multistyles: complete. IF ip_complete IS SUPPLIED. IF ip_xcomplete IS NOT SUPPLIED. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Complete styleinfo has to be supplied with corresponding X-field'. ENDIF. MOVE-CORRESPONDING ip_complete TO complete_style. MOVE-CORRESPONDING ip_xcomplete TO complete_stylex. ENDIF. IF ip_font IS SUPPLIED. DATA: fontx LIKE ip_xfont. IF ip_xfont IS SUPPLIED. fontx = ip_xfont. ELSE. * Only supplied values should be used - exception: Flags bold and italic strikethrough underline MOVE 'X' TO: fontx-bold, fontx-italic, fontx-strikethrough, fontx-underline_mode. CLEAR fontx-color WITH 'X'. clear_initial_colorxfields ip_font-color fontx-color. IF ip_font-family IS NOT INITIAL. fontx-family = 'X'. ENDIF. IF ip_font-name IS NOT INITIAL. fontx-name = 'X'. ENDIF. IF ip_font-scheme IS NOT INITIAL. fontx-scheme = 'X'. ENDIF. IF ip_font-size IS NOT INITIAL. fontx-size = 'X'. ENDIF. IF ip_font-underline_mode IS NOT INITIAL. fontx-underline_mode = 'X'. ENDIF. ENDIF. MOVE-CORRESPONDING ip_font TO complete_style-font. MOVE-CORRESPONDING fontx TO complete_stylex-font. * Correction for undeline mode ENDIF. IF ip_fill IS SUPPLIED. DATA: fillx LIKE ip_xfill. IF ip_xfill IS SUPPLIED. fillx = ip_xfill. ELSE. CLEAR fillx WITH 'X'. IF ip_fill-filltype IS INITIAL. CLEAR fillx-filltype. ENDIF. clear_initial_colorxfields ip_fill-fgcolor fillx-fgcolor. clear_initial_colorxfields ip_fill-bgcolor fillx-bgcolor. ENDIF. MOVE-CORRESPONDING ip_fill TO complete_style-fill. MOVE-CORRESPONDING fillx TO complete_stylex-fill. ENDIF. IF ip_borders IS SUPPLIED. DATA: bordersx LIKE ip_xborders. IF ip_xborders IS SUPPLIED. bordersx = ip_xborders. ELSE. CLEAR bordersx WITH 'X'. IF ip_borders-allborders-border_style IS INITIAL. CLEAR bordersx-allborders-border_style. ENDIF. IF ip_borders-diagonal-border_style IS INITIAL. CLEAR bordersx-diagonal-border_style. ENDIF. IF ip_borders-down-border_style IS INITIAL. CLEAR bordersx-down-border_style. ENDIF. IF ip_borders-left-border_style IS INITIAL. CLEAR bordersx-left-border_style. ENDIF. IF ip_borders-right-border_style IS INITIAL. CLEAR bordersx-right-border_style. ENDIF. IF ip_borders-top-border_style IS INITIAL. CLEAR bordersx-top-border_style. ENDIF. clear_initial_colorxfields ip_borders-allborders-border_color bordersx-allborders-border_color. clear_initial_colorxfields ip_borders-diagonal-border_color bordersx-diagonal-border_color. clear_initial_colorxfields ip_borders-down-border_color bordersx-down-border_color. clear_initial_colorxfields ip_borders-left-border_color bordersx-left-border_color. clear_initial_colorxfields ip_borders-right-border_color bordersx-right-border_color. clear_initial_colorxfields ip_borders-top-border_color bordersx-top-border_color. ENDIF. MOVE-CORRESPONDING ip_borders TO complete_style-borders. MOVE-CORRESPONDING bordersx TO complete_stylex-borders. ENDIF. IF ip_alignment IS SUPPLIED. DATA: alignmentx LIKE ip_xalignment. IF ip_xalignment IS SUPPLIED. alignmentx = ip_xalignment. ELSE. CLEAR alignmentx WITH 'X'. IF ip_alignment-horizontal IS INITIAL. CLEAR alignmentx-horizontal. ENDIF. IF ip_alignment-vertical IS INITIAL. CLEAR alignmentx-vertical. ENDIF. ENDIF. MOVE-CORRESPONDING ip_alignment TO complete_style-alignment. MOVE-CORRESPONDING alignmentx TO complete_stylex-alignment. ENDIF. IF ip_protection IS SUPPLIED. MOVE-CORRESPONDING ip_alignment TO complete_style-alignment. IF ip_xprotection IS SUPPLIED. MOVE-CORRESPONDING ip_xprotection TO complete_stylex-protection. ELSE. IF ip_protection-hidden IS NOT INITIAL. complete_style-protection-hidden = 'X'. ENDIF. IF ip_protection-locked IS NOT INITIAL. complete_style-protection-locked = 'X'. ENDIF. ENDIF. ENDIF. move_supplied_borders : borders_allborders borders-allborders, borders_diagonal borders-diagonal , borders_down borders-down , borders_left borders-left , borders_right borders-right , borders_top borders-top . DEFINE move_supplied_singlestyles. if ip_&1 is supplied. complete_style-&2 = ip_&1. complete_stylex-&2 = 'X'. endif. END-OF-DEFINITION. move_supplied_singlestyles: number_format_format_code number_format-format_code, font_bold font-bold, font_color font-color, font_color_rgb font-color-rgb, font_color_indexed font-color-indexed, font_color_theme font-color-theme, font_color_tint font-color-tint, font_family font-family, font_italic font-italic, font_name font-name, font_scheme font-scheme, font_size font-size, font_strikethrough font-strikethrough, font_underline font-underline, font_underline_mode font-underline_mode, fill_filltype fill-filltype, fill_rotation fill-rotation, fill_fgcolor fill-fgcolor, fill_fgcolor_rgb fill-fgcolor-rgb, fill_fgcolor_indexed fill-fgcolor-indexed, fill_fgcolor_theme fill-fgcolor-theme, fill_fgcolor_tint fill-fgcolor-tint, fill_bgcolor fill-bgcolor, fill_bgcolor_rgb fill-bgcolor-rgb, fill_bgcolor_indexed fill-bgcolor-indexed, fill_bgcolor_theme fill-bgcolor-theme, fill_bgcolor_tint fill-bgcolor-tint, borders_diagonal_mode borders-diagonal_mode, alignment_horizontal alignment-horizontal, alignment_vertical alignment-vertical, alignment_textrotation alignment-textrotation, alignment_wraptext alignment-wraptext, alignment_shrinktofit alignment-shrinktofit, alignment_indent alignment-indent, protection_hidden protection-hidden, protection_locked protection-locked, borders_allborders_style borders-allborders-border_style, borders_allborders_color borders-allborders-border_color, borders_allbo_color_rgb borders-allborders-border_color-rgb, borders_allbo_color_indexed borders-allborders-border_color-indexed, borders_allbo_color_theme borders-allborders-border_color-theme, borders_allbo_color_tint borders-allborders-border_color-tint, borders_diagonal_style borders-diagonal-border_style, borders_diagonal_color borders-diagonal-border_color, borders_diagonal_color_rgb borders-diagonal-border_color-rgb, borders_diagonal_color_inde borders-diagonal-border_color-indexed, borders_diagonal_color_them borders-diagonal-border_color-theme, borders_diagonal_color_tint borders-diagonal-border_color-tint, borders_down_style borders-down-border_style, borders_down_color borders-down-border_color, borders_down_color_rgb borders-down-border_color-rgb, borders_down_color_indexed borders-down-border_color-indexed, borders_down_color_theme borders-down-border_color-theme, borders_down_color_tint borders-down-border_color-tint, borders_left_style borders-left-border_style, borders_left_color borders-left-border_color, borders_left_color_rgb borders-left-border_color-rgb, borders_left_color_indexed borders-left-border_color-indexed, borders_left_color_theme borders-left-border_color-theme, borders_left_color_tint borders-left-border_color-tint, borders_right_style borders-right-border_style, borders_right_color borders-right-border_color, borders_right_color_rgb borders-right-border_color-rgb, borders_right_color_indexed borders-right-border_color-indexed, borders_right_color_theme borders-right-border_color-theme, borders_right_color_tint borders-right-border_color-tint, borders_top_style borders-top-border_style, borders_top_color borders-top-border_color, borders_top_color_rgb borders-top-border_color-rgb, borders_top_color_indexed borders-top-border_color-indexed, borders_top_color_theme borders-top-border_color-theme, borders_top_color_tint borders-top-border_color-tint. * Now we have a completly filled styles. * This can be used to get the guid * Return guid if requested. Might be used if copy&paste of styles is requested ep_guid = me->excel->get_static_cellstyle_guid( ip_cstyle_complete = complete_style ip_cstylex_complete = complete_stylex ). me->set_cell_style( ip_column = ip_column ip_row = ip_row ip_style = ep_guid ). endmethod. METHOD constructor. DATA: lv_title TYPE zexcel_sheet_title. me->excel = ip_excel. CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_16 = me->guid. IF ip_title IS NOT INITIAL. lv_title = ip_title. ELSE. * lv_title = me->guid. " del issue #154 - Names of worksheets lv_title = me->generate_title( ). " ins issue #154 - Names of worksheets ENDIF. me->set_title( ip_title = lv_title ). CREATE OBJECT sheet_setup. CREATE OBJECT conditional_styles. CREATE OBJECT data_validations. CREATE OBJECT tables. CREATE OBJECT ranges. " issue #163 CREATE OBJECT drawings EXPORTING ip_type = zcl_excel_drawing=>type_image. CREATE OBJECT charts EXPORTING ip_type = zcl_excel_drawing=>type_chart. me->zif_excel_sheet_protection~initialize( ). me->zif_excel_sheet_properties~initialize( ). CREATE OBJECT hyperlinks. * initialize active cell coordinates active_cell-cell_row = 1. active_cell-cell_column = 1. * inizialize dimension range lower_cell-cell_row = 1. lower_cell-cell_column = 1. upper_cell-cell_row = 1. upper_cell-cell_column = 1. ENDMETHOD. method DELETE_MERGE. DELETE sheet_content_merge INDEX 1. DELETE sheet_content_merge INDEX 1. endmethod. method FREEZE_PANES. data: lv_xsplit type i, lv_ysplit type i. IF ip_num_columns IS NOT SUPPLIED AND ip_num_rows IS NOT SUPPLIED. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Pleas provide number of rows and/or columns to freeze'. ENDIF. IF ip_num_columns IS SUPPLIED AND ip_num_columns <= 0. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Number of columns to freeze should be positive'. ENDIF. IF ip_num_rows IS SUPPLIED AND ip_num_rows <= 0. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Number of rows to freeze should be positive'. ENDIF. freeze_pane_cell_column = ip_num_columns + 1. freeze_pane_cell_row = ip_num_rows + 1. endmethod. method GENERATE_TITLE. DATA: lo_worksheets_iterator TYPE REF TO cl_object_collection_iterator, lo_worksheet TYPE REF TO zcl_excel_worksheet, errormessage TYPE string. DATA: t_titles TYPE HASHED TABLE OF zexcel_sheet_title WITH UNIQUE KEY table_line, title TYPE zexcel_sheet_title, sheetnumber TYPE i. * Get list of currently used titles lo_worksheets_iterator = me->excel->get_worksheets_iterator( ). WHILE lo_worksheets_iterator->has_next( ) = abap_true. lo_worksheet ?= lo_worksheets_iterator->get_next( ). title = lo_worksheet->get_title( ). INSERT title INTO TABLE t_titles. ADD 1 TO sheetnumber. ENDWHILE. * Now build sheetnumber. Increase counter until we hit a number that is not used so far ADD 1 TO sheetnumber. " Start counting with next number DO. title = sheetnumber. SHIFT title LEFT DELETING LEADING space. CONCATENATE 'Sheet'(001) title INTO ep_title. INSERT ep_title INTO TABLE t_titles. IF sy-subrc = 0. " Title not used so far --> take it EXIT. ENDIF. ADD 1 TO sheetnumber. ENDDO. endmethod. method GET_ACTIVE_CELL. DATA: lv_active_column TYPE zexcel_cell_column_alpha, lv_active_row TYPE string. lv_active_column = zcl_excel_common=>convert_column2alpha( active_cell-cell_column ). lv_active_row = active_cell-cell_row. SHIFT lv_active_row RIGHT DELETING TRAILING space. SHIFT lv_active_row LEFT DELETING LEADING space. CONCATENATE lv_active_column lv_active_row INTO ep_active_cell. endmethod. method GET_CELL. DATA: lv_column TYPE zexcel_cell_column, ls_sheet_content TYPE zexcel_s_cell_data. FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data. lv_column = zcl_excel_common=>convert_column2int( ip_column ). READ TABLE sheet_content INTO ls_sheet_content WITH TABLE KEY cell_row = ip_row cell_column = lv_column. ep_rc = sy-subrc. ep_value = ls_sheet_content-cell_value. ep_guid = ls_sheet_content-cell_style. " issue 139 - added this to be used for columnwidth calculation " Addition to solve issue #120, contribution by Stefan Schm#ƒÂ#cker DATA: style_iterator TYPE REF TO cl_object_collection_iterator, style TYPE REF TO zcl_excel_style. IF ep_style IS REQUESTED. style_iterator = me->excel->get_styles_iterator( ). WHILE style_iterator->has_next( ) = 'X'. style ?= style_iterator->get_next( ). IF style->get_guid( ) = ls_sheet_content-cell_style. ep_style = style. EXIT. ENDIF. ENDWHILE. ENDIF. endmethod. method GET_COLUMN_DIMENSION. FIELD-SYMBOLS: <fs_column_dimension> LIKE LINE OF column_dimensions. DATA: lv_column_alpha TYPE zexcel_cell_column_alpha. " issue #155 - less restrictive typing for ip_column lv_column_alpha = zcl_excel_common=>convert_column2alpha( ip_column )." issue #155 - less restrictive typing for ip_column READ TABLE me->column_dimensions ASSIGNING <fs_column_dimension> WITH KEY column = lv_column_alpha. " issue #155 - less restrictive typing for ip_column IF NOT <fs_column_dimension> IS ASSIGNED. CREATE OBJECT r_column_dimension EXPORTING ip_index = lv_column_alpha " issue #155 - less restrictive typing for ip_column ip_excel = me->excel " issue #157 - Allow style for columns ip_worksheet = me. " issue #157 - Allow style for columns APPEND INITIAL LINE TO me->column_dimensions ASSIGNING <fs_column_dimension>. <fs_column_dimension>-column = lv_column_alpha. " issue #155 - less restrictive typing for ip_column <fs_column_dimension>-column_dimension = r_column_dimension. ELSE. r_column_dimension = <fs_column_dimension>-column_dimension. ENDIF. endmethod. method GET_COLUMN_DIMENSIONS. r_column_dimension[] = me->column_dimensions[]. endmethod. method GET_COND_STYLES_ITERATOR. eo_iterator = me->conditional_styles->get_iterator( ). endmethod. method GET_DATA_VALIDATIONS_ITERATOR. eo_iterator = me->data_validations->get_iterator( ). endmethod. method GET_DATA_VALIDATIONS_SIZE. ep_size = me->data_validations->size( ). endmethod. method GET_DEFAULT_COLUMN_DIMENSION. IF me->default_column_dimension IS NOT BOUND. CREATE OBJECT me->default_column_dimension EXPORTING ip_index = 'A' " ???? ip_worksheet = me ip_excel = me->excel. ENDIF. r_column_dimension = me->default_column_dimension. endmethod. method GET_DEFAULT_EXCEL_DATE_FORMAT. CONSTANTS: c_lang_e TYPE lang VALUE 'E'. IF default_excel_date_format IS NOT INITIAL. ep_default_excel_date_format = default_excel_date_format. RETURN. ENDIF. "try to get defaults TRY. cl_abap_datfm=>get_date_format_des( EXPORTING im_langu = c_lang_e IMPORTING ex_dateformat = default_excel_date_format ). CATCH cx_abap_datfm_format_unknown. ENDTRY. " and fallback to fixed format IF default_excel_date_format IS INITIAL. default_excel_date_format = zcl_excel_style_number_format=>c_format_date_ddmmyyyydot. ENDIF. ep_default_excel_date_format = default_excel_date_format. endmethod. method GET_DEFAULT_EXCEL_TIME_FORMAT. DATA: l_timefm TYPE xutimefm. IF default_excel_time_format IS NOT INITIAL. ep_default_excel_time_format = default_excel_time_format. RETURN. ENDIF. * Let's get default l_timefm = cl_abap_timefm=>get_environment_timefm( ). CASE l_timefm. WHEN 0. *0 24 Hour Format (Example: 12:05:10) default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time6. WHEN 1. *1 12 Hour Format (Example: 12:05:10 PM) default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time2. WHEN 2. *2 12 Hour Format (Example: 12:05:10 pm) for now all the same. no chnage upper lower default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time2. WHEN 3. *3 Hours from 0 to 11 (Example: 00:05:10 PM) for now all the same. no chnage upper lower default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time2. WHEN 4. *4 Hours from 0 to 11 (Example: 00:05:10 pm) for now all the same. no chnage upper lower default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time2. WHEN OTHERS. " and fallback to fixed format default_excel_time_format = zcl_excel_style_number_format=>c_format_date_time6. ENDCASE. ep_default_excel_time_format = default_excel_time_format. endmethod. method GET_DEFAULT_ROW_DIMENSION. IF me->default_row_dimension IS NOT BOUND. CREATE OBJECT me->default_row_dimension. ENDIF. r_row_dimension = me->default_row_dimension. endmethod. method GET_DIMENSION_RANGE. me->update_dimension_range( ). IF upper_cell EQ lower_cell. "only one cell " Worksheet not filled * IF upper_cell-cell_coords = '0'. IF upper_cell-cell_coords IS INITIAL. ep_dimension_range = 'A1'. ELSE. ep_dimension_range = upper_cell-cell_coords. ENDIF. ELSE. CONCATENATE upper_cell-cell_coords ':' lower_cell-cell_coords INTO ep_dimension_range. ENDIF. endmethod. method GET_DRAWINGS. DATA: lo_drawing TYPE REF TO zcl_excel_drawing, lo_iterator TYPE REF TO cl_object_collection_iterator. CASE ip_type. WHEN zcl_excel_drawing=>type_image. r_drawings = drawings. WHEN zcl_excel_drawing=>type_chart. r_drawings = charts. WHEN space. CREATE OBJECT r_drawings EXPORTING ip_type = ''. lo_iterator = drawings->get_iterator( ). WHILE lo_iterator->has_next( ) = abap_true. lo_drawing ?= lo_iterator->get_next( ). r_drawings->include( lo_drawing ). ENDWHILE. lo_iterator = charts->get_iterator( ). WHILE lo_iterator->has_next( ) = abap_true. lo_drawing ?= lo_iterator->get_next( ). r_drawings->include( lo_drawing ). ENDWHILE. WHEN OTHERS. ENDCASE. endmethod. method GET_DRAWINGS_ITERATOR. CASE ip_type. WHEN zcl_excel_drawing=>type_image. eo_iterator = drawings->get_iterator( ). WHEN zcl_excel_drawing=>type_chart. eo_iterator = charts->get_iterator( ). ENDCASE. endmethod. method GET_FREEZE_CELL. ep_row = me->freeze_pane_cell_row. ep_column = me->freeze_pane_cell_column. endmethod. method GET_GUID. ep_guid = me->guid. endmethod. method GET_HIGHEST_COLUMN. me->update_dimension_range( ). r_highest_column = me->lower_cell-cell_column. endmethod. method GET_HIGHEST_ROW. me->update_dimension_range( ). r_highest_row = me->lower_cell-cell_row. endmethod. method GET_HYPERLINKS_ITERATOR. eo_iterator = hyperlinks->get_iterator( ). endmethod. method GET_HYPERLINKS_SIZE. ep_size = hyperlinks->size( ). endmethod. method GET_MERGE. DATA: lv_column_start TYPE string, lv_column_end TYPE string, lv_row TYPE string, lv_index TYPE sy-tabix, ls_sheet_content TYPE zexcel_s_cell_data, range_from TYPE string, range_to TYPE string, lv_merge_range TYPE string, lv_count TYPE string. FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data. DESCRIBE TABLE sheet_content_merge LINES lv_count. WHILE lv_count GT lv_index. * LOOP AT sheet_content_merge ASSIGNING <fs_sheet_content>. lv_index = lv_index + 1. READ TABLE sheet_content_merge ASSIGNING <fs_sheet_content> INDEX lv_index. lv_column_start = zcl_excel_common=>convert_column2alpha( <fs_sheet_content>-cell_column ). lv_row = <fs_sheet_content>-cell_row. SHIFT lv_column_start RIGHT DELETING TRAILING space. SHIFT lv_column_start LEFT DELETING LEADING space. SHIFT lv_row RIGHT DELETING TRAILING space. SHIFT lv_row LEFT DELETING LEADING space. CONCATENATE lv_column_start lv_row INTO range_from. lv_index = lv_index + 1. READ TABLE sheet_content_merge ASSIGNING <fs_sheet_content> INDEX lv_index. lv_column_end = zcl_excel_common=>convert_column2alpha( <fs_sheet_content>-cell_column ). lv_row = <fs_sheet_content>-cell_row. SHIFT lv_column_end RIGHT DELETING TRAILING space. SHIFT lv_column_end LEFT DELETING LEADING space. SHIFT lv_row RIGHT DELETING TRAILING space. SHIFT lv_row LEFT DELETING LEADING space. CONCATENATE lv_column_end lv_row INTO range_to. CONCATENATE range_from range_to INTO lv_merge_range SEPARATED BY ':'. APPEND lv_merge_range TO merge_range. ENDWHILE. * ENDLOOP. * READ TABLE sheet_content_merge ASSIGNING <fs_sheet_content> INDEX 1. * IF sy-subrc EQ 0 AND <fs_sheet_content> IS ASSIGNED. * lv_column_start = zcl_excel_common=>convert_column2alpha( <fs_sheet_content>-cell_column ). * lv_row = <fs_sheet_content>-cell_row. * SHIFT lv_column_start RIGHT DELETING TRAILING space. * SHIFT lv_column_start LEFT DELETING LEADING space. * SHIFT lv_row RIGHT DELETING TRAILING space. * SHIFT lv_row LEFT DELETING LEADING space. * CONCATENATE lv_column_start lv_row * INTO range_from. * ENDIF. * READ TABLE sheet_content_merge ASSIGNING <fs_sheet_content> INDEX 2. * IF sy-subrc EQ 0 AND <fs_sheet_content> IS ASSIGNED. * lv_column_end = zcl_excel_common=>convert_column2alpha( <fs_sheet_content>-cell_column ). * SHIFT lv_column_end RIGHT DELETING TRAILING space. * SHIFT lv_column_end LEFT DELETING LEADING space. * CONCATENATE lv_column_end lv_row * INTO range_to. * ENDIF. * IF range_from NE space AND range_to NE space. * CONCATENATE range_from range_to INTO ep_merge_range * SEPARATED BY ':'. * ENDIF. endmethod. method GET_RANGES_ITERATOR. eo_iterator = me->ranges->get_iterator( ). endmethod. method GET_ROW_DIMENSION. FIELD-SYMBOLS: <fs_row_dimension> LIKE LINE OF row_dimensions. READ TABLE me->row_dimensions ASSIGNING <fs_row_dimension> WITH KEY row = ip_row. IF NOT <fs_row_dimension> IS ASSIGNED. CREATE OBJECT r_row_dimension EXPORTING ip_index = ip_row. APPEND INITIAL LINE TO me->row_dimensions ASSIGNING <fs_row_dimension>. <fs_row_dimension>-row = ip_row. <fs_row_dimension>-row_dimension = r_row_dimension. ELSE. r_row_dimension = <fs_row_dimension>-row_dimension. ENDIF. endmethod. method GET_ROW_DIMENSIONS. r_row_dimension[] = me->row_dimensions[]. endmethod. method GET_TABCOLOR. ev_tabcolor = me->tabcolor. endmethod. method GET_TABLES_ITERATOR. eo_iterator = tables->if_object_collection~get_iterator( ). endmethod. method GET_TABLES_SIZE. ep_size = tables->if_object_collection~size( ). endmethod. method GET_TITLE. DATA lv_value TYPE string. IF ip_escaped EQ abap_true. lv_value = me->title. ep_title = zcl_excel_common=>escape_string( lv_value ). ELSE. ep_title = me->title. ENDIF. endmethod. method GET_VALUE_TYPE. DATA: lo_addit TYPE REF TO cl_abap_elemdescr, ls_dfies TYPE dfies, l_function TYPE funcname, l_value(50) TYPE c. ep_value = ip_value. ep_value_type = cl_abap_typedescr=>typekind_string. " Thats our default if something goes wrong. TRY. lo_addit ?= cl_abap_typedescr=>describe_by_data( ip_value ). CATCH cx_sy_move_cast_error. CLEAR lo_addit. ENDTRY. IF lo_addit IS BOUND. lo_addit->get_ddic_field( RECEIVING p_flddescr = ls_dfies EXCEPTIONS not_found = 1 no_ddic_type = 2 OTHERS = 3 ) . IF sy-subrc = 0. ep_value_type = ls_dfies-inttype. IF ls_dfies-convexit IS NOT INITIAL. * We need to convert with output conversion function CONCATENATE 'CONVERSION_EXIT_' ls_dfies-convexit '_OUTPUT' INTO l_function. SELECT SINGLE funcname INTO l_function FROM tfdir WHERE funcname = l_function. IF sy-subrc = 0. CALL FUNCTION l_function EXPORTING input = ip_value IMPORTING * LONG_TEXT = output = l_value * SHORT_TEXT = EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ELSE. ep_value = l_value. ENDIF. ENDIF. ENDIF. ELSE. ep_value_type = lo_addit->get_data_type_kind( ip_value ). ENDIF. ENDIF. endmethod. method SET_CELL. DATA: lv_column TYPE zexcel_cell_column, ls_sheet_content TYPE zexcel_s_cell_data, lv_row_alpha TYPE string, lv_col_alpha TYPE ZEXCEL_CELL_COLUMN_ALPHA, lv_value TYPE zexcel_cell_value, lv_data_type TYPE zexcel_cell_data_type, lv_value_type TYPE abap_typekind, lo_style TYPE REF TO zcl_excel_style, lv_style_guid TYPE zexcel_cell_style, lo_addit TYPE REF TO cl_abap_elemdescr, lo_value TYPE REF TO data, lo_value_new TYPE REF TO data. FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data, <fs_numeric> TYPE numeric, <fs_date> TYPE d, <fs_time> TYPE t, <fs_value> TYPE simple. IF ip_value IS NOT SUPPLIED AND ip_formula IS NOT SUPPLIED. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Please provide the value or formula'. ENDIF. * Begin of change issue #152 - don't touch exisiting style if only value is passed * lv_style_guid = ip_style. lv_column = zcl_excel_common=>convert_column2int( ip_column ). READ TABLE sheet_content ASSIGNING <fs_sheet_content> WITH KEY cell_row = ip_row cell_column = lv_column. IF sy-subrc = 0. IF ip_style IS INITIAL. " If no style is provided as method-parameter and cell is found use cell's current style lv_style_guid = <fs_sheet_content>-cell_style. ELSE. " Style provided as method-parameter --> use this lv_style_guid = ip_style. ENDIF. ELSE. " No cell found --> use supplied style even if empty lv_style_guid = ip_style. ENDIF. * End of change issue #152 - don't touch exisiting style if only value is passed IF ip_value IS SUPPLIED. "if data type is passed just write the value. Otherwise map abap type to excel and perform conversion "IP_DATA_TYPE is passed by excel reader so source types are preserved *First we get reference into local var. CREATE DATA lo_value LIKE ip_value. ASSIGN lo_value->* TO <fs_value>. <fs_value> = ip_value. IF ip_data_type IS SUPPLIED. IF ip_abap_type IS NOT SUPPLIED. get_value_type( EXPORTING ip_value = ip_value IMPORTING ep_value = <fs_value> ) . ENDIF. lv_value = <fs_value>. lv_data_type = ip_data_type. ELSE. IF ip_abap_type IS SUPPLIED. lv_value_type = ip_abap_type. ELSE. get_value_type( EXPORTING ip_value = ip_value IMPORTING ep_value = <fs_value> ep_value_type = lv_value_type ). ENDIF. CASE lv_value_type. WHEN cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 OR cl_abap_typedescr=>typekind_int2. lo_addit = cl_abap_elemdescr=>get_i( ). CREATE DATA lo_value_new TYPE HANDLE lo_addit. ASSIGN lo_value_new->* TO <fs_numeric>. IF sy-subrc = 0. <fs_numeric> = <fs_value>. lv_value = zcl_excel_common=>number_to_excel_string( ip_value = <fs_numeric> ). ENDIF. WHEN cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_packed. lo_addit = cl_abap_elemdescr=>get_f( ). CREATE DATA lo_value_new TYPE HANDLE lo_addit. ASSIGN lo_value_new->* TO <fs_numeric>. IF sy-subrc = 0. <fs_numeric> = <fs_value>. lv_value = zcl_excel_common=>number_to_excel_string( ip_value = <fs_numeric> ). ENDIF. WHEN cl_abap_typedescr=>typekind_char OR cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_num or cl_abap_typedescr=>typekind_hex. lv_value = <fs_value>. lv_data_type = 's'. WHEN cl_abap_typedescr=>typekind_date. lo_addit = cl_abap_elemdescr=>get_d( ). CREATE DATA lo_value_new TYPE HANDLE lo_addit. ASSIGN lo_value_new->* TO <fs_date>. IF sy-subrc = 0. <fs_date> = <fs_value>. lv_value = zcl_excel_common=>date_to_excel_string( ip_value = <fs_date> ) . ENDIF. * Begin of change issue #152 - don't touch exisiting style if only value is passed * Moved to end of routine - apply date-format even if other styleinformation is passed * IF ip_style IS NOT SUPPLIED. "get default date format in case parameter is initial * lo_style = excel->add_new_style( ). * lo_style->number_format->format_code = get_default_excel_date_format( ). * lv_style_guid = lo_style->get_guid( ). * ENDIF. * End of change issue #152 - don't touch exisiting style if only value is passed WHEN cl_abap_typedescr=>typekind_time. lo_addit = cl_abap_elemdescr=>get_t( ). CREATE DATA lo_value_new TYPE HANDLE lo_addit. ASSIGN lo_value_new->* TO <fs_time>. IF sy-subrc = 0. <fs_time> = <fs_value>. lv_value = zcl_excel_common=>time_to_excel_string( ip_value = <fs_time> ). ENDIF. * Begin of change issue #152 - don't touch exisiting style if only value is passed * Moved to end of routine - apply time-format even if other styleinformation is passed * IF ip_style IS NOT SUPPLIED. "get default time format for user in case parameter is initial * lo_style = excel->add_new_style( ). * lo_style->number_format->format_code = zcl_excel_style_number_format=>c_format_date_time6. * lv_style_guid = lo_style->get_guid( ). * ENDIF. * End of change issue #152 - don't touch exisiting style if only value is passed WHEN OTHERS. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Invalid data type of input value'. ENDCASE. ENDIF. ENDIF. IF ip_hyperlink IS BOUND. ip_hyperlink->set_cell_reference( ip_column = ip_column ip_row = ip_row ). me->hyperlinks->add( ip_hyperlink ). ENDIF. * Begin of change issue #152 - don't touch exisiting style if only value is passed * Read table moved up, so that current style may be evaluated * lv_column = zcl_excel_common=>convert_column2int( ip_column ). * READ TABLE sheet_content ASSIGNING <fs_sheet_content> WITH KEY cell_row = ip_row * cell_column = lv_column. * * IF sy-subrc EQ 0. IF <fs_sheet_content> IS ASSIGNED. * End of change issue #152 - don't touch exisiting style if only value is passed <fs_sheet_content>-cell_value = lv_value. <fs_sheet_content>-cell_formula = ip_formula. <fs_sheet_content>-cell_style = lv_style_guid. <fs_sheet_content>-data_type = lv_data_type. ELSE. ls_sheet_content-cell_row = ip_row. ls_sheet_content-cell_column = lv_column. ls_sheet_content-cell_value = lv_value. ls_sheet_content-cell_formula = ip_formula. ls_sheet_content-cell_style = lv_style_guid. ls_sheet_content-data_type = lv_data_type. lv_row_alpha = ip_row. * SHIFT lv_row_alpha RIGHT DELETING TRAILING space."del #152 - replaced with condense - should be faster * SHIFT lv_row_alpha LEFT DELETING LEADING space. "del #152 - replaced with condense - should be faster CONDENSE lv_row_alpha NO-GAPS. "ins #152 - replaced 2 shifts - should be faster lv_col_alpha = zcl_excel_common=>CONVERT_COLUMN2ALPHA( ip_column ). " issue #155 - less restrictive typing for ip_column CONCATENATE lv_col_alpha lv_row_alpha INTO ls_sheet_content-cell_coords. " issue #155 - less restrictive typing for ip_column INSERT ls_sheet_content INTO TABLE sheet_content ASSIGNING <fs_sheet_content>. "ins #152 - Now <fs_sheet_content> always holds the data * APPEND ls_sheet_content TO sheet_content. * SORT sheet_content BY cell_row cell_column. " me->update_dimension_range( ). ENDIF. * Begin of change issue #152 - don't touch exisiting style if only value is passed * For Date- or Timefields change the formatcode if nothing is set yet * Enhancement option: Check if existing formatcode is a date/ or timeformat * If not, use default DATA: lo_format_code_datetime TYPE zexcel_number_format. DATA: stylemapping TYPE zexcel_s_stylemapping. CASE lv_value_type. WHEN cl_abap_typedescr=>typekind_date. TRY. stylemapping = me->excel->get_style_to_guid( <fs_sheet_content>-cell_style ). CATCH zcx_excel . ENDTRY. IF stylemapping-complete_stylex-number_format-format_code IS INITIAL OR stylemapping-complete_style-number_format-format_code IS INITIAL. lo_format_code_datetime = zcl_excel_style_number_format=>c_format_date_std. ELSE. lo_format_code_datetime = stylemapping-complete_style-number_format-format_code. ENDIF. me->change_cell_style( ip_column = ip_column ip_row = ip_row ip_number_format_format_code = lo_format_code_datetime ). WHEN cl_abap_typedescr=>typekind_time. TRY. stylemapping = me->excel->get_style_to_guid( <fs_sheet_content>-cell_style ). CATCH zcx_excel . ENDTRY. IF stylemapping-complete_stylex-number_format-format_code IS INITIAL OR stylemapping-complete_style-number_format-format_code IS INITIAL. lo_format_code_datetime = zcl_excel_style_number_format=>c_format_date_time6. ELSE. lo_format_code_datetime = stylemapping-complete_style-number_format-format_code. ENDIF. me->change_cell_style( ip_column = ip_column ip_row = ip_row ip_number_format_format_code = lo_format_code_datetime ). ENDCASE. * End of change issue #152 - don't touch exisiting style if only value is passed endmethod. method SET_CELL_STYLE. DATA: lv_column TYPE zexcel_cell_column, ls_sheet_content TYPE zexcel_s_cell_data, lv_row_alpha TYPE string, lo_style TYPE REF TO zcl_excel_style, lv_style_guid TYPE zexcel_cell_style. FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data. lv_style_guid = ip_style. lv_column = zcl_excel_common=>convert_column2int( ip_column ). READ TABLE sheet_content ASSIGNING <fs_sheet_content> WITH KEY cell_row = ip_row cell_column = lv_column. IF sy-subrc EQ 0. <fs_sheet_content>-cell_style = lv_style_guid. ELSE. set_cell( ip_column = ip_column ip_row = ip_row ip_value = '' ip_style = ip_style ). ENDIF. endmethod. method SET_COLUMN_WIDTH. DATA: column_dimension TYPE REF TO zcl_excel_worksheet_columndime. DATA: width TYPE float. column_dimension = me->get_column_dimension( ip_column ). * if a fix size is supplied use this IF ip_width_fix IS SUPPLIED. TRY. width = ip_width_fix. IF width <= 0. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Please supply a positive number as column-width'. ENDIF. column_dimension->set_width( width ). EXIT. CATCH cx_sy_conversion_no_number. * Strange stuff passed --> raise error RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Unable to interpret supplied input as number'. ENDTRY. ENDIF. * If we get down to here, we have to use whatever is found in autosize. column_dimension->set_auto_size( ip_width_autosize ). endmethod. method SET_DEFAULT_EXCEL_DATE_FORMAT. IF ip_default_excel_date_format IS INITIAL. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Default date format cannot be blank'. ENDIF. default_excel_date_format = ip_default_excel_date_format. endmethod. method SET_MERGE. DATA: lv_column_start TYPE zexcel_cell_column, lv_column_end TYPE zexcel_cell_column, ls_sheet_content TYPE zexcel_s_cell_data, lv_row_alpha TYPE string. FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data. lv_column_start = zcl_excel_common=>convert_column2int( ip_column_start ). lv_column_end = zcl_excel_common=>convert_column2int( ip_column_end ). ls_sheet_content-cell_row = ip_row. ls_sheet_content-cell_column = lv_column_start. lv_row_alpha = ip_row. SHIFT lv_row_alpha RIGHT DELETING TRAILING space. SHIFT lv_row_alpha LEFT DELETING LEADING space. CONCATENATE ip_column_start lv_row_alpha INTO ls_sheet_content-cell_coords. INSERT ls_sheet_content INTO TABLE sheet_content_merge. ls_sheet_content-cell_column = lv_column_end. IF ip_row_to IS SUPPLIED. ls_sheet_content-cell_row = ip_row_to. lv_row_alpha = ip_row_to. ELSE. lv_row_alpha = ip_row. ls_sheet_content-cell_row = ip_row. ENDIF. SHIFT lv_row_alpha RIGHT DELETING TRAILING space. SHIFT lv_row_alpha LEFT DELETING LEADING space. CONCATENATE ip_column_end lv_row_alpha INTO ls_sheet_content-cell_coords. INSERT ls_sheet_content INTO TABLE sheet_content_merge. endmethod. method SET_PRINT_GRIDLINES. me->print_gridlines = i_print_gridlines. endmethod. method SET_ROW_HEIGHT. DATA: row_dimension TYPE REF TO zcl_excel_worksheet_rowdimensi. DATA: height TYPE float. row_dimension = me->get_row_dimension( ip_row ). * if a fix size is supplied use this TRY. height = ip_height_fix. IF height <= 0. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Please supply a positive number as row-height'. ENDIF. row_dimension->set_row_height( height ). EXIT. CATCH cx_sy_conversion_no_number. * Strange stuff passed --> raise error RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Unable to interpret supplied input as number'. ENDTRY. endmethod. method SET_SHOW_GRIDLINES. me->show_gridlines = i_show_gridlines. endmethod. method SET_SHOW_ROWCOLHEADERS. me->show_rowcolheaders = i_show_rowcolheaders. endmethod. method SET_TABCOLOR. me->tabcolor = iv_tabcolor. endmethod. method SET_TABLE. DATA: lo_tabdescr TYPE REF TO cl_abap_structdescr, lr_data TYPE REF TO data, ls_newline TYPE REF TO data, ls_header TYPE x030l, lt_dfies TYPE ddfields, lv_row_header TYPE zexcel_cell_row VALUE '2', lv_col_header TYPE zexcel_cell_column_alpha VALUE 'B', lv_row_int TYPE zexcel_cell_row, lv_column_int TYPE zexcel_cell_column, lv_column_alpha TYPE zexcel_cell_column_alpha, lv_cell_value TYPE zexcel_cell_value. FIELD-SYMBOLS: <fs_table_line> TYPE ANY, <fs_fldval> TYPE ANY, <fs_dfies> TYPE dfies, <fs_cell_value> TYPE zexcel_cell_value. lv_column_int = zcl_excel_common=>convert_column2int( ip_top_left_column ). lv_row_int = ip_top_left_row. CREATE DATA lr_data LIKE LINE OF ip_table. lo_tabdescr ?= cl_abap_structdescr=>describe_by_data_ref( lr_data ). ls_header = lo_tabdescr->get_ddic_header( ). lt_dfies = lo_tabdescr->get_ddic_field_list( ). * It is better to loop column by column LOOP AT lt_dfies ASSIGNING <fs_dfies>. lv_column_alpha = zcl_excel_common=>convert_column2alpha( lv_column_int ). IF ip_no_header = abap_false. " First of all write column header lv_cell_value = <fs_dfies>-scrtext_m. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = lv_cell_value ip_style = ip_hdr_style ). IF ip_transpose = abap_true. ADD 1 TO lv_column_int. ELSE. ADD 1 TO lv_row_int. ENDIF. ENDIF. LOOP AT ip_table ASSIGNING <fs_table_line>. lv_column_alpha = zcl_excel_common=>convert_column2alpha( lv_column_int ). ASSIGN COMPONENT <fs_dfies>-fieldname OF STRUCTURE <fs_table_line> TO <fs_fldval>. MOVE <fs_fldval> TO lv_cell_value. me->set_cell( ip_column = lv_column_alpha ip_row = lv_row_int ip_value = <fs_fldval> "lv_cell_value ip_style = ip_body_style ). IF ip_transpose = abap_true. ADD 1 TO lv_column_int. ELSE. ADD 1 TO lv_row_int. ENDIF. ENDLOOP. IF ip_transpose = abap_true. lv_column_int = zcl_excel_common=>convert_column2int( ip_top_left_column ). ADD 1 TO lv_row_int. ELSE. lv_row_int = ip_top_left_row. ADD 1 TO lv_column_int. ENDIF. ENDLOOP. endmethod. method SET_TITLE. DATA: lo_worksheets_iterator TYPE REF TO cl_object_collection_iterator, lo_worksheet TYPE REF TO zcl_excel_worksheet, errormessage TYPE string, lv_rangesheetname_old TYPE string, lv_rangesheetname_new TYPE string, lo_ranges_iterator TYPE REF TO cl_object_collection_iterator, lo_range TYPE REF TO zcl_excel_range, lv_range_value TYPE zexcel_range_value. * Check whether title consists only of allowed characters * Illegal characters are: / \ [ ] * ? : --> http://msdn.microsoft.com/en-us/library/ff837411.aspx IF ip_title CA '/\[]*?:'. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = 'Found illegal character in sheetname. List of forbidden characters: /\[]*?: '. ENDIF. * Check whether title is unique in worksheet lo_worksheets_iterator = me->excel->get_worksheets_iterator( ). WHILE lo_worksheets_iterator->has_next( ) = 'X'. lo_worksheet ?= lo_worksheets_iterator->get_next( ). CHECK me->guid <> lo_worksheet->get_guid( ). " Don't check against itself IF ip_title = lo_worksheet->get_title( ). " Not unique --> raise exception errormessage = 'Duplicate sheetname &'. REPLACE '&' IN errormessage WITH ip_title. RAISE EXCEPTION TYPE zcx_excel EXPORTING error = errormessage. ENDIF. ENDWHILE. CONCATENATE me->title '!' INTO lv_rangesheetname_old. me->title = ip_title. * After changing this worksheets title we have to adjust * all ranges that are referring to this worksheet. CONCATENATE me->title '!' INTO lv_rangesheetname_new. lo_ranges_iterator = me->excel->get_ranges_iterator( ). WHILE lo_ranges_iterator->has_next( ) = 'X'. lo_range ?= lo_ranges_iterator->get_next( ). lv_range_value = lo_range->get_value( ). REPLACE ALL OCCURRENCES OF lv_rangesheetname_old IN lv_range_value WITH lv_rangesheetname_new. IF sy-subrc = 0. lo_range->set_range_value( lv_range_value ). ENDIF. ENDWHILE. endmethod. method UPDATE_DIMENSION_RANGE. DATA: ls_sheet_content TYPE zexcel_s_cell_data, lt_sheet_content TYPE zexcel_t_cell_data_unsorted, lv_row_alpha TYPE string, lv_column_alpha TYPE zexcel_cell_column_alpha. CHECK sheet_content IS NOT INITIAL. * update dimension range lt_sheet_content = sheet_content. "upper left corner SORT lt_sheet_content BY cell_row. READ TABLE lt_sheet_content INDEX 1 INTO ls_sheet_content. upper_cell-cell_row = ls_sheet_content-cell_row. SORT lt_sheet_content BY cell_column. READ TABLE lt_sheet_content INDEX 1 INTO ls_sheet_content. upper_cell-cell_column = ls_sheet_content-cell_column. lv_row_alpha = upper_cell-cell_row. lv_column_alpha = zcl_excel_common=>convert_column2alpha( upper_cell-cell_column ). SHIFT lv_row_alpha RIGHT DELETING TRAILING space. SHIFT lv_row_alpha LEFT DELETING LEADING space. CONCATENATE lv_column_alpha lv_row_alpha INTO upper_cell-cell_coords. "bottom right corner SORT lt_sheet_content BY cell_row DESCENDING. READ TABLE lt_sheet_content INDEX 1 INTO ls_sheet_content. lower_cell-cell_row = ls_sheet_content-cell_row. SORT lt_sheet_content BY cell_column DESCENDING. READ TABLE lt_sheet_content INDEX 1 INTO ls_sheet_content. lower_cell-cell_column = ls_sheet_content-cell_column. lv_row_alpha = lower_cell-cell_row. lv_column_alpha = zcl_excel_common=>convert_column2alpha( lower_cell-cell_column ). SHIFT lv_row_alpha RIGHT DELETING TRAILING space. SHIFT lv_row_alpha LEFT DELETING LEADING space. CONCATENATE lv_column_alpha lv_row_alpha INTO lower_cell-cell_coords. endmethod.