From 5bf35f8c1c18eafb2e423ae3b77868bcccc505ff Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 9 Dec 2021 02:40:11 +0100 Subject: [PATCH] This closes #1088 (#1089) Support check string equality with the string value of a defined name --- calc.go | 8 ++++++-- calc_test.go | 33 ++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/calc.go b/calc.go index da32f97..e9ac0c8 100644 --- a/calc.go +++ b/calc.go @@ -736,6 +736,10 @@ func (f *File) evalInfixExp(sheet, cell string, tokens []efp.Token) (efp.Token, // current token is args or range, skip next token, order required: parse reference first if token.TSubType == efp.TokenSubTypeRange { if !opftStack.Empty() { + refTo := f.getDefinedNameRefTo(token.TValue, sheet) + if refTo != "" { + token.TValue = refTo + } // parse reference: must reference at here result, err := f.parseReference(sheet, token.TValue) if err != nil { @@ -871,13 +875,13 @@ func calcPow(rOpd, lOpd efp.Token, opdStack *Stack) error { // calcEq evaluate equal arithmetic operations. func calcEq(rOpd, lOpd efp.Token, opdStack *Stack) error { - opdStack.Push(efp.Token{TValue: strings.ToUpper(strconv.FormatBool(rOpd == lOpd)), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}) + opdStack.Push(efp.Token{TValue: strings.ToUpper(strconv.FormatBool(rOpd.TValue == lOpd.TValue)), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}) return nil } // calcNEq evaluate not equal arithmetic operations. func calcNEq(rOpd, lOpd efp.Token, opdStack *Stack) error { - opdStack.Push(efp.Token{TValue: strings.ToUpper(strconv.FormatBool(rOpd != lOpd)), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}) + opdStack.Push(efp.Token{TValue: strings.ToUpper(strconv.FormatBool(rOpd.TValue != lOpd.TValue)), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}) return nil } diff --git a/calc_test.go b/calc_test.go index b1d4f26..1de8fb8 100644 --- a/calc_test.go +++ b/calc_test.go @@ -3323,22 +3323,41 @@ func TestCalculate(t *testing.T) { func TestCalcWithDefinedName(t *testing.T) { cellData := [][]interface{}{ - {"A1 value", "B1 value", nil}, + {"A1_as_string", "B1_as_string", 123, nil}, } f := prepareCalcData(cellData) assert.NoError(t, f.SetDefinedName(&DefinedName{Name: "defined_name1", RefersTo: "Sheet1!A1", Scope: "Workbook"})) assert.NoError(t, f.SetDefinedName(&DefinedName{Name: "defined_name1", RefersTo: "Sheet1!B1", Scope: "Sheet1"})) + assert.NoError(t, f.SetDefinedName(&DefinedName{Name: "defined_name2", RefersTo: "Sheet1!C1", Scope: "Workbook"})) - assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "=defined_name1")) - result, err := f.CalcCellValue("Sheet1", "C1") + assert.NoError(t, f.SetCellFormula("Sheet1", "D1", "=defined_name1")) + result, err := f.CalcCellValue("Sheet1", "D1") assert.NoError(t, err) // DefinedName with scope WorkSheet takes precedence over DefinedName with scope Workbook, so we should get B1 value - assert.Equal(t, "B1 value", result, "=defined_name1") + assert.Equal(t, "B1_as_string", result, "=defined_name1") - assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "=CONCATENATE(\"<\",defined_name1,\">\")")) - result, err = f.CalcCellValue("Sheet1", "C1") + assert.NoError(t, f.SetCellFormula("Sheet1", "D1", `=CONCATENATE("<",defined_name1,">")`)) + result, err = f.CalcCellValue("Sheet1", "D1") assert.NoError(t, err) - assert.Equal(t, "", result, "=defined_name1") + assert.Equal(t, "", result, "=defined_name1") + + // comparing numeric values + assert.NoError(t, f.SetCellFormula("Sheet1", "D1", `=123=defined_name2`)) + result, err = f.CalcCellValue("Sheet1", "D1") + assert.NoError(t, err) + assert.Equal(t, "TRUE", result, "=123=defined_name2") + + // comparing text values + assert.NoError(t, f.SetCellFormula("Sheet1", "D1", `="B1_as_string"=defined_name1`)) + result, err = f.CalcCellValue("Sheet1", "D1") + assert.NoError(t, err) + assert.Equal(t, "TRUE", result, `="B1_as_string"=defined_name1`) + + // comparing text values + assert.NoError(t, f.SetCellFormula("Sheet1", "D1", `=IF("B1_as_string"=defined_name1,"YES","NO")`)) + result, err = f.CalcCellValue("Sheet1", "D1") + assert.NoError(t, err) + assert.Equal(t, "YES", result, `=IF("B1_as_string"=defined_name1,"YES","NO")`) }