Fix SHIFT_FORMULA (issues #727 and #728) (#830)

Fix SHIFT_FORMULA (issues #727 and #728)

Co-authored-by: Abo <andrea@borgia.bo.it>
This commit is contained in:
sandraros 2021-10-07 19:47:35 +02:00 committed by GitHub
parent 16430d17dd
commit f7151f3d39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 13 deletions

View File

@ -1061,7 +1061,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
lv_numchars TYPE i, " Number of characters counter
lv_tchar(1) TYPE c, " Temp character
lv_tchar2(1) TYPE c, " Temp character
lv_cur_form(2000) TYPE c, " Formula for current cell
lv_cur_form TYPE string, " Formula for current cell
lv_ref_cell_addr TYPE string, " Reference cell address
lv_tcol1 TYPE string, " Temp column letter
lv_tcol2 TYPE string, " Temp column letter
@ -1073,6 +1073,9 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
lv_substr1 TYPE string, " Substring variable
lv_abscol TYPE string, " Absolute column symbol
lv_absrow TYPE string, " Absolute row symbol
lv_ref_formula TYPE string,
lv_compare_1 TYPE string,
lv_compare_2 TYPE string,
lv_errormessage TYPE string.
@ -1087,17 +1090,18 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
* §4 Build resulting formula
*--------------------------------------------------------------------*
lv_ref_formula = iv_reference_formula.
*--------------------------------------------------------------------*
* No distance --> Reference = resulting cell/formula
*--------------------------------------------------------------------*
IF iv_shift_cols = 0
AND iv_shift_rows = 0.
ev_resulting_formula = iv_reference_formula.
ev_resulting_formula = lv_ref_formula.
RETURN. " done
ENDIF.
lv_flen = strlen( iv_reference_formula ).
lv_flen = strlen( lv_ref_formula ).
lv_numchars = 1.
*--------------------------------------------------------------------*
@ -1116,7 +1120,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
*--------------------------------------------------------------------*
* Here we have the current character in the formula
*--------------------------------------------------------------------*
lv_tchar = iv_reference_formula+lv_cnt(1).
lv_tchar = lv_ref_formula+lv_cnt(1).
*--------------------------------------------------------------------*
* Operators or opening parenthesis will separate possible cellreferences
@ -1124,7 +1128,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
IF ( lv_tchar CA lcv_operators
OR lv_tchar CA '(' )
AND lv_cnt2 = 1.
lv_substr1 = iv_reference_formula+lv_offset1(1).
lv_substr1 = lv_ref_formula+lv_offset1(1).
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
@ -1138,16 +1142,16 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
IF lv_tchar EQ '"'.
lv_cnt = lv_cnt + 1.
lv_numchars = lv_numchars + 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
lv_tchar = lv_ref_formula+lv_cnt(1).
WHILE lv_tchar NE '"'.
lv_cnt = lv_cnt + 1.
lv_numchars = lv_numchars + 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
lv_tchar = lv_ref_formula+lv_cnt(1).
ENDWHILE.
lv_cnt2 = lv_cnt + 1.
lv_substr1 = iv_reference_formula+lv_offset1(lv_numchars).
lv_substr1 = lv_ref_formula+lv_offset1(lv_numchars).
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
IF lv_cnt = lv_flen.
@ -1155,7 +1159,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
ENDIF.
lv_offset1 = lv_cnt.
lv_numchars = 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
lv_tchar = lv_ref_formula+lv_cnt(1).
lv_cnt2 = lv_cnt + 1.
CONTINUE. " --> next character in formula can be analyzed
ENDIF.
@ -1168,7 +1172,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
OR lv_tchar CA '():'
OR lv_cnt2 = lv_flen.
IF lv_cnt > 0.
lv_substr1 = iv_reference_formula+lv_offset1(lv_numchars).
lv_substr1 = lv_ref_formula+lv_offset1(lv_numchars).
*--------------------------------------------------------------------*
* Check for text concatenation and functions
*--------------------------------------------------------------------*
@ -1203,7 +1207,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
* Capture reference cell address
*--------------------------------------------------------------------*
TRY.
MOVE: iv_reference_formula+lv_offset1(lv_tlen) TO lv_ref_cell_addr. "Ref cell address
MOVE: lv_ref_formula+lv_offset1(lv_tlen) TO lv_ref_cell_addr. "Ref cell address
CATCH cx_root.
lv_errormessage = 'Internal error in Class ZCL_EXCEL_COMMON Method SHIFT_FORMULA Spot 1 '. " Change to messageclass if possible
zcx_excel=>raise_text( lv_errormessage ).
@ -1230,6 +1234,19 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
lv_tcnt = lv_tcnt + 1.
ENDDO.
ENDIF.
" Is valid column & row ?
IF lv_tcol1 IS NOT INITIAL AND lv_trow1 IS NOT INITIAL.
" COLUMN + ROW
CONCATENATE lv_tcol1 lv_trow1 INTO lv_compare_1.
" Original condensed string
lv_compare_2 = lv_ref_cell_addr.
CONDENSE lv_compare_2.
IF lv_compare_1 <> lv_compare_2.
CLEAR: lv_trow1, lv_tchar2.
ENDIF.
ENDIF.
*--------------------------------------------------------------------*
* Check for invalid cell address
*--------------------------------------------------------------------*
@ -1307,6 +1324,8 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
* Check whether there is a referencing problem
*--------------------------------------------------------------------*
lv_trow2 = lv_trow1 + iv_shift_rows.
" Remove the space used for the sign
CONDENSE lv_trow2.
IF ( lv_tcoln < 1 AND lv_abscol <> '$' ) " Maybe we should add here max-column and max row-tests as well.
OR ( lv_trow2 < 1 AND lv_absrow <> '$' ). " Check how EXCEL behaves in this case
*--------------------------------------------------------------------*
@ -1355,7 +1374,7 @@ CLASS ZCL_EXCEL_COMMON IMPLEMENTATION.
lv_numchars = 0.
IF lv_tchar CA lcv_operators
OR lv_tchar CA ':)'.
CONCATENATE lv_cur_form lv_tchar INTO lv_cur_form.
CONCATENATE lv_cur_form lv_tchar INTO lv_cur_form RESPECTING BLANKS.
ENDIF.
lv_offset1 = lv_cnt2.
ENDIF.

View File

@ -1137,7 +1137,7 @@ CLASS lcl_excel_common_test IMPLEMENTATION.
iv_reference_formula = `X(B13, "KK" ) `
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = `X(C14,"KK")` ).
iv_expected = `X(C14, "KK" ) ` ).
" same as above - but with string input instead of Char-input
macro_shift_formula(
@ -1188,6 +1188,62 @@ CLASS lcl_excel_common_test IMPLEMENTATION.
iv_shift_rows = -1
iv_expected = '#REF!+#REF!+#REF!+$A$1+A1' ).
" Sheet name not ending with digit
macro_shift_formula(
iv_reference_formula = 'Sheet!A1'
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = 'Sheet!B2' ).
" Sheet name ending with digit
macro_shift_formula(
iv_reference_formula = 'Sheet2!A1'
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = 'Sheet2!B2' ).
" Sheet name with special characters
macro_shift_formula(
iv_reference_formula = |'Sheet name'!A1|
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = |'Sheet name'!B2| ).
" Respecting blanks
macro_shift_formula(
iv_reference_formula = 'SUBTOTAL(109,Table1[SUM 1])'
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = 'SUBTOTAL(109,Table1[SUM 1])' ).
" Respecting blanks
macro_shift_formula(
iv_reference_formula = 'B4 & C4'
iv_shift_cols = 0
iv_shift_rows = 1
iv_expected = 'B5 & C5' ).
" F_1 is a range name, not a cell address
macro_shift_formula(
iv_reference_formula = 'SUM(F_1,F_2)'
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = 'SUM(F_1,F_2)' ).
" RC are not columns
macro_shift_formula(
iv_reference_formula = 'INDIRECT("RC[4]",FALSE)'
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = 'INDIRECT("RC[4]",FALSE)' ).
" A1 is a sheet name
macro_shift_formula(
iv_reference_formula = |'A1'!$A$1|
iv_shift_cols = 1
iv_shift_rows = 1
iv_expected = |'A1'!$A$1| ).
ENDMETHOD.
METHOD is_cell_in_range.