diff --git a/ClosedXML/Excel/CalcEngine/Functions/Tally.cs b/ClosedXML/Excel/CalcEngine/Functions/Tally.cs index 5cf212e..8796b84 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/Tally.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/Tally.cs @@ -13,7 +13,6 @@ private double[] _numericValues; - public Tally() : this(false) { } @@ -84,7 +83,7 @@ return _list.Count(o => !Statistical.IsBlank(o)); } - IEnumerable NumericValuesEnumerable() + private IEnumerable NumericValuesEnumerable() { foreach (var value in _list) { @@ -92,14 +91,14 @@ var vEnumerable = value as IEnumerable; if (vEnumerable == null) { - if (double.TryParse(value.ToString(), out tmp)) + if (TryParseToDouble(value, out tmp)) yield return tmp; } else { foreach (var v in vEnumerable) { - if (double.TryParse(v.ToString(), out tmp)) + if (TryParseToDouble(v, out tmp)) yield return tmp; break; } @@ -107,7 +106,25 @@ } } - double[] NumericValuesInternal() + private bool TryParseToDouble(object value, out double d) + { + if (value.IsNumber()) + { + d = Convert.ToDouble(value); + return true; + } + else if (value is DateTime) + { + d = Convert.ToDouble(((DateTime)value).ToOADate()); + return true; + } + else + { + return double.TryParse(value.ToString(), out d); + } + } + + private double[] NumericValuesInternal() => LazyInitializer.EnsureInitialized(ref _numericValues, () => NumericValuesEnumerable().ToArray()); public IEnumerable NumericValues() @@ -144,7 +161,7 @@ public double Range() => Max() - Min(); - static double Sum2(IEnumerable nums) + private static double Sum2(IEnumerable nums) { return nums.Sum(d => d * d); } diff --git a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs index 3ad7f8e..a4435ef 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs @@ -379,7 +379,7 @@ actual = XLWorkbook.EvaluateExpr("Round(-50.55, -2)"); Assert.AreEqual(-100.0, actual); - + actual = XLWorkbook.EvaluateExpr("ROUND(59 * 0.535, 2)"); // (59 * 0.535) = 31.565 Assert.AreEqual(31.57, actual); @@ -574,6 +574,22 @@ } [Test] + public void SumDateTimeAndNumber() + { + using (var wb = new XLWorkbook()) + { + var ws = wb.AddWorksheet("Sheet1"); + ws.Cell("A1").Value = 1; + ws.Cell("A2").Value = new DateTime(2018, 1, 1); + Assert.AreEqual(43102, ws.Evaluate("SUM(A1:A2)")); + + ws.Cell("A1").Value = 2; + ws.Cell("A2").FormulaA1 = "DATE(2018,1,1)"; + Assert.AreEqual(43103, ws.Evaluate("SUM(A1:A2)")); + } + } + + [Test] public void SumSq() { Object actual;