diff --git a/src/EPPlus/FormulaParsing/DependencyChain/RpnFormulaExecution.cs b/src/EPPlus/FormulaParsing/DependencyChain/RpnFormulaExecution.cs index f91b4574b..871945822 100644 --- a/src/EPPlus/FormulaParsing/DependencyChain/RpnFormulaExecution.cs +++ b/src/EPPlus/FormulaParsing/DependencyChain/RpnFormulaExecution.cs @@ -1144,14 +1144,13 @@ private static void HandleCircularReference(RpnOptimizedDependencyChain depChain private static bool IsSingleAddress(RpnFormula f) { - var t = f._tokenIndex + 1; - while (t < f._tokens.Count && f._tokens[t].TokenTypeIsAddressToken) + var t = f._tokenIndex + 2; + if(t < f._tokens.Count && f._tokens[t-1].TokenTypeIsAddressToken) { if (f._tokens[t].TokenType == TokenType.Operator && f._tokens[t].Value == ":") { return false; } - t++; } return true; } diff --git a/src/EPPlusTest/Issues/FormulaCalculationIssues.cs b/src/EPPlusTest/Issues/FormulaCalculationIssues.cs index 979246d25..7ee481dbd 100644 --- a/src/EPPlusTest/Issues/FormulaCalculationIssues.cs +++ b/src/EPPlusTest/Issues/FormulaCalculationIssues.cs @@ -1771,6 +1771,42 @@ public void s1066() Assert.AreEqual("CH-0% output tax foreign/foreign", result); } } + [TestMethod] + public void i2490_CalcNameAsFirstOperandOfRangeComparison() + { + var fileName = "i2490_CalcTest.xlsx"; + using (var pck = OpenPackage(fileName, true)) + { + var ws = pck.Workbook.Worksheets.Add("CalcTest"); + ws.Cells["A1"].Value = 10D; + ws.Cells["A2"].Value = 20D; + ws.Cells["A3"].Value = 30D; + ws.Cells["B1"].Value = 1D; + ws.Cells["B2"].Value = 2D; + ws.Cells["B3"].Value = 3D; + + //LIMIT points to a formula cell that is calculated after F1. + ws.Cells["D5"].Formula = "1+1"; + var range = pck.Workbook.Names.Add("LIMIT", ws.Cells["D5"]); + + ExcelNamedRange.ValidateCellAddressInFormulas = true; + + //The name is the first operand, so in the RPN token list it is followed by the + //tokens of B1:B3. IsSingleAddress sees the ':' of the next operand and returns + //false, so D5 is never added to the dependency chain and LIMIT is read before + //D5 has been calculated. + ws.Cells["F1"].Formula = "MAX(FILTER(A1:A3,LIMIT>=B1:B3))"; + + var options = new ExcelCalculationOption() { FollowDependencyChain = true }; + + ws.Calculate(options); + + var outputFile = GetOutputFile("", "out_" + fileName); + pck.SaveAs(outputFile); + + Assert.AreEqual(20D, ws.Cells["F1"].Value); + } + } } }