From ec3f73c0e279a09bde3793e4b8b7ac1a29ec7903 Mon Sep 17 00:00:00 2001 From: sandraros <34005250+sandraros@users.noreply.github.com> Date: Sat, 16 Oct 2021 13:22:38 +0200 Subject: [PATCH] Fix #836 new feature "Ignored Errors" (#839) * Fix SHIFT_FORMULA (issues #727 and #728) (#830) (#838) Fix SHIFT_FORMULA (issues #727 and #728) Co-authored-by: Abo Co-authored-by: Abo * Fix #836 new feature "Ignored Errors" Fix #836 * Lint xsdbool -> boolc * lint expression as argument -> variable as argumen * lint remove constructor expression * Update src/zcl_excel_writer_2007.clas.abap Co-authored-by: abaplint[bot] <24845621+abaplint[bot]@users.noreply.github.com> * Update src/zcl_excel_writer_2007.clas.abap Co-authored-by: abaplint[bot] <24845621+abaplint[bot]@users.noreply.github.com> * fix previous merge mistake Co-authored-by: Abo Co-authored-by: sandraros Co-authored-by: Lars Hvam --- src/demos/zdemo_excel3.prog.abap | 8 +++ src/zcl_excel_reader_2007.clas.abap | 69 ++++++++++++++++++++++++++ src/zcl_excel_worksheet.clas.abap | 42 ++++++++++++++++ src/zcl_excel_writer_2007.clas.abap | 76 +++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) diff --git a/src/demos/zdemo_excel3.prog.abap b/src/demos/zdemo_excel3.prog.abap index 7620b54..29ba65c 100644 --- a/src/demos/zdemo_excel3.prog.abap +++ b/src/demos/zdemo_excel3.prog.abap @@ -20,6 +20,8 @@ DATA: ls_table_settings TYPE zexcel_s_table_settings. DATA: lv_title TYPE zexcel_sheet_title, lt_carr TYPE TABLE OF scarr, row TYPE zexcel_cell_row VALUE 2, + ls_error TYPE zcl_excel_worksheet=>mty_s_ignored_errors, + lt_error TYPE zcl_excel_worksheet=>mty_th_ignored_errors, lo_range TYPE REF TO zcl_excel_range. DATA: lo_data_validation TYPE REF TO zcl_excel_data_validation. FIELD-SYMBOLS: LIKE LINE OF lt_carr. @@ -54,6 +56,12 @@ START-OF-SELECTION. is_table_settings = ls_table_settings ). lo_worksheet->freeze_panes( ip_num_rows = 3 ). "freeze column headers when scrolling + IF lines( lt_test ) >= 1. + ls_error-cell_coords = |B2:B{ lines( lt_test ) + 1 }|. + ls_error-number_stored_as_text = abap_true. + INSERT ls_error INTO TABLE lt_error. + lo_worksheet->set_ignored_errors( lt_error ). + ENDIF. lo_column = lo_worksheet->get_column( ip_column = 'E' ). "make date field a bit wider lo_column->set_width( ip_width = 11 ). diff --git a/src/zcl_excel_reader_2007.clas.abap b/src/zcl_excel_reader_2007.clas.abap index a622db8..39e0641 100644 --- a/src/zcl_excel_reader_2007.clas.abap +++ b/src/zcl_excel_reader_2007.clas.abap @@ -232,6 +232,12 @@ CLASS zcl_excel_reader_2007 DEFINITION !it_external_hyperlinks TYPE gtt_external_hyperlinks RAISING zcx_excel . + METHODS load_worksheet_ignored_errors + IMPORTING + !io_ixml_worksheet TYPE REF TO if_ixml_document + !io_worksheet TYPE REF TO zcl_excel_worksheet + RAISING + zcx_excel . METHODS load_worksheet_pagebreaks IMPORTING !io_ixml_worksheet TYPE REF TO if_ixml_document @@ -2901,6 +2907,12 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION. CATCH zcx_excel. " Ignore autofilter reading errors - pass everything we were able to identify ENDTRY. + TRY. + me->load_worksheet_ignored_errors( io_ixml_worksheet = lo_ixml_worksheet + io_worksheet = io_worksheet ). + CATCH zcx_excel. " Ignore "ignoredErrors" reading errors - pass everything we were able to identify + ENDTRY. + ENDMETHOD. @@ -3512,6 +3524,63 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION. ENDMETHOD. + METHOD load_worksheet_ignored_errors. + + DATA: lo_ixml_ignored_errors TYPE REF TO if_ixml_node_collection, + lo_ixml_ignored_error TYPE REF TO if_ixml_element, + lo_ixml_iterator TYPE REF TO if_ixml_node_iterator, + ls_ignored_error TYPE zcl_excel_worksheet=>mty_s_ignored_errors, + lt_ignored_errors TYPE zcl_excel_worksheet=>mty_th_ignored_errors. + + DATA: BEGIN OF ls_raw_ignored_error, + sqref TYPE string, + evalerror TYPE string, + twodigittextyear TYPE string, + numberstoredastext TYPE string, + formula TYPE string, + formularange TYPE string, + unlockedformula TYPE string, + emptycellreference TYPE string, + listdatavalidation TYPE string, + calculatedcolumn TYPE string, + END OF ls_raw_ignored_error. + + CLEAR lt_ignored_errors. + + lo_ixml_ignored_errors = io_ixml_worksheet->get_elements_by_tag_name( name = 'ignoredError' ). + lo_ixml_iterator = lo_ixml_ignored_errors->create_iterator( ). + lo_ixml_ignored_error ?= lo_ixml_iterator->get_next( ). + + WHILE lo_ixml_ignored_error IS BOUND. + + fill_struct_from_attributes( EXPORTING + ip_element = lo_ixml_ignored_error + CHANGING + cp_structure = ls_raw_ignored_error ). + + CLEAR ls_ignored_error. + ls_ignored_error-cell_coords = ls_raw_ignored_error-sqref. + ls_ignored_error-eval_error = boolc( ls_raw_ignored_error-evalerror = '1' ). + ls_ignored_error-two_digit_text_year = boolc( ls_raw_ignored_error-twodigittextyear = '1' ). + ls_ignored_error-number_stored_as_text = boolc( ls_raw_ignored_error-numberstoredastext = '1' ). + ls_ignored_error-formula = boolc( ls_raw_ignored_error-formula = '1' ). + ls_ignored_error-formula_range = boolc( ls_raw_ignored_error-formularange = '1' ). + ls_ignored_error-unlocked_formula = boolc( ls_raw_ignored_error-unlockedformula = '1' ). + ls_ignored_error-empty_cell_reference = boolc( ls_raw_ignored_error-emptycellreference = '1' ). + ls_ignored_error-list_data_validation = boolc( ls_raw_ignored_error-listdatavalidation = '1' ). + ls_ignored_error-calculated_column = boolc( ls_raw_ignored_error-calculatedcolumn = '1' ). + + INSERT ls_ignored_error INTO TABLE lt_ignored_errors. + + lo_ixml_ignored_error ?= lo_ixml_iterator->get_next( ). + + ENDWHILE. + + io_worksheet->set_ignored_errors( lt_ignored_errors ). + + ENDMETHOD. + + METHOD load_worksheet_pagebreaks. DATA: lo_node TYPE REF TO if_ixml_element, diff --git a/src/zcl_excel_worksheet.clas.abap b/src/zcl_excel_worksheet.clas.abap index f96888a..959744b 100644 --- a/src/zcl_excel_worksheet.clas.abap +++ b/src/zcl_excel_worksheet.clas.abap @@ -32,6 +32,31 @@ CLASS zcl_excel_worksheet DEFINITION TYPES: mty_ts_outlines_row TYPE SORTED TABLE OF mty_s_outline_row WITH UNIQUE KEY row_from row_to . TYPES: + BEGIN OF mty_s_ignored_errors, + "! Cell reference (e.g. "A1") or list like "A1 A2" or range "A1:G1" + cell_coords TYPE zexcel_cell_coords, + "! Ignore errors when cells contain formulas that result in an error. + eval_error TYPE abap_bool, + "! Ignore errors when formulas contain text formatted cells with years represented as 2 digits. + two_digit_text_year TYPE abap_bool, + "! Ignore errors when numbers are formatted as text or are preceded by an apostrophe. + number_stored_as_text TYPE abap_bool, + "! Ignore errors when a formula in a region of your WorkSheet differs from other formulas in the same region. + formula TYPE abap_bool, + "! Ignore errors when formulas omit certain cells in a region. + formula_range TYPE abap_bool, + "! Ignore errors when unlocked cells contain formulas. + unlocked_formula TYPE abap_bool, + "! Ignore errors when formulas refer to empty cells. + empty_cell_reference TYPE abap_bool, + "! Ignore errors when a cell's value in a Table does not comply with the Data Validation rules specified. + list_data_validation TYPE abap_bool, + "! Ignore errors when cells contain a value different from a calculated column formula. + "! In other words, for a calculated column, a cell in that column is considered to have an error + "! if its formula is different from the calculated column formula, or doesn't contain a formula at all. + calculated_column TYPE abap_bool, + END OF mty_s_ignored_errors, + mty_th_ignored_errors TYPE HASHED TABLE OF mty_s_ignored_errors WITH UNIQUE KEY cell_coords, BEGIN OF mty_s_column_formula, id TYPE i, column TYPE zexcel_cell_column, @@ -370,6 +395,9 @@ CLASS zcl_excel_worksheet DEFINITION METHODS get_hyperlinks_size RETURNING VALUE(ep_size) TYPE i . + METHODS get_ignored_errors + RETURNING + VALUE(rt_ignored_errors) TYPE mty_th_ignored_errors. METHODS get_merge RETURNING VALUE(merge_range) TYPE string_table @@ -463,6 +491,9 @@ CLASS zcl_excel_worksheet DEFINITION !ip_default_excel_date_format TYPE zexcel_number_format RAISING zcx_excel . + METHODS set_ignored_errors + IMPORTING + it_ignored_errors TYPE mty_th_ignored_errors. METHODS set_merge IMPORTING !ip_column_start TYPE simple DEFAULT zcl_excel_common=>c_excel_sheet_min_col @@ -646,6 +677,7 @@ CLASS zcl_excel_worksheet DEFINITION DATA tables TYPE REF TO cl_object_collection . DATA title TYPE zexcel_sheet_title VALUE 'Worksheet'. "#EC NOTEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . " . DATA upper_cell TYPE zexcel_s_cell_data . + DATA mt_ignored_errors TYPE mty_th_ignored_errors. METHODS calculate_cell_width IMPORTING @@ -2311,6 +2343,11 @@ CLASS zcl_excel_worksheet IMPLEMENTATION. ENDMETHOD. "GET_HYPERLINKS_SIZE + METHOD get_ignored_errors. + rt_ignored_errors = mt_ignored_errors. + ENDMETHOD. + + METHOD get_merge. FIELD-SYMBOLS: LIKE LINE OF me->mt_merged_cells. @@ -3319,6 +3356,11 @@ CLASS zcl_excel_worksheet IMPLEMENTATION. ENDMETHOD. "SET_DEFAULT_EXCEL_DATE_FORMAT + METHOD set_ignored_errors. + mt_ignored_errors = it_ignored_errors. + ENDMETHOD. + + METHOD set_merge. DATA: ls_merge TYPE mty_merge, diff --git a/src/zcl_excel_writer_2007.clas.abap b/src/zcl_excel_writer_2007.clas.abap index 023d332..70ef5c0 100644 --- a/src/zcl_excel_writer_2007.clas.abap +++ b/src/zcl_excel_writer_2007.clas.abap @@ -123,6 +123,11 @@ CLASS zcl_excel_writer_2007 DEFINITION VALUE(ep_content) TYPE xstring RAISING zcx_excel . + METHODS create_xl_sheet_ignored_errors + IMPORTING + io_worksheet TYPE REF TO zcl_excel_worksheet + io_document TYPE REF TO if_ixml_document + io_element_root TYPE REF TO if_ixml_element. METHODS create_xl_sheet_pagebreaks IMPORTING !io_document TYPE REF TO if_ixml_document @@ -5373,6 +5378,10 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION. ENDIF. * +* ignoredErrors + create_xl_sheet_ignored_errors( io_worksheet = io_worksheet io_document = lo_document io_element_root = lo_element_root ). + + * tables DATA lv_table_count TYPE i. @@ -5412,6 +5421,73 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION. ENDMETHOD. + METHOD create_xl_sheet_ignored_errors. + DATA: lo_element TYPE REF TO if_ixml_element, + lo_element2 TYPE REF TO if_ixml_element, + lt_ignored_errors TYPE zcl_excel_worksheet=>mty_th_ignored_errors. + FIELD-SYMBOLS: TYPE zcl_excel_worksheet=>mty_s_ignored_errors. + + lt_ignored_errors = io_worksheet->get_ignored_errors( ). + + IF lt_ignored_errors IS NOT INITIAL. + lo_element = io_document->create_simple_element( name = 'ignoredErrors' + parent = io_document ). + + + LOOP AT lt_ignored_errors ASSIGNING . + + lo_element2 = io_document->create_simple_element( name = 'ignoredError' + parent = io_document ). + + lo_element2->set_attribute_ns( name = 'sqref' + value = -cell_coords ). + + IF -eval_error = abap_true. + lo_element2->set_attribute_ns( name = 'evalError' + value = '1' ). + ENDIF. + IF -two_digit_text_year = abap_true. + lo_element2->set_attribute_ns( name = 'twoDigitTextYear' + value = '1' ). + ENDIF. + IF -number_stored_as_text = abap_true. + lo_element2->set_attribute_ns( name = 'numberStoredAsText' + value = '1' ). + ENDIF. + IF -formula = abap_true. + lo_element2->set_attribute_ns( name = 'formula' + value = '1' ). + ENDIF. + IF -formula_range = abap_true. + lo_element2->set_attribute_ns( name = 'formulaRange' + value = '1' ). + ENDIF. + IF -unlocked_formula = abap_true. + lo_element2->set_attribute_ns( name = 'unlockedFormula' + value = '1' ). + ENDIF. + IF -empty_cell_reference = abap_true. + lo_element2->set_attribute_ns( name = 'emptyCellReference' + value = '1' ). + ENDIF. + IF -list_data_validation = abap_true. + lo_element2->set_attribute_ns( name = 'listDataValidation' + value = '1' ). + ENDIF. + IF -calculated_column = abap_true. + lo_element2->set_attribute_ns( name = 'calculatedColumn' + value = '1' ). + ENDIF. + + lo_element->append_child( lo_element2 ). + + ENDLOOP. + + io_element_root->append_child( lo_element ). + + ENDIF. + + ENDMETHOD. METHOD create_xl_sheet_column_formula. TYPES: ls_column_formula_used TYPE mty_column_formula_used,