diff --git a/ClosedXML/Excel/CalcEngine/Expression.cs b/ClosedXML/Excel/CalcEngine/Expression.cs index ff1288c..a65b7ad 100644 --- a/ClosedXML/Excel/CalcEngine/Expression.cs +++ b/ClosedXML/Excel/CalcEngine/Expression.cs @@ -486,6 +486,9 @@ public IEnumerator GetEnumerator() { + if (_value is string) + return new [] {(string) _value}.GetEnumerator(); + return (_value as IEnumerable).GetEnumerator(); } diff --git a/ClosedXML/Excel/CalcEngine/Functions/Statistical.cs b/ClosedXML/Excel/CalcEngine/Functions/Statistical.cs index 58baace..958221e 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/Statistical.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/Statistical.cs @@ -1,5 +1,5 @@ +using ClosedXML.Excel.CalcEngine.Exceptions; using System; -using System.Net; using System.Collections; using System.Collections.Generic; @@ -96,44 +96,39 @@ //ZTEST Returns the one-tailed probability-value of a z-test } - - - static object Average(List p) + private static object Average(List p) { return GetTally(p, true).Average(); } - static object AverageA(List p) + + private static object AverageA(List p) { return GetTally(p, false).Average(); } - static object Count(List p) + + private static object Count(List p) { return GetTally(p, true).Count(); } - static object CountA(List p) + + private static object CountA(List p) { return GetTally(p, false).Count(); } - static object CountBlank(List p) + + private static object CountBlank(List p) { + if ((p[0] as XObjectExpression)?.Value as CellRangeReference == null) + throw new NoValueAvailableException("COUNTBLANK should have a single argument which is a range reference"); + var cnt = 0.0; - foreach (Expression e in p) + var e = p[0] as XObjectExpression; + foreach (var value in e) { - var ienum = e as IEnumerable; - if (ienum != null) - { - foreach (var value in ienum) - { - if (IsBlank(value)) - cnt++; - } - } - else - { - if (IsBlank(e.Evaluate())) - cnt++; - } + if (IsBlank(value)) + cnt++; } + return cnt; } @@ -144,7 +139,7 @@ value is string && ((string)value).Length == 0; } - static object CountIf(List p) + private static object CountIf(List p) { CalcEngine ce = new CalcEngine(); var cnt = 0.0; @@ -210,59 +205,68 @@ return count; } - static object Max(List p) + private static object Max(List p) { return GetTally(p, true).Max(); } - static object MaxA(List p) + private static object MaxA(List p) { return GetTally(p, false).Max(); } - static object Min(List p) + private static object Min(List p) { return GetTally(p, true).Min(); } - static object MinA(List p) + + private static object MinA(List p) { return GetTally(p, false).Min(); } - static object StDev(List p) + + private static object StDev(List p) { return GetTally(p, true).Std(); } - static object StDevA(List p) + + private static object StDevA(List p) { return GetTally(p, false).Std(); } - static object StDevP(List p) + + private static object StDevP(List p) { return GetTally(p, true).StdP(); } - static object StDevPA(List p) + + private static object StDevPA(List p) { return GetTally(p, false).StdP(); } - static object Var(List p) + + private static object Var(List p) { return GetTally(p, true).Var(); } - static object VarA(List p) + + private static object VarA(List p) { return GetTally(p, false).Var(); } - static object VarP(List p) + + private static object VarP(List p) { return GetTally(p, true).VarP(); } - static object VarPA(List p) + + private static object VarPA(List p) { return GetTally(p, false).VarP(); } // utility for tallying statistics - static Tally GetTally(List p, bool numbersOnly) + private static Tally GetTally(List p, bool numbersOnly) { return new Tally(p, numbersOnly); } diff --git a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs index a0bb2a2..7a432e1 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/StatisticalTests.cs @@ -2,6 +2,8 @@ using NUnit.Framework; using System; using System.Linq; +using ClosedXML.Excel.CalcEngine; +using ClosedXML.Excel.CalcEngine.Exceptions; namespace ClosedXML_Tests.Excel.CalcEngine { @@ -72,8 +74,15 @@ value = ws.Evaluate(@"=COUNTBLANK(D43:D49)").CastTo(); Assert.AreEqual(4, value); - value = workbook.Evaluate(@"=COUNTBLANK(E3:E45)").CastTo(); + value = ws.Evaluate(@"=COUNTBLANK(E3:E45)").CastTo(); Assert.AreEqual(0, value); + + value = ws.Evaluate(@"=COUNTBLANK(A1)").CastTo(); + Assert.AreEqual(1, value); + + Assert.Throws(() => workbook.Evaluate(@"=COUNTBLANK(E3:E45)")); + Assert.Throws(() => ws.Evaluate(@"=COUNTBLANK()")); + Assert.Throws(() => ws.Evaluate(@"=COUNTBLANK(A3:A45,E3:E45)")); } [Test]