From ad8541790df7d423803aca9851132639179ad8f2 Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 8 Sep 2024 12:19:58 +0800 Subject: [PATCH] This closes #1989, fix incorrect result of formula functions XIRR and XNPV - Require number data type instead of string - Fix incorrect formula error type --- calc.go | 26 ++++++++++++-------------- calc_test.go | 40 ++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/calc.go b/calc.go index 193e01f..e867d2f 100644 --- a/calc.go +++ b/calc.go @@ -18197,28 +18197,26 @@ func (fn *formulaFuncs) prepareXArgs(values, dates formulaArg) (valuesArg, dates valuesArg = append(valuesArg, numArg.Number) continue } - err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) + err = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) return } if len(valuesArg) < 2 { err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) return } - args, date := list.New(), 0.0 + date := 0.0 for _, arg := range dates.ToList() { - args.Init() - args.PushBack(arg) - dateValue := fn.DATEVALUE(args) - if dateValue.Type != ArgNumber { - err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) - return + if arg.Type == ArgNumber { + datesArg = append(datesArg, arg.Number) + if arg.Number < date { + err = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + return + } + date = arg.Number + continue } - if dateValue.Number < date { - err = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) - return - } - datesArg = append(datesArg, dateValue.Number) - date = dateValue.Number + err = newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + return } if len(valuesArg) != len(datesArg) { err = newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) diff --git a/calc_test.go b/calc_test.go index a842a23..868533c 100644 --- a/calc_test.go +++ b/calc_test.go @@ -5562,13 +5562,13 @@ func TestCalcSUMIFSAndAVERAGEIFS(t *testing.T) { func TestCalcXIRR(t *testing.T) { cellData := [][]interface{}{ - {-100.00, "01/01/2016"}, - {20.00, "04/01/2016"}, - {40.00, "10/01/2016"}, - {25.00, "02/01/2017"}, - {8.00, "03/01/2017"}, - {15.00, "06/01/2017"}, - {-1e-10, "09/01/2017"}, + {-100.00, 42370}, + {20.00, 42461}, + {40.00, 42644}, + {25.00, 42767}, + {8.00, 42795}, + {15.00, 42887}, + {-1e-10, 42979}, } f := prepareCalcData(cellData) formulaList := map[string]string{ @@ -5584,8 +5584,8 @@ func TestCalcXIRR(t *testing.T) { calcError := map[string][]string{ "=XIRR()": {"#VALUE!", "XIRR requires 2 or 3 arguments"}, "=XIRR(A1:A4,B1:B4,-1)": {"#VALUE!", "XIRR requires guess > -1"}, - "=XIRR(\"\",B1:B4)": {"#NUM!", "#NUM!"}, - "=XIRR(A1:A4,\"\")": {"#NUM!", "#NUM!"}, + "=XIRR(\"\",B1:B4)": {"#VALUE!", "#VALUE!"}, + "=XIRR(A1:A4,\"\")": {"#VALUE!", "#VALUE!"}, "=XIRR(A1:A4,B1:B4,\"\")": {"#NUM!", "#NUM!"}, "=XIRR(A2:A6,B2:B6)": {"#NUM!", "#NUM!"}, "=XIRR(A2:A7,B2:B7)": {"#NUM!", "#NUM!"}, @@ -5708,15 +5708,15 @@ func TestCalcXLOOKUP(t *testing.T) { func TestCalcXNPV(t *testing.T) { cellData := [][]interface{}{ {nil, 0.05}, - {"01/01/2016", -10000, nil}, - {"02/01/2016", 2000}, - {"05/01/2016", 2400}, - {"07/01/2016", 2900}, - {"11/01/2016", 3500}, - {"01/01/2017", 4100}, + {42370, -10000, nil}, + {42401, 2000}, + {42491, 2400}, + {42552, 2900}, + {42675, 3500}, + {42736, 4100}, {}, - {"02/01/2016"}, - {"01/01/2016"}, + {42401}, + {42370}, } f := prepareCalcData(cellData) formulaList := map[string]string{ @@ -5732,9 +5732,9 @@ func TestCalcXNPV(t *testing.T) { "=XNPV()": {"#VALUE!", "XNPV requires 3 arguments"}, "=XNPV(\"\",B2:B7,A2:A7)": {"#VALUE!", "strconv.ParseFloat: parsing \"\": invalid syntax"}, "=XNPV(0,B2:B7,A2:A7)": {"#VALUE!", "XNPV requires rate > 0"}, - "=XNPV(B1,\"\",A2:A7)": {"#NUM!", "#NUM!"}, - "=XNPV(B1,B2:B7,\"\")": {"#NUM!", "#NUM!"}, - "=XNPV(B1,B2:B7,C2:C7)": {"#NUM!", "#NUM!"}, + "=XNPV(B1,\"\",A2:A7)": {"#VALUE!", "#VALUE!"}, + "=XNPV(B1,B2:B7,\"\")": {"#VALUE!", "#VALUE!"}, + "=XNPV(B1,B2:B7,C2:C7)": {"#VALUE!", "#VALUE!"}, "=XNPV(B1,B2,A2)": {"#NUM!", "#NUM!"}, "=XNPV(B1,B2:B3,A2:A5)": {"#NUM!", "#NUM!"}, "=XNPV(B1,B2:B3,A9:A10)": {"#VALUE!", "#VALUE!"},