From 90981b21c5c1bd1f80ca38e55b03a4c99b9aa27a Mon Sep 17 00:00:00 2001 From: Derby <75079431+boy0korea@users.noreply.github.com> Date: Tue, 30 Aug 2022 01:04:16 +0900 Subject: [PATCH] add METHOD convert_to_table. (#999) * added METHOD convert_to_table. Co-authored-by: Abo Co-authored-by: Lars Hvam Co-authored-by: Domi Bigl --- src/zcl_excel_worksheet.clas.abap | 296 +++++++++++++++++++++++++++++- 1 file changed, 291 insertions(+), 5 deletions(-) diff --git a/src/zcl_excel_worksheet.clas.abap b/src/zcl_excel_worksheet.clas.abap index 6dd421a..77ad294 100644 --- a/src/zcl_excel_worksheet.clas.abap +++ b/src/zcl_excel_worksheet.clas.abap @@ -664,6 +664,20 @@ CLASS zcl_excel_worksheet DEFINITION !ip_is_internal TYPE abap_bool RAISING zcx_excel . + "! excel upload, counterpart to BIND_TABLE + "! @parameter it_field_catalog | field catalog, used to derive correct types + "! @parameter iv_begin_row | starting row, by default 2 to skip header + "! @parameter et_data | generic internal table, there may be conversion losses + "! @parameter er_data | ref to internal table of string columns, to get raw data without conversion losses. + METHODS convert_to_table + IMPORTING + !it_field_catalog TYPE zexcel_t_fieldcatalog OPTIONAL + !iv_begin_row TYPE int4 DEFAULT 2 + EXPORTING + !et_data TYPE STANDARD TABLE + !er_data TYPE REF TO data + RAISING + zcx_excel . PROTECTED SECTION. METHODS set_table_reference IMPORTING @@ -2051,6 +2065,281 @@ CLASS zcl_excel_worksheet IMPLEMENTATION. ENDMETHOD. "CONSTRUCTOR + METHOD convert_to_table. + + TYPES: + BEGIN OF ts_field_conv, + fieldname TYPE x031l-fieldname, + convexit TYPE x031l-convexit, + END OF ts_field_conv, + BEGIN OF ts_style_conv, + cell_style TYPE zexcel_s_cell_data-cell_style, + abap_type TYPE abap_typekind, + END OF ts_style_conv. + + DATA: + lv_row_int 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, + ls_field_catalog TYPE zexcel_s_fieldcatalog, + lv_value TYPE string, + lv_maxcol TYPE i, + lv_maxrow TYPE i, + lt_field_conv TYPE TABLE OF ts_field_conv, + lt_comp TYPE abap_component_tab, + ls_comp TYPE abap_componentdescr, + lo_line_type TYPE REF TO cl_abap_structdescr, + lo_tab_type TYPE REF TO cl_abap_tabledescr, + lr_data TYPE REF TO data, + lt_comp_view TYPE abap_component_view_tab, + ls_comp_view TYPE abap_simple_componentdescr, + lt_ddic_object TYPE dd_x031l_table, + lt_ddic_object_comp TYPE dd_x031l_table, + ls_ddic_object TYPE x031l, + lt_style_conv TYPE TABLE OF ts_style_conv, + ls_style_conv TYPE ts_style_conv, + ls_stylemapping TYPE zexcel_s_stylemapping, + lv_format_code TYPE zexcel_number_format, + lv_float TYPE f, + lt_map_excel_row TYPE TABLE OF i, + lv_index TYPE i, + lv_index_col TYPE i. + + FIELD-SYMBOLS: + TYPE STANDARD TABLE, + TYPE data, + TYPE data, + TYPE STANDARD TABLE, + TYPE data, + TYPE data, + TYPE ts_field_conv, + TYPE x031l, + TYPE zexcel_s_cell_data. + + CLEAR: et_data, er_data. + + lv_maxcol = get_highest_column( ). + lv_maxrow = get_highest_row( ). + + + " Field catalog + lt_field_catalog = it_field_catalog. + IF lt_field_catalog IS INITIAL. + IF et_data IS SUPPLIED. + lt_field_catalog = zcl_excel_common=>get_fieldcatalog( ip_table = et_data ). + ELSE. + DO lv_maxcol TIMES. + ls_field_catalog-position = sy-index. + ls_field_catalog-fieldname = 'COL_' && sy-index. + ls_field_catalog-dynpfld = abap_true. + APPEND ls_field_catalog TO lt_field_catalog. + ENDDO. + ENDIF. + ENDIF. + + SORT lt_field_catalog BY position. + DELETE lt_field_catalog WHERE dynpfld NE abap_true. + CHECK: lt_field_catalog IS NOT INITIAL. + + + " Create dynamic table string columns + ls_comp-type = cl_abap_elemdescr=>get_string( ). + LOOP AT lt_field_catalog INTO ls_field_catalog. + ls_comp-name = ls_field_catalog-fieldname. + APPEND ls_comp TO lt_comp. + ENDLOOP. + lo_line_type = cl_abap_structdescr=>create( lt_comp ). + lo_tab_type = cl_abap_tabledescr=>create( lo_line_type ). + CREATE DATA er_data TYPE HANDLE lo_tab_type. + ASSIGN er_data->* TO . + + + " Collect field conversion rules + IF et_data IS SUPPLIED. +* lt_ddic_object = get_ddic_object( et_data ). + lo_tab_type ?= cl_abap_tabledescr=>describe_by_data( et_data ). + lo_line_type ?= lo_tab_type->get_table_line_type( ). + lo_line_type->get_ddic_object( + RECEIVING + p_object = lt_ddic_object + EXCEPTIONS + OTHERS = 3 + ). + IF lt_ddic_object IS INITIAL. + lt_comp_view = lo_line_type->get_included_view( ). + LOOP AT lt_comp_view INTO ls_comp_view. + ls_comp_view-type->get_ddic_object( + RECEIVING + p_object = lt_ddic_object_comp + EXCEPTIONS + OTHERS = 3 + ). + IF lt_ddic_object_comp IS NOT INITIAL. + READ TABLE lt_ddic_object_comp INTO ls_ddic_object INDEX 1. + ls_ddic_object-fieldname = ls_comp_view-name. + APPEND ls_ddic_object TO lt_ddic_object. + ENDIF. + ENDLOOP. + ENDIF. + + SORT lt_ddic_object BY fieldname. + LOOP AT lt_field_catalog INTO ls_field_catalog. + APPEND INITIAL LINE TO lt_field_conv ASSIGNING . + MOVE-CORRESPONDING ls_field_catalog TO . + READ TABLE lt_ddic_object ASSIGNING WITH KEY fieldname = -fieldname BINARY SEARCH. + CHECK: sy-subrc EQ 0. + CASE -exid. + WHEN cl_abap_typedescr=>typekind_int + OR cl_abap_typedescr=>typekind_int1 + OR cl_abap_typedescr=>typekind_int8 + OR cl_abap_typedescr=>typekind_int2 + OR cl_abap_typedescr=>typekind_packed + OR cl_abap_typedescr=>typekind_decfloat + OR cl_abap_typedescr=>typekind_decfloat16 + OR cl_abap_typedescr=>typekind_decfloat34 + OR cl_abap_typedescr=>typekind_float. + " Numbers + -convexit = cl_abap_typedescr=>typekind_float. + WHEN OTHERS. + -convexit = -convexit. + ENDCASE. + ENDLOOP. + ENDIF. + + " Date & Time in excel style + LOOP AT me->sheet_content ASSIGNING WHERE cell_style IS NOT INITIAL AND data_type IS INITIAL. + ls_style_conv-cell_style = -cell_style. + APPEND ls_style_conv TO lt_style_conv. + ENDLOOP. + IF lt_style_conv IS NOT INITIAL. + SORT lt_style_conv BY cell_style. + DELETE ADJACENT DUPLICATES FROM lt_style_conv COMPARING cell_style. + + LOOP AT lt_style_conv INTO ls_style_conv. + + ls_stylemapping = me->excel->get_style_to_guid( ls_style_conv-cell_style ). + lv_format_code = ls_stylemapping-complete_style-number_format-format_code. + " https://support.microsoft.com/en-us/office/number-format-codes-5026bbd6-04bc-48cd-bf33-80f18b4eae68 + IF lv_format_code CS ';'. + lv_format_code = lv_format_code(sy-fdpos). + ENDIF. + CHECK: lv_format_code NA '#?'. + + " Remove color pattern + REPLACE ALL OCCURRENCES OF REGEX '\[\L[^]]*\]' IN lv_format_code WITH ''. + + IF lv_format_code CA 'yd' OR lv_format_code EQ zcl_excel_style_number_format=>c_format_date_std. + " DATE = yyyymmdd + ls_style_conv-abap_type = cl_abap_typedescr=>typekind_date. + ELSEIF lv_format_code CA 'hs'. + " TIME = hhmmss + ls_style_conv-abap_type = cl_abap_typedescr=>typekind_time. + ELSE. + DELETE lt_style_conv. + CONTINUE. + ENDIF. + + MODIFY lt_style_conv FROM ls_style_conv TRANSPORTING abap_type. + + ENDLOOP. + ENDIF. + + +*--------------------------------------------------------------------* +* Start of convert content +*--------------------------------------------------------------------* + READ TABLE me->sheet_content TRANSPORTING NO FIELDS WITH KEY cell_row = iv_begin_row. + IF sy-subrc EQ 0. + lv_index = sy-tabix. + ENDIF. + + LOOP AT me->sheet_content ASSIGNING FROM lv_index. + AT NEW cell_row. + " New line + APPEND INITIAL LINE TO ASSIGNING . + lv_index = sy-tabix. + ENDAT. + + IF -cell_value IS NOT INITIAL. + ASSIGN COMPONENT -cell_column OF STRUCTURE TO . + IF sy-subrc EQ 0. + " value + = -cell_value. + + " field conversion + READ TABLE lt_field_conv ASSIGNING INDEX -cell_column. + IF sy-subrc EQ 0 AND -convexit IS NOT INITIAL. + CASE -convexit. + WHEN cl_abap_typedescr=>typekind_float. + lv_float = zcl_excel_common=>excel_string_to_number( -cell_value ). + = |{ lv_float NUMBER = RAW }|. + WHEN 'ALPHA'. + CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT' + EXPORTING + input = -cell_value + IMPORTING + output = . + ENDCASE. + ENDIF. + + " style conversion + IF -cell_style IS NOT INITIAL. + READ TABLE lt_style_conv INTO ls_style_conv WITH KEY cell_style = -cell_style BINARY SEARCH. + IF sy-subrc EQ 0. + CASE ls_style_conv-abap_type. + WHEN cl_abap_typedescr=>typekind_date. + = zcl_excel_common=>excel_string_to_date( -cell_value ). + WHEN cl_abap_typedescr=>typekind_time. + = zcl_excel_common=>excel_string_to_time( -cell_value ). + ENDCASE. + ENDIF. + ENDIF. + + " condense + CONDENSE . + ENDIF. + ENDIF. + + AT END OF cell_row. + " Delete empty line + IF IS INITIAL. + DELETE INDEX lv_index. + ELSE. + APPEND -cell_row TO lt_map_excel_row. + ENDIF. + ENDAT. + ENDLOOP. +*--------------------------------------------------------------------* +* End of convert content +*--------------------------------------------------------------------* + + + IF et_data IS SUPPLIED. +* MOVE-CORRESPONDING TO et_data. + LOOP AT ASSIGNING . + APPEND INITIAL LINE TO et_data ASSIGNING . + MOVE-CORRESPONDING TO . + ENDLOOP. + ENDIF. + + " Apply conversion exit. + LOOP AT lt_field_conv ASSIGNING + WHERE convexit = 'ALPHA'. + LOOP AT et_data ASSIGNING . + ASSIGN COMPONENT -fieldname OF STRUCTURE TO . + CHECK: sy-subrc EQ 0 AND IS NOT INITIAL. + CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' + EXPORTING + input = + IMPORTING + output = . + ENDLOOP. + ENDLOOP. + + ENDMETHOD. + + METHOD create_data_conv_exit_length. DATA: lo_addit TYPE REF TO cl_abap_elemdescr, ls_dfies TYPE dfies, @@ -2085,11 +2374,8 @@ CLASS zcl_excel_worksheet IMPLEMENTATION. lv_column = zcl_excel_common=>convert_column2int( ip_cell_column ). LOOP AT me->mt_merged_cells TRANSPORTING NO FIELDS - WHERE - ( row_from <= ip_cell_row AND row_to >= ip_cell_row ) - AND - ( col_from <= lv_column AND col_to >= lv_column ). - + WHERE row_from <= ip_cell_row AND row_to >= ip_cell_row + AND col_from <= lv_column AND col_to >= lv_column. DELETE me->mt_merged_cells. EXIT. ENDLOOP.