*"* 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. "c_oi_proxy_error DEFINITION
*--------------------------------------------------------------------*
* 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. "lcl_gui_alv_grid DEFINITION*"* use this source file for any macro definitions you need
*"* in the implementation part of the classABAPSLISSOImethod ZIF_EXCEL_SHEET_PRINTSETTINGS~CLEAR_PRINT_REPEAT_COLUMNS.
*--------------------------------------------------------------------*
* adjust internal representation
*--------------------------------------------------------------------*
CLEAR: me->print_title_col_from,
me->print_title_col_to .
*--------------------------------------------------------------------*
* adjust corresponding range
*--------------------------------------------------------------------*
me->print_title_set_range( ).
endmethod.method ZIF_EXCEL_SHEET_PRINTSETTINGS~CLEAR_PRINT_REPEAT_ROWS.
*--------------------------------------------------------------------*
* adjust internal representation
*--------------------------------------------------------------------*
CLEAR: me->print_title_row_from,
me->print_title_row_to .
*--------------------------------------------------------------------*
* adjust corresponding range
*--------------------------------------------------------------------*
me->print_title_set_range( ).
endmethod.method ZIF_EXCEL_SHEET_PRINTSETTINGS~GET_PRINT_REPEAT_COLUMNS.
ev_columns_from = me->print_title_col_from.
ev_columns_to = me->print_title_col_to.
endmethod.method ZIF_EXCEL_SHEET_PRINTSETTINGS~GET_PRINT_REPEAT_ROWS.
ev_rows_from = me->print_title_row_from.
ev_rows_to = me->print_title_row_to.
endmethod.method ZIF_EXCEL_SHEET_PRINTSETTINGS~SET_PRINT_REPEAT_COLUMNS.
*--------------------------------------------------------------------*
* issue#235 - repeat rows/columns
* - Stefan Schmöcker, 2012-12-02
*--------------------------------------------------------------------*
DATA: lv_col_from_int TYPE i,
lv_col_to_int TYPE i,
lv_errormessage TYPE string.
DATA: lo_range_iterator TYPE REF TO cl_object_collection_iterator,
lo_range TYPE REF TO zcl_excel_range.
lv_col_from_int = zcl_excel_common=>convert_column2int( iv_columns_from ).
lv_col_to_int = zcl_excel_common=>convert_column2int( iv_columns_to ).
*--------------------------------------------------------------------*
* Check if valid range is supplied
*--------------------------------------------------------------------*
IF lv_col_from_int < 1.
lv_errormessage = 'Invalid range supplied for print-title repeatable columns'(401).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
IF lv_col_from_int > lv_col_to_int.
lv_errormessage = 'Invalid range supplied for print-title repeatable columns'(401).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* adjust internal representation
*--------------------------------------------------------------------*
me->print_title_col_from = iv_columns_from.
me->print_title_col_to = iv_columns_to.
*--------------------------------------------------------------------*
* adjust corresponding range
*--------------------------------------------------------------------*
me->print_title_set_range( ).
endmethod.method ZIF_EXCEL_SHEET_PRINTSETTINGS~SET_PRINT_REPEAT_ROWS.
*--------------------------------------------------------------------*
* issue#235 - repeat rows/columns
* - Stefan Schmöcker, 2012-12-02
*--------------------------------------------------------------------*
DATA: lv_errormessage TYPE string.
DATA: lo_range_iterator TYPE REF TO cl_object_collection_iterator,
lo_range TYPE REF TO zcl_excel_range.
*--------------------------------------------------------------------*
* Check if valid range is supplied
*--------------------------------------------------------------------*
IF iv_rows_from < 1.
lv_errormessage = 'Invalid range supplied for print-title repeatable rowumns'(401).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
IF iv_rows_from > iv_rows_to.
lv_errormessage = 'Invalid range supplied for print-title repeatable rowumns'(401).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* adjust internal representation
*--------------------------------------------------------------------*
me->print_title_row_from = iv_rows_from.
me->print_title_row_to = iv_rows_to.
*--------------------------------------------------------------------*
* adjust corresponding range
*--------------------------------------------------------------------*
me->print_title_set_range( ).
endmethod.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.
* use prefix notation for signed numbers
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.
*--------------------------------------------------------------------*
* issue #230 - Pimp my Code
* - Stefan Schmöcker, (wi p) 2012-12-01
* - ...
* aligning code
* message made to support multilinguality
*--------------------------------------------------------------------*
* issue #237 - Check if overlapping areas exist
* - Alessandro Iannacci 2012-12-01
* changes: - Added raise if overlaps are detected
*--------------------------------------------------------------------*
CONSTANTS:
lc_top_left_column TYPE zexcel_cell_column_alpha VALUE 'B',
lc_top_left_row TYPE zexcel_cell_row VALUE 3.
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_value_lowercase TYPE string,
lv_syindex TYPE char3,
lv_errormessage TYPE string, "ins issue #237
lv_columns TYPE i,
lt_columns TYPE zexcel_t_fieldcatalog,
lv_maxcol TYPE i,
lv_maxrow TYPE i,
lo_iterator TYPE REF TO cl_object_collection_iterator,
lo_curtable TYPE REF TO zcl_excel_table.
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.
*--------------------------------------------------------------------*
* issue #237 Check if overlapping areas exist Start
*--------------------------------------------------------------------*
"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.
lv_column_int = zcl_excel_common=>convert_column2int( ls_settings-top_left_column ).
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 )
)
AND
( ( lv_column_int GE zcl_excel_common=>convert_column2int( lo_curtable->settings-top_left_column ) AND lv_column_int LE zcl_excel_common=>convert_column2int( 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 zcl_excel_common=>convert_column2int( lo_curtable->settings-bottom_right_column ) )
).
lv_errormessage = 'Table overlaps with previously bound table and will not be added to worksheet.'(400).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
ENDWHILE.
*--------------------------------------------------------------------*
* issue #237 Check if overlapping areas exist End
*--------------------------------------------------------------------*
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.
lv_value_lowercase = lv_value.
TRANSLATE lv_value_lowercase TO LOWER CASE.
READ TABLE lt_column_name_buffer TRANSPORTING NO FIELDS WITH KEY table_line = lv_value_lowercase BINARY SEARCH.
IF sy-subrc <> 0.
<ls_field_catalog>-scrtext_l = lv_value.
INSERT lv_value_lowercase 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>.
" issue #290 Add formula support in table
IF <ls_field_catalog>-formula EQ abap_true.
IF <ls_field_catalog>-style IS NOT INITIAL.
me->set_cell( ip_column = lv_column_alpha
ip_row = lv_row_int
ip_formula = <fs_fldval>
ip_style = <ls_field_catalog>-style ).
ELSE.
me->set_cell( ip_column = lv_column_alpha
ip_row = lv_row_int
ip_formula = <fs_fldval> ).
ENDIF.
ELSE.
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.
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.
" >> Issue #291
IF ip_table IS INITIAL.
es_table_settings-bottom_right_row = ls_settings-top_left_row + 2. "Last rows
ELSE.
es_table_settings-bottom_right_row = ls_settings-top_left_row + lv_rows + 1. "Last rows
ENDIF.
" << Issue #291
endmethod.*--------------------------------------------------------------------*
* issue #293 - Roberto Bianco
* - Christian Assig 2014-03-14
*
* changes: - Calculate widths using SAPscript font metrics
* (transaction SE73)
* - Calculate the width of dates
* - Add additional width for auto filter buttons
* - Add cell padding to simulate Excel behavior
*--------------------------------------------------------------------*
METHOD calculate_cell_width.
CONSTANTS:
lc_default_font_name TYPE zexcel_style_font_name VALUE 'Calibri', "#EC NOTEXT
lc_default_font_height TYPE tdfontsize VALUE '110',
lc_excel_cell_padding TYPE float VALUE '0.75'.
DATA: ld_cell_value TYPE zexcel_cell_value,
ld_current_character TYPE c LENGTH 1,
ld_style_guid TYPE zexcel_cell_style,
ls_stylemapping TYPE zexcel_s_stylemapping,
lo_table_object TYPE REF TO object,
lo_table TYPE REF TO zcl_excel_table,
ld_table_top_left_column TYPE zexcel_cell_column,
ld_table_bottom_right_column TYPE zexcel_cell_column,
ld_flag_contains_auto_filter TYPE abap_bool VALUE abap_false,
ld_flag_bold TYPE abap_bool VALUE abap_false,
ld_flag_italic TYPE abap_bool VALUE abap_false,
ld_date TYPE d,
ld_date_char TYPE c LENGTH 50,
ld_font_height TYPE tdfontsize VALUE lc_default_font_height,
lt_itcfc TYPE STANDARD TABLE OF itcfc,
ld_offset TYPE i,
ld_length TYPE i,
ld_uccp TYPE i,
ls_font_metric TYPE mty_s_font_metric,
ld_width_from_font_metrics TYPE i,
ld_font_family TYPE itcfh-tdfamily,
ld_font_name TYPE zexcel_style_font_name VALUE lc_default_font_name,
lt_font_families LIKE STANDARD TABLE OF ld_font_family,
ls_font_cache TYPE mty_s_font_cache.
FIELD-SYMBOLS: <ls_font_cache> TYPE mty_s_font_cache,
<ls_font_metric> TYPE mty_s_font_metric,
<ls_itcfc> TYPE itcfc.
" Determine cell content and cell style
me->get_cell( EXPORTING ip_column = ip_column
ip_row = ip_row
IMPORTING ep_value = ld_cell_value
ep_guid = ld_style_guid ).
" ABAP2XLSX uses tables to define areas containing headers and
" auto-filters. Find out if the current cell is in the header
" of one of these tables.
LOOP AT me->tables->collection INTO lo_table_object.
" Downcast: OBJECT -> ZCL_EXCEL_TABLE
lo_table ?= lo_table_object.
" Convert column letters to corresponding integer values
ld_table_top_left_column =
zcl_excel_common=>convert_column2int(
lo_table->settings-top_left_column ).
ld_table_bottom_right_column =
zcl_excel_common=>convert_column2int(
lo_table->settings-bottom_right_column ).
" Is the current cell part of the table header?
IF ip_column BETWEEN ld_table_top_left_column AND
ld_table_bottom_right_column AND
ip_row EQ lo_table->settings-top_left_row.
" Current cell is part of the table header
" -> Assume that an auto filter is present and that the font is
" bold
ld_flag_contains_auto_filter = abap_true.
ld_flag_bold = abap_true.
ENDIF.
ENDLOOP.
" If a style GUID is present, read style attributes
IF ld_style_guid IS NOT INITIAL.
TRY.
" Read style attributes
ls_stylemapping = me->excel->get_style_to_guid( ld_style_guid ).
" If the current cell contains the default date format,
" convert the cell value to a date and calculate its length
IF ls_stylemapping-complete_style-number_format-format_code =
zcl_excel_style_number_format=>c_format_date_std.
" Convert excel date to ABAP date
ld_date =
zcl_excel_common=>excel_string_to_date( ld_cell_value ).
" Format ABAP date using user's formatting settings
WRITE ld_date TO ld_date_char.
" Remember the formatted date to calculate the cell size
ld_cell_value = ld_date_char.
ENDIF.
" Read the font size and convert it to the font height
" used by SAPscript (multiplication by 10)
IF ls_stylemapping-complete_stylex-font-size = abap_true.
ld_font_height = ls_stylemapping-complete_style-font-size * 10.
ENDIF.
" If set, remember the font name
IF ls_stylemapping-complete_stylex-font-name = abap_true.
ld_font_name = ls_stylemapping-complete_style-font-name.
ENDIF.
" If set, remember whether font is bold and italic.
IF ls_stylemapping-complete_stylex-font-bold = abap_true.
ld_flag_bold = ls_stylemapping-complete_style-font-bold.
ENDIF.
IF ls_stylemapping-complete_stylex-font-italic = abap_true.
ld_flag_italic = ls_stylemapping-complete_style-font-italic.
ENDIF.
CATCH zcx_excel ##NO_HANDLER.
" Style GUID is present, but style was not found
" Continue with default values
ENDTRY.
ENDIF.
" Check if the same font (font name and font attributes) was already
" used before
READ TABLE mth_font_cache
WITH TABLE KEY
font_name = ld_font_name
font_height = ld_font_height
flag_bold = ld_flag_bold
flag_italic = ld_flag_italic
ASSIGNING <ls_font_cache>.
IF sy-subrc <> 0.
" Font is used for the first time
" Add the font to our local font cache
ls_font_cache-font_name = ld_font_name.
ls_font_cache-font_height = ld_font_height.
ls_font_cache-flag_bold = ld_flag_bold.
ls_font_cache-flag_italic = ld_flag_italic.
INSERT ls_font_cache INTO TABLE mth_font_cache
ASSIGNING <ls_font_cache>.
" Determine the SAPscript font family name from the Excel
" font name
SELECT tdfamily
FROM tfo01
INTO TABLE lt_font_families
UP TO 1 ROWS
WHERE tdtext = ld_font_name.
" Check if a matching font family was found
" Fonts can be uploaded from TTF files using transaction SE73
IF lines( lt_font_families ) > 0.
READ TABLE lt_font_families INDEX 1 INTO ld_font_family.
" Load font metrics (returns a table with the size of each letter
" in the font)
CALL FUNCTION 'LOAD_FONT'
EXPORTING
family = ld_font_family
height = ld_font_height
printer = 'SWIN'
bold = ld_flag_bold
italic = ld_flag_italic
TABLES
metric = lt_itcfc
EXCEPTIONS
font_family = 1
codepage = 2
device_type = 3
OTHERS = 4.
IF sy-subrc <> 0.
CLEAR lt_itcfc.
ENDIF.
" For faster access, convert each character number to the actual
" character, and store the characters and their sizes in a hash
" table
LOOP AT lt_itcfc ASSIGNING <ls_itcfc>.
ld_uccp = <ls_itcfc>-cpcharno.
ls_font_metric-char =
cl_abap_conv_in_ce=>uccpi( ld_uccp ).
ls_font_metric-char_width = <ls_itcfc>-tdcwidths.
INSERT ls_font_metric
INTO TABLE <ls_font_cache>-th_font_metrics.
ENDLOOP.
ENDIF.
ENDIF.
" Calculate the cell width
" If available, use font metrics
IF lines( <ls_font_cache>-th_font_metrics ) = 0.
" Font metrics are not available
" -> Calculate the cell width using only the font size
ld_length = strlen( ld_cell_value ).
ep_width = ld_length * ld_font_height / lc_default_font_height + lc_excel_cell_padding.
ELSE.
" Font metrics are available
" Calculate the size of the text by adding the sizes of each
" letter
ld_length = strlen( ld_cell_value ).
DO ld_length TIMES.
" Subtract 1, because the first character is at offset 0
ld_offset = sy-index - 1.
" Read the current character from the cell value
ld_current_character = ld_cell_value+ld_offset(1).
" Look up the size of the current letter
READ TABLE <ls_font_cache>-th_font_metrics
WITH TABLE KEY char = ld_current_character
ASSIGNING <ls_font_metric>.
IF sy-subrc = 0.
" The size of the letter is known
" -> Add the actual size of the letter
ADD <ls_font_metric>-char_width TO ld_width_from_font_metrics.
ELSE.
" The size of the letter is unknown
" -> Add the font height as the default letter size
ADD ld_font_height TO ld_width_from_font_metrics.
ENDIF.
ENDDO.
" Add cell padding (Excel makes columns a bit wider than the space
" that is needed for the text itself) and convert unit
" (division by 100)
ep_width = ld_width_from_font_metrics / 100 + lc_excel_cell_padding.
ENDIF.
" If the current cell contains an auto filter, make it a bit wider.
" The size used by the auto filter button does not depend on the font
" size.
IF ld_flag_contains_auto_filter = abap_true.
ADD 2 TO ep_width.
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 float.
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.
* Do not check merged cells
IF is_cell_merged(
ip_column = <auto_size>-col_index
ip_row = count ) = abap_false.
* 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.
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 zexcel_cell_style. "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_protection TO complete_style-protection.
IF ip_xprotection IS SUPPLIED.
MOVE-CORRESPONDING ip_xprotection TO complete_stylex-protection.
ELSE.
IF ip_protection-hidden IS NOT INITIAL.
complete_stylex-protection-hidden = 'X'.
ENDIF.
IF ip_protection-locked IS NOT INITIAL.
complete_stylex-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 delete_row_outline.
DELETE me->mt_row_outlines WHERE row_from = iv_row_from
AND row_to = iv_row_to.
IF sy-subrc <> 0. " didn't find outline that was to be deleted
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Row outline to be deleted does not exist'.
ENDIF.
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: <ls_row_dimension> LIKE LINE OF me->row_dimensions.
DATA: ls_row_dimension LIKE LINE OF me->row_dimensions.
READ TABLE me->row_dimensions ASSIGNING <ls_row_dimension>
WITH TABLE KEY row = ip_row.
IF NOT <ls_row_dimension> IS ASSIGNED.
CREATE OBJECT r_row_dimension
EXPORTING
ip_index = ip_row.
ls_row_dimension-row = ip_row.
ls_row_dimension-row_dimension = r_row_dimension.
INSERT ls_row_dimension INTO TABLE me->row_dimensions.
ELSE.
r_row_dimension = <ls_row_dimension>-row_dimension.
ENDIF.
ENDMETHOD.METHOD get_row_dimensions.
r_row_dimension[] = me->row_dimensions[].
ENDMETHOD.METHOD get_row_outlines.
rt_row_outlines = me->mt_row_outlines.
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 IS_CELL_MERGED.
DATA lt_merge_range TYPE string_table.
FIELD-SYMBOLS <lv_merge_range> LIKE LINE OF lt_merge_range.
lt_merge_range = me->get_merge( ).
LOOP AT lt_merge_range ASSIGNING <lv_merge_range>.
rp_is_merged = zcl_excel_common=>is_cell_in_range(
ip_column = ip_column
ip_row = ip_row
ip_range = <lv_merge_range> ).
IF rp_is_merged = abap_true.
EXIT.
ENDIF.
ENDLOOP.
endmethod.method PRINT_TITLE_SET_RANGE.
*--------------------------------------------------------------------*
* issue#235 - repeat rows/columns
* - Stefan Schmoecker, 2012-12-02
*--------------------------------------------------------------------*
DATA: lo_range_iterator TYPE REF TO cl_object_collection_iterator,
lo_range TYPE REF TO zcl_excel_range,
lv_repeat_range_sheetname TYPE string,
lv_repeat_range_col TYPE string,
lv_row_char_from TYPE char10,
lv_row_char_to TYPE char10,
lv_repeat_range_row TYPE string,
lv_repeat_range TYPE string.
*--------------------------------------------------------------------*
* Get range that represents printarea
* if non-existant, create it
*--------------------------------------------------------------------*
lo_range_iterator = me->get_ranges_iterator( ).
WHILE lo_range_iterator->has_next( ) = abap_true.
lo_range ?= lo_range_iterator->get_next( ).
IF lo_range->name = zif_excel_sheet_printsettings=>gcv_print_title_name.
EXIT. " Found it
ENDIF.
CLEAR lo_range.
ENDWHILE.
IF me->print_title_col_from IS INITIAL AND
me->print_title_row_from IS INITIAL.
*--------------------------------------------------------------------*
* No print titles are present,
*--------------------------------------------------------------------*
IF lo_range IS BOUND.
me->ranges->remove( lo_range ).
ENDIF.
ELSE.
*--------------------------------------------------------------------*
* Print titles are present,
*--------------------------------------------------------------------*
IF lo_range IS NOT BOUND.
lo_range = me->add_new_range( ).
lo_range->name = zif_excel_sheet_printsettings=>gcv_print_title_name.
ENDIF.
lv_repeat_range_sheetname = me->get_title( ).
lv_repeat_range_sheetname = zcl_excel_common=>escape_string( lv_repeat_range_sheetname ).
*--------------------------------------------------------------------*
* Repeat-columns
*--------------------------------------------------------------------*
IF me->print_title_col_from IS NOT INITIAL.
CONCATENATE lv_repeat_range_sheetname
'!$' me->print_title_col_from
':$' me->print_title_col_to
INTO lv_repeat_range_col.
ENDIF.
*--------------------------------------------------------------------*
* Repeat-rows
*--------------------------------------------------------------------*
IF me->print_title_row_from IS NOT INITIAL.
lv_row_char_from = me->print_title_row_from.
lv_row_char_to = me->print_title_row_to.
CONCATENATE '!$' lv_row_char_from
':$' lv_row_char_to
INTO lv_repeat_range_row.
CONDENSE lv_repeat_range_row NO-GAPS.
CONCATENATE lv_repeat_range_sheetname
lv_repeat_range_row
INTO lv_repeat_range_row.
ENDIF.
*--------------------------------------------------------------------*
* Concatenate repeat-rows and columns
*--------------------------------------------------------------------*
IF lv_repeat_range_col IS INITIAL.
lv_repeat_range = lv_repeat_range_row.
ELSEIF lv_repeat_range_row IS INITIAL.
lv_repeat_range = lv_repeat_range_col.
ELSE.
CONCATENATE lv_repeat_range_col lv_repeat_range_row
INTO lv_repeat_range SEPARATED BY ','.
ENDIF.
lo_range->set_range_value( lv_repeat_range ).
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 TABLE KEY cell_row = ip_row " Changed to access via table key , Stefan Schmöcker, 2013-08-03
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
* Fix issue #162
lv_value = ip_value.
IF lv_value CS cl_abap_char_utilities=>cr_lf.
me->change_cell_style( ip_column = ip_column
ip_row = ip_row
ip_alignment_wraptext = abap_true ).
ENDIF.
* End of Fix issue #162
endmethod.method SET_CELL_FORMULA.
DATA:
lv_column TYPE zexcel_cell_column,
ls_sheet_content LIKE LINE OF me->sheet_content.
FIELD-SYMBOLS:
<sheet_content> LIKE LINE OF me->sheet_content.
*--------------------------------------------------------------------*
* Get cell to set formula into
*--------------------------------------------------------------------*
lv_column = zcl_excel_common=>convert_column2int( ip_column ).
READ TABLE me->sheet_content ASSIGNING <sheet_content> WITH TABLE KEY cell_row = ip_row
cell_column = lv_column.
IF sy-subrc <> 0. " Create new entry in sheet_content if necessary
CHECK ip_formula IS INITIAL. " no need to create new entry in sheet_content when no formula is passed
ls_sheet_content-cell_row = ip_row.
ls_sheet_content-cell_column = lv_column.
INSERT ls_sheet_content INTO TABLE me->sheet_content ASSIGNING <sheet_content>.
ENDIF.
*--------------------------------------------------------------------*
* Fieldsymbol now holds the relevant cell
*--------------------------------------------------------------------*
<sheet_content>-cell_formula = ip_formula.
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_row_outline.
DATA: ls_row_outline LIKE LINE OF me->mt_row_outlines.
FIELD-SYMBOLS: <ls_row_outline> LIKE LINE OF me->mt_row_outlines.
READ TABLE me->mt_row_outlines ASSIGNING <ls_row_outline> WITH TABLE KEY row_from = iv_row_from
row_to = iv_row_to.
IF sy-subrc <> 0.
IF iv_row_from <= 0.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'First row of outline must be a positive number'.
ENDIF.
IF iv_row_to < iv_row_from.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Last row of outline may not be less than first line of outline'.
ENDIF.
ls_row_outline-row_from = iv_row_from.
ls_row_outline-row_to = iv_row_to.
INSERT ls_row_outline INTO TABLE me->mt_row_outlines ASSIGNING <ls_row_outline>.
ENDIF.
CASE iv_collapsed.
WHEN abap_true
OR abap_false.
<ls_row_outline>-collapsed = iv_collapsed.
WHEN OTHERS.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Unknown collapse state'.
ENDCASE.
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.
*--------------------------------------------------------------------*
* ToDos:
* 2doç1 The current coding for replacing a named ranges name
* after renaming a sheet should be checked if it is
* really working if sheetname should be escaped
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* issue #230 - Pimp my Code
* - Stefan Schmoecker, (wip ) 2012-12-08
* - ...
* changes: aligning code
* message made to support multilinguality
*--------------------------------------------------------------------*
* issue#243 - ' is not allowed as first character in sheet title
* - Stefan Schmoecker, 2012-12-02
* changes: added additional check for ' as first character
*--------------------------------------------------------------------*
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,
lv_errormessage TYPE string. " Can't pass '...'(abc) to exception-class
*--------------------------------------------------------------------*
* Check whether title consists only of allowed characters
* Illegal characters are: / \ [ ] * ? : --> http://msdn.microsoft.com/en-us/library/ff837411.aspx
* Illegal characters not in documentation: ' as first character
*--------------------------------------------------------------------*
IF ip_title CA '/\[]*?:'.
lv_errormessage = 'Found illegal character in sheetname. List of forbidden characters: /\[]*?:'(402).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
IF ip_title IS NOT INITIAL AND ip_title(1) = `'`.
lv_errormessage = 'Sheetname may not start with &'(403). " & used instead of ' to allow fallbacklanguage
REPLACE '&' IN lv_errormessage WITH `'`.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* Check whether title is unique in workbook
*--------------------------------------------------------------------*
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.
*--------------------------------------------------------------------*
* Remember old sheetname and rename sheet to desired name
*--------------------------------------------------------------------*
CONCATENATE me->title '!' INTO lv_rangesheetname_old.
me->title = ip_title.
*--------------------------------------------------------------------*
* After changing this worksheet's title we have to adjust
* all ranges that are referring to this worksheet.
*--------------------------------------------------------------------*
* 2doç1 - Check if the following quickfix is solid
* I fear it isn't - but this implementation is better then
* nothing at all since it handles a supposed majority of cases
*--------------------------------------------------------------------*
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.