Initial commit of the ClosedXML library
Establishes the foundational structure, core Excel functionality, and tooling. - Implements base components for cells, ranges, columns, and rows. - Integrates a custom calculation engine with a wide range of Excel functions. - Adds comprehensive support for styling, conditional formatting, data validation, comments, pictures, and charts. - Configures build setup, project metadata (NuGet), and developer guidelines. - Includes editor and Git attributes for consistent code style and line endings.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
public class CalcEngineCellEnumerationTests
|
||||
{
|
||||
[Test]
|
||||
public void CanEnumerateCellsOverEmptySheet()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet1 = wb.AddWorksheet("Sheet1");
|
||||
var sheet2 = wb.AddWorksheet("Sheet2");
|
||||
|
||||
var cell = sheet1.FirstCell();
|
||||
cell.FormulaA1 = "=SUMIFS(Sheet2!B:B, Sheet2!C:C, 1)";
|
||||
|
||||
Assert.AreEqual(0, cell.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using ClosedXML.Excel;
|
||||
using ClosedXML.Excel.CalcEngine.Exceptions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class CalcEngineExceptionTests
|
||||
{
|
||||
[OneTimeSetUp]
|
||||
public void SetCultureInfo()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidCharNumber()
|
||||
{
|
||||
Assert.Throws<CellValueException>(() => XLWorkbook.EvaluateExpr("CHAR(-2)"));
|
||||
Assert.Throws<CellValueException>(() => XLWorkbook.EvaluateExpr("CHAR(270)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DivisionByZero()
|
||||
{
|
||||
Assert.Throws<DivisionByZeroException>(() => XLWorkbook.EvaluateExpr("0/0"));
|
||||
Assert.Throws<DivisionByZeroException>(() => new XLWorkbook().AddWorksheet().Evaluate("0/0"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidFunction()
|
||||
{
|
||||
Exception ex;
|
||||
ex = Assert.Throws<NameNotRecognizedException>(() => XLWorkbook.EvaluateExpr("XXX(A1:A2)"));
|
||||
Assert.That(ex.Message, Is.EqualTo("The identifier `XXX` was not recognised."));
|
||||
|
||||
var ws = new XLWorkbook().AddWorksheet();
|
||||
ex = Assert.Throws<NameNotRecognizedException>(() => ws.Evaluate("XXX(A1:A2)"));
|
||||
Assert.That(ex.Message, Is.EqualTo("The identifier `XXX` was not recognised."));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedNameNotRecognizedException()
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet();
|
||||
ws.Cell("A1").SetFormulaA1("=XXX");
|
||||
ws.Cell("A2").SetFormulaA1(@"=IFERROR(A1, ""Success"")");
|
||||
|
||||
Assert.AreEqual("Success", ws.Cell("A2").Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
using ClosedXML.Excel;
|
||||
using ClosedXML.Excel.CalcEngine.Exceptions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.DataValidations
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for UnitTest1
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class DateAndTimeTests
|
||||
{
|
||||
[SetUp]
|
||||
public void SetCultureInfo()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Date()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, 1, 1)");
|
||||
Assert.AreEqual(39448, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, 15, 1)");
|
||||
Assert.AreEqual(39873, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, -50, 1)");
|
||||
Assert.AreEqual(37895, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, 5, 63)");
|
||||
Assert.AreEqual(39631, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, 13, 63)");
|
||||
Assert.AreEqual(39876, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Date(2008, 15, -120)");
|
||||
Assert.AreEqual(39752, actual);
|
||||
}
|
||||
|
||||
[TestCase("1/1/2006", "12/12/2010", "Y", ExpectedResult = 4)]
|
||||
[TestCase("1/1/2006", "12/12/2010", "M", ExpectedResult = 59)]
|
||||
[TestCase("1/1/2006", "12/12/2010", "D", ExpectedResult = 1806)]
|
||||
[TestCase("1/1/2006", "12/12/2010", "MD", ExpectedResult = 11)]
|
||||
[TestCase("1/1/2006", "12/12/2010", "YM", ExpectedResult = 11)]
|
||||
[TestCase("1/1/2006", "12/12/2010", "YD", ExpectedResult = 345)]
|
||||
[TestCase(38718, 40524, "Y", ExpectedResult = 4)]
|
||||
[TestCase(38718, 40524, "M", ExpectedResult = 59)]
|
||||
[TestCase(38718, 40524, "D", ExpectedResult = 1806)]
|
||||
[TestCase(38718, 40524, "MD", ExpectedResult = 11)]
|
||||
[TestCase(38718, 40524, "YM", ExpectedResult = 11)]
|
||||
[TestCase(38718, 40524, "YD", ExpectedResult = 345)]
|
||||
[TestCase("2001-12-31", "2002-4-15", "YM", ExpectedResult = 3)]
|
||||
[TestCase("2001-12-10", "2002-4-15", "YM", ExpectedResult = 4)]
|
||||
[TestCase("2001-12-15", "2002-4-15", "YM", ExpectedResult = 4)]
|
||||
[TestCase("2001-12-31", "2002-4-15", "YD", ExpectedResult = 105)]
|
||||
[TestCase("2001-12-31", "2003-4-15", "YD", ExpectedResult = 105)]
|
||||
[TestCase("2002-01-31", "2002-4-15", "YD", ExpectedResult = 74)]
|
||||
[TestCase("2001-12-02", "2001-12-15", "Y", ExpectedResult = 0)]
|
||||
[TestCase("2001-12-02", "2002-12-02", "Y", ExpectedResult = 1)]
|
||||
[TestCase("2006-01-15", "2006-03-14", "M", ExpectedResult = 1)]
|
||||
[TestCase("2020-11-22", "2020-11-23 9:00", "D", ExpectedResult = 1)]
|
||||
public double Datedif(object startDate, object endDate, string unit)
|
||||
{
|
||||
if (startDate is string s1) startDate = $"\"{s1}\"";
|
||||
if (endDate is string s2) endDate = $"\"{s2}\"";
|
||||
return (double)XLWorkbook.EvaluateExpr($"DATEDIF({startDate}, {endDate}, \"{unit}\")");
|
||||
}
|
||||
|
||||
[TestCase("\"1/1/2010\"", "\"12/12/2006\"", "Y")]
|
||||
[TestCase(40524, 38718, "Y")]
|
||||
[TestCase("\"1/1/2006\"", "\"12/12/2010\"", "N")]
|
||||
[TestCase(38718, 40524, "N")]
|
||||
public void DatedifExceptions(object startDate, object endDate, string unit)
|
||||
{
|
||||
Assert.Throws<NumberException>(() => XLWorkbook.EvaluateExpr($"DATEDIF({startDate}, {endDate}, \"{unit}\")"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Datevalue()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DateValue(\"8/22/2008\")");
|
||||
Assert.AreEqual(39682, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Day()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Day(\"8/22/2008\")");
|
||||
Assert.AreEqual(22, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DAYS(DATE(2016,10,1),DATE(1992,2,29))");
|
||||
Assert.AreEqual(8981, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("DAYS(\"2016-10-1\",\"1992-2-29\")");
|
||||
Assert.AreEqual(8981, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DayWithDifferentCulture()
|
||||
{
|
||||
CultureInfo ci = new CultureInfo(CultureInfo.InvariantCulture.LCID);
|
||||
ci.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
|
||||
Thread.CurrentThread.CurrentCulture = ci;
|
||||
Object actual = XLWorkbook.EvaluateExpr("Day(\"1/6/2008\")");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days360_Default()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Days360(\"1/30/2008\", \"2/1/2008\")");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days360_Europe1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DAYS360(\"1/1/2008\", \"3/31/2008\",TRUE)");
|
||||
Assert.AreEqual(89, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days360_Europe2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DAYS360(\"3/31/2008\", \"1/1/2008\",TRUE)");
|
||||
Assert.AreEqual(-89, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days360_US1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DAYS360(\"1/1/2008\", \"3/31/2008\",FALSE)");
|
||||
Assert.AreEqual(90, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Days360_US2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("DAYS360(\"3/31/2008\", \"1/1/2008\",FALSE)");
|
||||
Assert.AreEqual(-89, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EDate_Negative1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EDate(\"3/1/2008\", -1)");
|
||||
Assert.AreEqual(new DateTime(2008, 2, 1), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EDate_Negative2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EDate(\"3/31/2008\", -1)");
|
||||
Assert.AreEqual(new DateTime(2008, 2, 29), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EDate_Positive1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EDate(\"3/1/2008\", 1)");
|
||||
Assert.AreEqual(new DateTime(2008, 4, 1), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EDate_Positive2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EDate(\"3/31/2008\", 1)");
|
||||
Assert.AreEqual(new DateTime(2008, 4, 30), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EOMonth_Negative()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EOMonth(\"3/1/2008\", -1)");
|
||||
Assert.AreEqual(new DateTime(2008, 2, 29), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EOMonth_Positive()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("EOMonth(\"3/31/2008\", 1)");
|
||||
Assert.AreEqual(new DateTime(2008, 4, 30), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Hour()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Hour(\"8/22/2008 3:30:45 PM\")");
|
||||
Assert.AreEqual(15, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Minute()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Minute(\"8/22/2008 3:30:45 AM\")");
|
||||
Assert.AreEqual(30, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Month()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Month(\"8/22/2008\")");
|
||||
Assert.AreEqual(8, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsoWeekNum()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("ISOWEEKNUM(DATEVALUE(\"2012-3-9\"))");
|
||||
Assert.AreEqual(10, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("ISOWEEKNUM(DATE(2012,12,31))");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Networkdays_MultipleHolidaysGiven()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
|
||||
ws.FirstCell().SetValue("Date")
|
||||
.CellBelow().SetValue(new DateTime(2008, 10, 1))
|
||||
.CellBelow().SetValue(new DateTime(2009, 3, 1))
|
||||
.CellBelow().SetValue(new DateTime(2008, 11, 26))
|
||||
.CellBelow().SetValue(new DateTime(2008, 12, 4))
|
||||
.CellBelow().SetValue(new DateTime(2009, 1, 21));
|
||||
Object actual = ws.Evaluate("Networkdays(A2,A3,A4:A6)");
|
||||
Assert.AreEqual(105, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Networkdays_NoHolidaysGiven()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Networkdays(\"10/01/2008\", \"3/01/2009\")");
|
||||
Assert.AreEqual(108, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Networkdays_NegativeResult()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Networkdays(\"3/01/2009\", \"10/01/2008\")");
|
||||
Assert.AreEqual(-108, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Networkdays(\"2016-01-01\", \"2015-12-23\")");
|
||||
Assert.AreEqual(-8, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Networkdays_OneHolidaysGiven()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Networkdays(\"10/01/2008\", \"3/01/2009\", \"11/26/2008\")");
|
||||
Assert.AreEqual(107, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Second()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Second(\"8/22/2008 3:30:45 AM\")");
|
||||
Assert.AreEqual(45, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Time()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Time(1,2,3)");
|
||||
Assert.AreEqual(new TimeSpan(1, 2, 3), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TimeValue1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("TimeValue(\"2:24 AM\")");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.1, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TimeValue2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("TimeValue(\"22-Aug-2008 6:35 AM\")");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.27430555555555558, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Today()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Today()");
|
||||
Assert.AreEqual(DateTime.Now.Date, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weekday_1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Weekday(\"2/14/2008\", 1)");
|
||||
Assert.AreEqual(5, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weekday_2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Weekday(\"2/14/2008\", 2)");
|
||||
Assert.AreEqual(4, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weekday_3()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Weekday(\"2/14/2008\", 3)");
|
||||
Assert.AreEqual(3, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weekday_Omitted()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Weekday(\"2/14/2008\")");
|
||||
Assert.AreEqual(5, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_1()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2000\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_10()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2004\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_11()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2005\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_12()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2005\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_13()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2006\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_14()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2006\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_15()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2007\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_16()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2007\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_17()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2008\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_18()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2008\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_19()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2009\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_2()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2000\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_20()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2009\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_3()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2001\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_4()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2001\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_5()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2002\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_6()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2002\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_7()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2003\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_8()
|
||||
{
|
||||
Assert.AreEqual(10, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2003\", 2)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_9()
|
||||
{
|
||||
Assert.AreEqual(11, XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2004\", 1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Weeknum_Default()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Weeknum(\"3/9/2008\")");
|
||||
Assert.AreEqual(11, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Workdays_MultipleHolidaysGiven()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
|
||||
ws.FirstCell().SetValue("Date")
|
||||
.CellBelow().SetValue(new DateTime(2008, 10, 1))
|
||||
.CellBelow().SetValue(151)
|
||||
.CellBelow().SetValue(new DateTime(2008, 11, 26))
|
||||
.CellBelow().SetValue(new DateTime(2008, 12, 4))
|
||||
.CellBelow().SetValue(new DateTime(2009, 1, 21));
|
||||
Object actual = ws.Evaluate("Workday(A2,A3,A4:A6)");
|
||||
Assert.AreEqual(new DateTime(2009, 5, 5), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Workdays_NoHolidaysGiven()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Workday(\"10/01/2008\", 151)");
|
||||
Assert.AreEqual(new DateTime(2009, 4, 30), actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Workday(\"2016-01-01\", -10)");
|
||||
Assert.AreEqual(new DateTime(2015, 12, 18), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Workdays_OneHolidaysGiven()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Workday(\"10/01/2008\", 152, \"11/26/2008\")");
|
||||
Assert.AreEqual(new DateTime(2009, 5, 4), actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Year()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Year(\"8/22/2008\")");
|
||||
Assert.AreEqual(2008, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_1_base0()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2008\",0)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.25, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_1_base1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2008\",1)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.24590163934426229, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_1_base2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2008\",2)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.25, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_1_base3()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2008\",3)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.24657534246575341, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_1_base4()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2008\",4)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.24722222222222223, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_2_base0()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2013\",0)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(5.25, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_2_base1()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2013\",1)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(5.24452554744526, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_2_base2()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2013\",2)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(5.32222222222222, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_2_base3()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2013\",3)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(5.24931506849315, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Yearfrac_2_base4()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr("Yearfrac(\"1/1/2008\", \"3/31/2013\",4)");
|
||||
Assert.IsTrue(XLHelper.AreEqual(5.24722222222222, (double)actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class FormulaCachingTests
|
||||
{
|
||||
[Test]
|
||||
public void NewWorkbookDoesNotNeedRecalculation()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var cell = sheet.Cell(1, 1);
|
||||
|
||||
Assert.AreEqual(0, wb.RecalculationCounter);
|
||||
Assert.IsFalse(cell.NeedsRecalculation);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EditCellCausesCounterIncreasing()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var cell = sheet.Cell(1, 1);
|
||||
cell.Value = "1234567";
|
||||
|
||||
Assert.Greater(wb.RecalculationCounter, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StaticCellDoesNotNeedRecalculation()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var cell = sheet.Cell(1, 1);
|
||||
cell.Value = "1234567";
|
||||
|
||||
Assert.IsFalse(cell.NeedsRecalculation);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EditCellInvalidatesDependentCells()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var cell = sheet.Cell(1, 1);
|
||||
var dependentCell = sheet.Cell(2, 1);
|
||||
dependentCell.FormulaA1 = "=A1";
|
||||
var _ = dependentCell.Value;
|
||||
|
||||
cell.Value = "1234567";
|
||||
|
||||
Assert.IsTrue(dependentCell.NeedsRecalculation);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EditFormulaA1InvalidatesDependentCells()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=SUM(A1:A3)";
|
||||
a1.Value = 15;
|
||||
|
||||
var res1 = a4.Value;
|
||||
a2.FormulaA1 = "=A1*20";
|
||||
var res2 = a4.Value;
|
||||
|
||||
Assert.AreEqual(15 + 150 + 1500, res1);
|
||||
Assert.AreEqual(15 + 300 + 3000, res2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EditFormulaR1C1InvalidatesDependentCells()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=SUM(A1:A3)";
|
||||
a1.Value = 15;
|
||||
|
||||
var res1 = a4.Value;
|
||||
a2.FormulaR1C1 = "=R[-1]C*2";
|
||||
var res2 = a4.Value;
|
||||
|
||||
Assert.AreEqual(15 + 150 + 1500, res1);
|
||||
Assert.AreEqual(15 + 30 + 300, res2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertRowInvalidatesValues()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a4.FormulaA1 = "=COUNTBLANK(A1:A3)";
|
||||
|
||||
var res1 = a4.Value;
|
||||
sheet.Row(2).InsertRowsAbove(2);
|
||||
var res2 = a4.Value;
|
||||
|
||||
Assert.AreEqual(3, res1);
|
||||
Assert.AreEqual(5, res2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteRowInvalidatesValues()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a4.FormulaA1 = "=COUNTBLANK(A1:A3)";
|
||||
|
||||
var res1 = a4.Value;
|
||||
sheet.Row(2).Delete();
|
||||
var res2 = a4.Value;
|
||||
|
||||
Assert.AreEqual(3, res1);
|
||||
Assert.AreEqual(2, res2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChainedCalculationPreservesIntermediateValues()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=SUM(A1:A3)";
|
||||
|
||||
a1.Value = 15;
|
||||
var res = a4.Value;
|
||||
|
||||
Assert.AreEqual(15 + 150 + 1500, res);
|
||||
Assert.IsFalse(a4.NeedsRecalculation);
|
||||
Assert.IsFalse(a3.NeedsRecalculation);
|
||||
Assert.IsFalse(a2.NeedsRecalculation);
|
||||
Assert.AreEqual(150, a2.CachedValue);
|
||||
Assert.AreEqual(1500, a3.CachedValue);
|
||||
Assert.AreEqual(15 + 150 + 1500, a4.CachedValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EditingAffectsDependentCells()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=SUM(A1:A3)";
|
||||
a1.Value = 15;
|
||||
|
||||
var res1 = a4.Value;
|
||||
a1.Value = 20;
|
||||
var res2 = a4.Value;
|
||||
|
||||
Assert.AreEqual(15 + 150 + 1500, res1);
|
||||
Assert.AreEqual(20 + 200 + 2000, res2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("C4", new string[] { "C5" })]
|
||||
[TestCase("D4", new string[] { })]
|
||||
[TestCase("A1", new string[] { "A2", "A3", "A4", "C1", "C2", "C3", "C5" })]
|
||||
[TestCase("B2", new string[] { "B3", "B4", "C2", "C3", "C5" })]
|
||||
[TestCase("C2", new string[] { "C5" })]
|
||||
public void EditingDoesNotAffectNonDependingCells(string changedCell, string[] affectedCells)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
sheet.Cell("A2").FormulaA1 = "A1+1";
|
||||
sheet.Cell("A3").FormulaA1 = "SUM(A1:A2)";
|
||||
sheet.Cell("A4").FormulaA1 = "SUM(A1:A3)";
|
||||
sheet.Cell("B2").FormulaA1 = "B1+1";
|
||||
sheet.Cell("B3").FormulaA1 = "SUM(B1:B2)";
|
||||
sheet.Cell("B4").FormulaA1 = "SUM(B1:B3)";
|
||||
sheet.Cell("C1").FormulaA1 = "SUM(A1:B1)";
|
||||
sheet.Cell("C2").FormulaA1 = "SUM(A2:B2)";
|
||||
sheet.Cell("C3").FormulaA1 = "SUM(A3:B3)";
|
||||
sheet.Cell("C5").FormulaA1 = "SUM($A$1:$C$4)";
|
||||
sheet.RecalculateAllFormulas();
|
||||
var allCells = sheet.CellsUsed();
|
||||
|
||||
sheet.Cell(changedCell).Value = 100;
|
||||
var modifiedCells = allCells.Where(cell => cell.NeedsRecalculation);
|
||||
|
||||
Assert.AreEqual(affectedCells.Length, modifiedCells.Count());
|
||||
foreach (var cellAddress in affectedCells)
|
||||
{
|
||||
Assert.IsTrue(modifiedCells.Any(cell => cell.Address.ToString() == cellAddress),
|
||||
string.Format("Cell {0} is expected to need recalculation, but it does not", cellAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircularReferenceFailsCalculating()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=A3*10";
|
||||
a1.FormulaA1 = "A2+A3+A4";
|
||||
|
||||
var getValueA1 = new TestDelegate(() => { var v = a1.Value; });
|
||||
var getValueA2 = new TestDelegate(() => { var v = a2.Value; });
|
||||
var getValueA3 = new TestDelegate(() => { var v = a3.Value; });
|
||||
var getValueA4 = new TestDelegate(() => { var v = a4.Value; });
|
||||
|
||||
Assert.Throws(typeof(InvalidOperationException), getValueA1);
|
||||
Assert.Throws(typeof(InvalidOperationException), getValueA2);
|
||||
Assert.Throws(typeof(InvalidOperationException), getValueA3);
|
||||
Assert.Throws(typeof(InvalidOperationException), getValueA4);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CircularReferenceRecalculationNeededDoesNotFail()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var a1 = sheet.Cell("A1");
|
||||
var a2 = sheet.Cell("A2");
|
||||
var a3 = sheet.Cell("A3");
|
||||
var a4 = sheet.Cell("A4");
|
||||
|
||||
a2.FormulaA1 = "=A1*10";
|
||||
a3.FormulaA1 = "=A2*10";
|
||||
a4.FormulaA1 = "=A3*10";
|
||||
var _ = a4.Value;
|
||||
a1.FormulaA1 = "=SUM(A2:A4)";
|
||||
|
||||
var recalcNeededA1 = a1.NeedsRecalculation;
|
||||
var recalcNeededA2 = a2.NeedsRecalculation;
|
||||
var recalcNeededA3 = a3.NeedsRecalculation;
|
||||
var recalcNeededA4 = a4.NeedsRecalculation;
|
||||
|
||||
Assert.IsTrue(recalcNeededA1);
|
||||
Assert.IsTrue(recalcNeededA2);
|
||||
Assert.IsTrue(recalcNeededA3);
|
||||
Assert.IsTrue(recalcNeededA4);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteWorksheetInvalidatesValues()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet1 = wb.Worksheets.Add("Sheet1");
|
||||
var sheet2 = wb.Worksheets.Add("Sheet2");
|
||||
var sheet1_a1 = sheet1.Cell("A1");
|
||||
var sheet2_a1 = sheet2.Cell("A1");
|
||||
sheet1_a1.FormulaA1 = "Sheet2!A1";
|
||||
sheet2_a1.Value = "TestValue";
|
||||
|
||||
var val1 = sheet1_a1.Value;
|
||||
sheet2.Delete();
|
||||
var getValue = new TestDelegate(() => { var val2 = sheet1_a1.Value; });
|
||||
|
||||
Assert.AreEqual("TestValue", val1.ToString());
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), getValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestValueCellsCachedValue()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.Worksheets.Add("TestSheet");
|
||||
var cell = sheet.Cell(1, 1);
|
||||
|
||||
var date = new DateTime(2018, 4, 19); ;
|
||||
cell.Value = date;
|
||||
|
||||
Assert.AreEqual(XLDataType.DateTime, cell.DataType);
|
||||
Assert.AreEqual(date, cell.CachedValue);
|
||||
|
||||
cell.DataType = XLDataType.Number;
|
||||
|
||||
Assert.AreEqual(XLDataType.Number, cell.DataType);
|
||||
Assert.AreEqual(date.ToOADate(), cell.CachedValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CachedValueToExternalWorkbook()
|
||||
{
|
||||
using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Other\ExternalLinks\WorkbookWithExternalLink.xlsx")))
|
||||
using (var wb = new XLWorkbook(stream))
|
||||
{
|
||||
var ws = wb.Worksheets.First();
|
||||
var cell = ws.Cell("B2");
|
||||
Assert.IsFalse(cell.NeedsRecalculation);
|
||||
Assert.IsTrue(cell.HasFormula);
|
||||
|
||||
// This will fail when we start supporting external links
|
||||
Assert.IsTrue(cell.FormulaA1.StartsWith("[1]"));
|
||||
|
||||
Assert.AreEqual("hello world", cell.CachedValue);
|
||||
Assert.AreEqual("hello world", cell.Value);
|
||||
|
||||
Assert.AreEqual(11, ws.Evaluate("LEN(B2)"));
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => wb.RecalculateAllFormulas());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChangingDataTypeChangesCachedValue()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Test");
|
||||
ws.Cell(1, 1).Value = new DateTime(2019, 1, 1, 14, 0, 0);
|
||||
ws.Cell(1, 2).Value = new DateTime(2019, 1, 1, 17, 45, 0);
|
||||
var cell = ws.Cell(1, 3);
|
||||
cell.FormulaA1 = "=B1-A1";
|
||||
cell.Style.DateFormat.Format = "hh:mm";
|
||||
|
||||
Assert.IsNull(cell.CachedValue);
|
||||
|
||||
double value = (double)cell.Value;
|
||||
Assert.AreEqual(value, cell.CachedValue);
|
||||
|
||||
cell.DataType = XLDataType.DateTime;
|
||||
Assert.AreEqual(DateTime.FromOADate(value), cell.CachedValue);
|
||||
Assert.AreEqual("03:45", cell.GetFormattedString());
|
||||
|
||||
cell.DataType = XLDataType.Number;
|
||||
Assert.AreEqual(value, (double)cell.CachedValue, 1e-10);
|
||||
Assert.AreEqual("0.15625", cell.GetFormattedString());
|
||||
|
||||
cell.DataType = XLDataType.TimeSpan;
|
||||
Assert.AreEqual(TimeSpan.FromDays(value), (TimeSpan)cell.CachedValue);
|
||||
Assert.AreEqual("03:45:00", cell.GetFormattedString()); // I think the seconds in this string is due to a shortcoming in the ExcelNumberFormat library
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,754 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class FunctionsTests
|
||||
{
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// Make sure tests run on a deterministic culture
|
||||
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Asc()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Asc(""Text"")");
|
||||
Assert.AreEqual("Text", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Clean()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(String.Format(@"Clean(""A{0}B"")", Environment.NewLine));
|
||||
Assert.AreEqual("AB", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Combin()
|
||||
{
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Combin(200, 2)");
|
||||
Assert.AreEqual(19900.0, actual1);
|
||||
|
||||
object actual2 = XLWorkbook.EvaluateExpr("Combin(20.1, 2.9)");
|
||||
Assert.AreEqual(190.0, actual2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Degrees()
|
||||
{
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Degrees(180)");
|
||||
Assert.IsTrue(Math.PI - (double)actual1 < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Dollar()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Dollar(12345.123)");
|
||||
Assert.AreEqual(TestHelper.CurrencySymbol + "12,345.12", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Dollar(12345.123, 1)");
|
||||
Assert.AreEqual(TestHelper.CurrencySymbol + "12,345.1", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Even()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Even(3)");
|
||||
Assert.AreEqual(4, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(2)");
|
||||
Assert.AreEqual(2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(-1)");
|
||||
Assert.AreEqual(-2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(-2)");
|
||||
Assert.AreEqual(-2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(0)");
|
||||
Assert.AreEqual(0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(1.5)");
|
||||
Assert.AreEqual(2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Even(2.01)");
|
||||
Assert.AreEqual(4, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Exact()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Exact(\"A\", \"A\")");
|
||||
Assert.AreEqual(true, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Exact(\"A\", \"a\")");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Fact()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Fact(5.9)");
|
||||
Assert.AreEqual(120.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FactDouble()
|
||||
{
|
||||
object actual1 = XLWorkbook.EvaluateExpr("FactDouble(6)");
|
||||
Assert.AreEqual(48.0, actual1);
|
||||
object actual2 = XLWorkbook.EvaluateExpr("FactDouble(7)");
|
||||
Assert.AreEqual(105.0, actual2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Fixed()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Fixed(12345.123)");
|
||||
Assert.AreEqual("12,345.12", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Fixed(12345.123, 1)");
|
||||
Assert.AreEqual("12,345.1", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Fixed(12345.123, 1, TRUE)");
|
||||
Assert.AreEqual("12345.1", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Formula_from_another_sheet()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws1 = wb.AddWorksheet("ws1");
|
||||
ws1.FirstCell().SetValue(1).CellRight().SetFormulaA1("A1 + 1");
|
||||
IXLWorksheet ws2 = wb.AddWorksheet("ws2");
|
||||
ws2.FirstCell().SetFormulaA1("ws1!B1 + 1");
|
||||
object v = ws2.FirstCell().Value;
|
||||
Assert.AreEqual(3.0, v);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Gcd()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Gcd(24, 36)");
|
||||
Assert.AreEqual(12, actual);
|
||||
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Gcd(5, 0)");
|
||||
Assert.AreEqual(5, actual1);
|
||||
|
||||
object actual2 = XLWorkbook.EvaluateExpr("Gcd(0, 5)");
|
||||
Assert.AreEqual(5, actual2);
|
||||
|
||||
object actual3 = XLWorkbook.EvaluateExpr("Gcd(240, 360, 30)");
|
||||
Assert.AreEqual(30, actual3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Lcm()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Lcm(24, 36)");
|
||||
Assert.AreEqual(72, actual);
|
||||
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Lcm(5, 0)");
|
||||
Assert.AreEqual(0, actual1);
|
||||
|
||||
object actual2 = XLWorkbook.EvaluateExpr("Lcm(0, 5)");
|
||||
Assert.AreEqual(0, actual2);
|
||||
|
||||
object actual3 = XLWorkbook.EvaluateExpr("Lcm(240, 360, 30)");
|
||||
Assert.AreEqual(720, actual3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MDetem()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").SetValue(2).CellRight().SetValue(4);
|
||||
ws.Cell("A2").SetValue(3).CellRight().SetValue(5);
|
||||
|
||||
Object actual;
|
||||
|
||||
ws.Cell("A5").FormulaA1 = "MDeterm(A1:B2)";
|
||||
actual = ws.Cell("A5").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(-2.0, (double)actual));
|
||||
|
||||
ws.Cell("A6").FormulaA1 = "Sum(A5)";
|
||||
actual = ws.Cell("A6").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(-2.0, (double)actual));
|
||||
|
||||
ws.Cell("A7").FormulaA1 = "Sum(MDeterm(A1:B2))";
|
||||
actual = ws.Cell("A7").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(-2.0, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MInverse()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").SetValue(1).CellRight().SetValue(2).CellRight().SetValue(1);
|
||||
ws.Cell("A2").SetValue(3).CellRight().SetValue(4).CellRight().SetValue(-1);
|
||||
ws.Cell("A3").SetValue(0).CellRight().SetValue(2).CellRight().SetValue(0);
|
||||
|
||||
Object actual;
|
||||
|
||||
ws.Cell("A5").FormulaA1 = "MInverse(A1:C3)";
|
||||
actual = ws.Cell("A5").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.25, (double)actual));
|
||||
|
||||
ws.Cell("A6").FormulaA1 = "Sum(A5)";
|
||||
actual = ws.Cell("A6").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.25, (double)actual));
|
||||
|
||||
ws.Cell("A7").FormulaA1 = "Sum(MInverse(A1:C3))";
|
||||
actual = ws.Cell("A7").Value;
|
||||
|
||||
Assert.IsTrue(XLHelper.AreEqual(0.5, (double)actual));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MMult()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").SetValue(2).CellRight().SetValue(4);
|
||||
ws.Cell("A2").SetValue(3).CellRight().SetValue(5);
|
||||
ws.Cell("A3").SetValue(2).CellRight().SetValue(4);
|
||||
ws.Cell("A4").SetValue(3).CellRight().SetValue(5);
|
||||
|
||||
Object actual;
|
||||
|
||||
ws.Cell("A5").FormulaA1 = "MMult(A1:B2, A3:B4)";
|
||||
actual = ws.Cell("A5").Value;
|
||||
|
||||
Assert.AreEqual(16.0, actual);
|
||||
|
||||
ws.Cell("A6").FormulaA1 = "Sum(A5)";
|
||||
actual = ws.Cell("A6").Value;
|
||||
|
||||
Assert.AreEqual(16.0, actual);
|
||||
|
||||
ws.Cell("A7").FormulaA1 = "Sum(MMult(A1:B2, A3:B4))";
|
||||
actual = ws.Cell("A7").Value;
|
||||
|
||||
Assert.AreEqual(102.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Mod()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Mod(3, 2)");
|
||||
Assert.AreEqual(1, actual);
|
||||
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Mod(-3, 2)");
|
||||
Assert.AreEqual(1, actual1);
|
||||
|
||||
object actual2 = XLWorkbook.EvaluateExpr("Mod(3, -2)");
|
||||
Assert.AreEqual(-1, actual2);
|
||||
|
||||
object actual3 = XLWorkbook.EvaluateExpr("Mod(-3, -2)");
|
||||
Assert.AreEqual(-1, actual3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Multinomial()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Multinomial(2,3,4)");
|
||||
Assert.AreEqual(1260.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Odd()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Odd(1.5)");
|
||||
Assert.AreEqual(3, actual);
|
||||
|
||||
object actual1 = XLWorkbook.EvaluateExpr("Odd(3)");
|
||||
Assert.AreEqual(3, actual1);
|
||||
|
||||
object actual2 = XLWorkbook.EvaluateExpr("Odd(2)");
|
||||
Assert.AreEqual(3, actual2);
|
||||
|
||||
object actual3 = XLWorkbook.EvaluateExpr("Odd(-1)");
|
||||
Assert.AreEqual(-1, actual3);
|
||||
|
||||
object actual4 = XLWorkbook.EvaluateExpr("Odd(-2)");
|
||||
Assert.AreEqual(-3, actual4);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Odd(0)");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Product()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Product(2,3,4)");
|
||||
Assert.AreEqual(24.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Quotient()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Quotient(5,2)");
|
||||
Assert.AreEqual(2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Quotient(4.5,3.1)");
|
||||
Assert.AreEqual(1, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Quotient(-10,3)");
|
||||
Assert.AreEqual(-3, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Radians()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Radians(270)");
|
||||
Assert.IsTrue(Math.Abs(4.71238898038469 - (double)actual) < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Roman()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Roman(3046, 1)");
|
||||
Assert.AreEqual("MMMXLVI", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Roman(270)");
|
||||
Assert.AreEqual("CCLXX", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Roman(3999, true)");
|
||||
Assert.AreEqual("MMMCMXCIX", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Round()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Round(2.15, 1)");
|
||||
Assert.AreEqual(2.2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Round(2.149, 1)");
|
||||
Assert.AreEqual(2.1, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Round(-1.475, 2)");
|
||||
Assert.AreEqual(-1.48, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Round(21.5, -1)");
|
||||
Assert.AreEqual(20.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Round(626.3, -3)");
|
||||
Assert.AreEqual(1000.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Round(1.98, -1)");
|
||||
Assert.AreEqual(0.0, actual);
|
||||
|
||||
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);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("ROUND(59 * -0.535, 2)"); // (59 * -0.535) = -31.565
|
||||
Assert.AreEqual(-31.57, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundDown()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("RoundDown(3.2, 0)");
|
||||
Assert.AreEqual(3.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundDown(76.9, 0)");
|
||||
Assert.AreEqual(76.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundDown(3.14159, 3)");
|
||||
Assert.AreEqual(3.141, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundDown(-3.14159, 1)");
|
||||
Assert.AreEqual(-3.1, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundDown(31415.92654, -2)");
|
||||
Assert.AreEqual(31400.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundDown(0, 3)");
|
||||
Assert.AreEqual(0.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundUp()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("RoundUp(3.2, 0)");
|
||||
Assert.AreEqual(4.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundUp(76.9, 0)");
|
||||
Assert.AreEqual(77.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundUp(3.14159, 3)");
|
||||
Assert.AreEqual(3.142, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundUp(-3.14159, 1)");
|
||||
Assert.AreEqual(-3.2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundUp(31415.92654, -2)");
|
||||
Assert.AreEqual(31500.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("RoundUp(0, 3)");
|
||||
Assert.AreEqual(0.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SeriesSum()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("SERIESSUM(2,3,4,5)");
|
||||
Assert.AreEqual(40.0, actual);
|
||||
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A2").FormulaA1 = "PI()/4";
|
||||
ws.Cell("A3").Value = 1;
|
||||
ws.Cell("A4").FormulaA1 = "-1/FACT(2)";
|
||||
ws.Cell("A5").FormulaA1 = "1/FACT(4)";
|
||||
ws.Cell("A6").FormulaA1 = "-1/FACT(6)";
|
||||
|
||||
actual = ws.Evaluate("SERIESSUM(A2,0,2,A3:A6)");
|
||||
Assert.IsTrue(Math.Abs(0.70710321482284566 - (double)actual) < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SqrtPi()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("SqrtPi(1)");
|
||||
Assert.IsTrue(Math.Abs(1.7724538509055159 - (double)actual) < XLHelper.Epsilon);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("SqrtPi(2)");
|
||||
Assert.IsTrue(Math.Abs(2.5066282746310002 - (double)actual) < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalAverage()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Subtotal(1,2,3)");
|
||||
Assert.AreEqual(2.5, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(1,""A"",3, 2)");
|
||||
Assert.AreEqual(2.5, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalCount()
|
||||
{
|
||||
object actual = XLWorkbook.EvaluateExpr("Subtotal(2,2,3)");
|
||||
Assert.AreEqual(2, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(2,""A"",3)");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalCountA()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("Subtotal(3,2,3)");
|
||||
Assert.AreEqual(2.0, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(3,"""",3)");
|
||||
Assert.AreEqual(1.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalMax()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(4,2,3,""A"")");
|
||||
Assert.AreEqual(3.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalMin()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(5,2,3,""A"")");
|
||||
Assert.AreEqual(2.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalProduct()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(6,2,3,""A"")");
|
||||
Assert.AreEqual(6.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalStDev()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(7,2,3,""A"")");
|
||||
Assert.IsTrue(Math.Abs(0.70710678118654757 - (double)actual) < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalStDevP()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(8,2,3,""A"")");
|
||||
Assert.AreEqual(0.5, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalSum()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(9,2,3,""A"")");
|
||||
Assert.AreEqual(5.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalVar()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(10,2,3,""A"")");
|
||||
Assert.IsTrue(Math.Abs(0.5 - (double)actual) < XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalVarP()
|
||||
{
|
||||
Object actual;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"Subtotal(11,2,3,""A"")");
|
||||
Assert.AreEqual(0.25, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubtotalCalc()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet();
|
||||
ws.NamedRanges.Add("subtotalrange", "A37:A38");
|
||||
|
||||
ws.Cell("A1").Value = 2;
|
||||
ws.Cell("A2").Value = 4;
|
||||
ws.Cell("A3").FormulaA1 = "SUBTOTAL(9, A1:A2)"; // simple add subtotal
|
||||
ws.Cell("A4").Value = 8;
|
||||
ws.Cell("A5").Value = 16;
|
||||
ws.Cell("A6").FormulaA1 = "SUBTOTAL(9, A4:A5)"; // simple add subtotal
|
||||
ws.Cell("A7").Value = 32;
|
||||
ws.Cell("A8").Value = 64;
|
||||
ws.Cell("A9").FormulaA1 = "SUM(A7:A8)"; // func but not subtotal
|
||||
ws.Cell("A10").Value = 128;
|
||||
ws.Cell("A11").Value = 256;
|
||||
ws.Cell("A12").FormulaA1 = "SUBTOTAL(1, A10:A11)"; // simple avg subtotal
|
||||
ws.Cell("A13").Value = 512;
|
||||
ws.Cell("A14").FormulaA1 = "SUBTOTAL(9, A1:A13)"; // subtotals in range
|
||||
ws.Cell("A15").Value = 1024;
|
||||
ws.Cell("A16").Value = 2048;
|
||||
ws.Cell("A17").FormulaA1 = "42 + SUBTOTAL(9, A15:A16)"; // simple add subtotal in formula
|
||||
ws.Cell("A18").Value = 4096;
|
||||
ws.Cell("A19").FormulaA1 = "SUBTOTAL(9, A15:A18)"; // subtotals in range
|
||||
ws.Cell("A20").Value = 8192;
|
||||
ws.Cell("A21").Value = 16384;
|
||||
ws.Cell("A22").FormulaA1 = @"32768 * SEARCH(""SUBTOTAL(9, A1:A2)"", A28)"; // subtotal literal in formula
|
||||
ws.Cell("A23").FormulaA1 = "SUBTOTAL(9, A20:A22)"; // subtotal literal in formula in range
|
||||
ws.Cell("A24").Value = 65536;
|
||||
ws.Cell("A25").FormulaA1 = "A23"; // link to subtotal
|
||||
ws.Cell("A26").FormulaA1 = "PRODUCT(SUBTOTAL(9, A24:A25), 2)"; // subtotal as parameter in func
|
||||
ws.Cell("A27").Value = 131072;
|
||||
ws.Cell("A28").Value = "SUBTOTAL(9, A1:A2)"; // subtotal literal
|
||||
ws.Cell("A29").FormulaA1 = "SUBTOTAL(9, A27:A28)"; // subtotal literal in range
|
||||
ws.Cell("A30").FormulaA1 = "SUBTOTAL(9, A31:A32)"; // simple add subtotal backward
|
||||
ws.Cell("A31").Value = 262144;
|
||||
ws.Cell("A32").Value = 524288;
|
||||
ws.Cell("A33").FormulaA1 = "SUBTOTAL(9, A20:A32)"; // subtotals in range
|
||||
ws.Cell("A34").FormulaA1 = @"SUBTOTAL(VALUE(""9""), A1:A33, A35:A41)"; // func as parameter in subtotal and many ranges
|
||||
ws.Cell("A35").Value = 1048576;
|
||||
ws.Cell("A36").FormulaA1 = "SUBTOTAL(9, A31:A32, A35)"; // many ranges
|
||||
ws.Cell("A37").Value = 2097152;
|
||||
ws.Cell("A38").Value = 4194304;
|
||||
ws.Cell("A39").FormulaA1 = "SUBTOTAL(3*3, subtotalrange)"; // formula as parameter in subtotal and named range
|
||||
ws.Cell("A40").Value = 8388608;
|
||||
ws.Cell("A41").FormulaA1 = "PRODUCT(SUBTOTAL(A4+1, A35:A40), 2)"; // formula with link as parameter in subtotal
|
||||
ws.Cell("A42").FormulaA1 = "PRODUCT(SUBTOTAL(A4+1, A35:A40), 2) + SUBTOTAL(A4+1, A35:A40)"; // two subtotals in one formula
|
||||
|
||||
Assert.AreEqual(6, ws.Cell("A3").Value);
|
||||
Assert.AreEqual(24, ws.Cell("A6").Value);
|
||||
Assert.AreEqual(192, ws.Cell("A12").Value);
|
||||
Assert.AreEqual(1118, ws.Cell("A14").Value);
|
||||
Assert.AreEqual(3114, ws.Cell("A17").Value);
|
||||
Assert.AreEqual(7168, ws.Cell("A19").Value);
|
||||
Assert.AreEqual(57344, ws.Cell("A23").Value);
|
||||
Assert.AreEqual(245760, ws.Cell("A26").Value);
|
||||
Assert.AreEqual(131072, ws.Cell("A29").Value);
|
||||
Assert.AreEqual(786432, ws.Cell("A30").Value);
|
||||
Assert.AreEqual(1097728, ws.Cell("A33").Value);
|
||||
Assert.AreEqual(16834654, ws.Cell("A34").Value);
|
||||
Assert.AreEqual(1835008, ws.Cell("A36").Value);
|
||||
Assert.AreEqual(6291456, ws.Cell("A39").Value);
|
||||
Assert.AreEqual(31457280, ws.Cell("A41").Value);
|
||||
Assert.AreEqual(47185920, ws.Cell("A42").Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Sum()
|
||||
{
|
||||
IXLCell cell = new XLWorkbook().AddWorksheet("Sheet1").FirstCell();
|
||||
IXLCell fCell = cell.SetValue(1).CellBelow().SetValue(2).CellBelow();
|
||||
fCell.FormulaA1 = "sum(A1:A2)";
|
||||
|
||||
Assert.AreEqual(3.0, fCell.Value);
|
||||
}
|
||||
|
||||
[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;
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"SumSq(3,4)");
|
||||
Assert.AreEqual(25.0, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextConcat()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").Value = 1;
|
||||
ws.Cell("A2").Value = 1;
|
||||
ws.Cell("B1").Value = 1;
|
||||
ws.Cell("B2").Value = 1;
|
||||
|
||||
ws.Cell("C1").FormulaA1 = "\"The total value is: \" & SUM(A1:B2)";
|
||||
|
||||
object r = ws.Cell("C1").Value;
|
||||
Assert.AreEqual("The total value is: 4", r.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Trim()
|
||||
{
|
||||
Assert.AreEqual("Test", XLWorkbook.EvaluateExpr("Trim(\"Test \")"));
|
||||
|
||||
//Should not trim non breaking space
|
||||
//See http://office.microsoft.com/en-us/excel-help/trim-function-HP010062581.aspx
|
||||
Assert.AreEqual("Test\u00A0", XLWorkbook.EvaluateExpr("Trim(\"Test\u00A0 \")"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEmptyTallyOperations()
|
||||
{
|
||||
//In these test no values have been set
|
||||
XLWorkbook wb = new XLWorkbook();
|
||||
wb.Worksheets.Add("TallyTests");
|
||||
var cell = wb.Worksheet(1).Cell(1, 1).SetFormulaA1("=MAX(D1,D2)");
|
||||
Assert.AreEqual(0, cell.Value);
|
||||
cell = wb.Worksheet(1).Cell(2, 1).SetFormulaA1("=MIN(D1,D2)");
|
||||
Assert.AreEqual(0, cell.Value);
|
||||
cell = wb.Worksheet(1).Cell(3, 1).SetFormulaA1("=SUM(D1,D2)");
|
||||
Assert.AreEqual(0, cell.Value);
|
||||
Assert.That(() => wb.Worksheet(1).Cell(3, 1).SetFormulaA1("=AVERAGE(D1,D2)").Value, Throws.TypeOf<ApplicationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOmittedParameters()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
object value;
|
||||
value = wb.Evaluate("=IF(TRUE,1)");
|
||||
Assert.AreEqual(1, value);
|
||||
|
||||
value = wb.Evaluate("=IF(TRUE,1,)");
|
||||
Assert.AreEqual(1, value);
|
||||
|
||||
value = wb.Evaluate("=IF(FALSE,1,)");
|
||||
Assert.AreEqual(false, value);
|
||||
|
||||
value = wb.Evaluate("=IF(FALSE,,2)");
|
||||
Assert.AreEqual(2, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDefaultExcelFunctionNamespace()
|
||||
{
|
||||
Assert.DoesNotThrow(() => XLWorkbook.EvaluateExpr("TODAY()"));
|
||||
Assert.DoesNotThrow(() => XLWorkbook.EvaluateExpr("_xlfn.TODAY()"));
|
||||
Assert.IsTrue((bool)XLWorkbook.EvaluateExpr("_xlfn.TODAY() = TODAY()"));
|
||||
}
|
||||
|
||||
[TestCase("=1234%", 12.34)]
|
||||
[TestCase("=1234%%", 0.1234)]
|
||||
[TestCase("=100+200%", 102.0)]
|
||||
[TestCase("=100%+200", 201.0)]
|
||||
[TestCase("=(100+200)%", 3.0)]
|
||||
[TestCase("=200%^5", 32.0)]
|
||||
[TestCase("=200%^400%", 16.0)]
|
||||
[TestCase("=SUM(100,200,300)%", 6.0)]
|
||||
public void PercentOperator(string formula, double expectedResult)
|
||||
{
|
||||
var res = (double)XLWorkbook.EvaluateExpr(formula);
|
||||
|
||||
Assert.AreEqual(expectedResult, res, XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[TestCase("=--1", 1)]
|
||||
[TestCase("=++1", 1)]
|
||||
[TestCase("=-+-+-1", -1)]
|
||||
[TestCase("=2^---2", 0.25)]
|
||||
public void MultipleUnaryOperators(string formula, double expectedResult)
|
||||
{
|
||||
var res = (double)XLWorkbook.EvaluateExpr(formula);
|
||||
|
||||
Assert.AreEqual(expectedResult, res, XLHelper.Epsilon);
|
||||
}
|
||||
|
||||
[TestCase("RIGHT(\"2020\", 2) + 1", 21)]
|
||||
[TestCase("LEFT(\"20.2020\", 6) + 1", 21.202)]
|
||||
[TestCase("2 + (\"3\" & \"4\")", 36)]
|
||||
[TestCase("2 + \"3\" & \"4\"", "54")]
|
||||
[TestCase("\"7\" & \"4\"", "74")]
|
||||
public void TestStringSubExpression(string formula, object expectedResult)
|
||||
{
|
||||
var actual = XLWorkbook.EvaluateExpr(formula);
|
||||
|
||||
Assert.AreEqual(expectedResult, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class InformationTests
|
||||
{
|
||||
[SetUp]
|
||||
public void SetCultureInfo()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
|
||||
}
|
||||
|
||||
#region IsBlank Tests
|
||||
|
||||
[Test]
|
||||
public void IsBlank_MultipleAllEmpty_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
var actual = ws.Evaluate("=IsBlank(A1:A3)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBlank_MultipleAllFill_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "1";
|
||||
ws.Cell("A2").Value = "1";
|
||||
ws.Cell("A3").Value = "1";
|
||||
var actual = ws.Evaluate("=IsBlank(A1:A3)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBlank_MultipleMixedFill_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "1";
|
||||
ws.Cell("A3").Value = "1";
|
||||
var actual = ws.Evaluate("=IsBlank(A1:A3)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBlank_Single_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = " ";
|
||||
var actual = ws.Evaluate("=IsBlank(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBlank_Single_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
var actual = ws.Evaluate("=IsBlank(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsBlank Tests
|
||||
|
||||
#region IsEven Tests
|
||||
|
||||
[Test]
|
||||
public void IsEven_Single_False()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = 1;
|
||||
ws.Cell("A2").Value = 1.2;
|
||||
ws.Cell("A3").Value = 3;
|
||||
|
||||
var actual = ws.Evaluate("=IsEven(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
|
||||
actual = ws.Evaluate("=IsEven(A2)");
|
||||
Assert.AreEqual(false, actual);
|
||||
|
||||
actual = ws.Evaluate("=IsEven(A3)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEven_Single_True()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = 4;
|
||||
ws.Cell("A2").Value = 0.2;
|
||||
ws.Cell("A3").Value = 12.2;
|
||||
|
||||
var actual = ws.Evaluate("=IsEven(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
|
||||
actual = ws.Evaluate("=IsEven(A2)");
|
||||
Assert.AreEqual(true, actual);
|
||||
|
||||
actual = ws.Evaluate("=IsEven(A3)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IsEven Tests
|
||||
|
||||
#region IsLogical Tests
|
||||
|
||||
[Test]
|
||||
public void IsLogical_Simpe_False()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = 123;
|
||||
|
||||
var actual = ws.Evaluate("=IsLogical(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsLogical_Simple_True()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = true;
|
||||
|
||||
var actual = ws.Evaluate("=IsLogical(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsLogical Tests
|
||||
|
||||
[Test]
|
||||
public void IsNA()
|
||||
{
|
||||
object actual;
|
||||
actual = XLWorkbook.EvaluateExpr("ISNA(#N/A)");
|
||||
Assert.AreEqual(true, actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr("ISNA(#REF!)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
|
||||
#region IsNotText Tests
|
||||
|
||||
[Test]
|
||||
public void IsNotText_Simple_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "asd";
|
||||
var actual = ws.Evaluate("=IsNonText(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsNotText_Simple_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "123"; //Double Value
|
||||
ws.Cell("A2").Value = DateTime.Now; //Date Value
|
||||
ws.Cell("A3").Value = "12,235.5"; //Comma Formatting
|
||||
ws.Cell("A4").Value = "$12,235.5"; //Currency Value
|
||||
ws.Cell("A5").Value = true; //Bool Value
|
||||
ws.Cell("A6").Value = "12%"; //Percentage Value
|
||||
|
||||
var actual = ws.Evaluate("=IsNonText(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNonText(A2)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNonText(A3)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNonText(A4)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNonText(A5)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNonText(A6)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsNotText Tests
|
||||
|
||||
#region IsNumber Tests
|
||||
|
||||
[Test]
|
||||
public void IsNumber_Simple_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "asd"; //String Value
|
||||
ws.Cell("A2").Value = true; //Bool Value
|
||||
|
||||
var actual = ws.Evaluate("=IsNumber(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsNumber(A2)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsNumber_Simple_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "123"; //Double Value
|
||||
ws.Cell("A2").Value = DateTime.Now; //Date Value
|
||||
ws.Cell("A3").Value = "12,235.5"; //Coma Formatting
|
||||
ws.Cell("A4").Value = "$12,235.5"; //Currency Value
|
||||
ws.Cell("A5").Value = "12%"; //Percentage Value
|
||||
|
||||
var actual = ws.Evaluate("=IsNumber(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNumber(A2)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNumber(A3)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNumber(A4)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsNumber(A5)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsNumber Tests
|
||||
|
||||
#region IsOdd Test
|
||||
|
||||
[Test]
|
||||
public void IsOdd_Simple_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = 4;
|
||||
ws.Cell("A2").Value = 0.2;
|
||||
ws.Cell("A3").Value = 12.2;
|
||||
|
||||
var actual = ws.Evaluate("=IsOdd(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsOdd(A2)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsOdd(A3)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsOdd_Simple_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = 1;
|
||||
ws.Cell("A2").Value = 1.2;
|
||||
ws.Cell("A3").Value = 3;
|
||||
|
||||
var actual = ws.Evaluate("=IsOdd(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsOdd(A2)");
|
||||
Assert.AreEqual(true, actual);
|
||||
actual = ws.Evaluate("=IsOdd(A3)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsOdd Test
|
||||
|
||||
[Test]
|
||||
public void IsRef()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "123";
|
||||
|
||||
ws.Cell("B1").FormulaA1 = "ISREF(A1)";
|
||||
ws.Cell("B2").FormulaA1 = "ISREF(5)";
|
||||
ws.Cell("B3").FormulaA1 = "ISREF(YEAR(TODAY()))";
|
||||
|
||||
bool actual;
|
||||
actual = ws.Cell("B1").GetValue<bool>();
|
||||
Assert.AreEqual(true, actual);
|
||||
|
||||
actual = ws.Cell("B2").GetValue<bool>();
|
||||
Assert.AreEqual(false, actual);
|
||||
|
||||
actual = ws.Cell("B3").GetValue<bool>();
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#region IsText Tests
|
||||
|
||||
[Test]
|
||||
public void IsText_Simple_false()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "123"; //Double Value
|
||||
ws.Cell("A2").Value = DateTime.Now; //Date Value
|
||||
ws.Cell("A3").Value = "12,235.5"; //Comma Formatting
|
||||
ws.Cell("A4").Value = "$12,235.5"; //Currency Value
|
||||
ws.Cell("A5").Value = true; //Bool Value
|
||||
ws.Cell("A6").Value = "12%"; //Percentage Value
|
||||
|
||||
var actual = ws.Evaluate("=IsText(A1)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsText(A2)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsText(A3)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsText(A4)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsText(A5)");
|
||||
Assert.AreEqual(false, actual);
|
||||
actual = ws.Evaluate("=IsText(A6)");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsText_Simple_true()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
|
||||
ws.Cell("A1").Value = "asd";
|
||||
|
||||
var actual = ws.Evaluate("=IsText(A1)");
|
||||
Assert.AreEqual(true, actual);
|
||||
}
|
||||
}
|
||||
#endregion IsText Tests
|
||||
|
||||
#region N Tests
|
||||
|
||||
[Test]
|
||||
public void N_Date_SerialNumber()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
var testedDate = DateTime.Now;
|
||||
ws.Cell("A1").Value = testedDate;
|
||||
var actual = ws.Evaluate("=N(A1)");
|
||||
Assert.AreEqual(testedDate.ToOADate(), actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void N_False_Zero()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = false;
|
||||
var actual = ws.Evaluate("=N(A1)");
|
||||
Assert.AreEqual(0, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void N_Number_Number()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
var testedValue = 123;
|
||||
ws.Cell("A1").Value = testedValue;
|
||||
var actual = ws.Evaluate("=N(A1)");
|
||||
Assert.AreEqual(testedValue, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void N_String_Zero()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = "asd";
|
||||
var actual = ws.Evaluate("=N(A1)");
|
||||
Assert.AreEqual(0, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void N_True_One()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet");
|
||||
ws.Cell("A1").Value = true;
|
||||
var actual = ws.Evaluate("=N(A1)");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
}
|
||||
#endregion N Tests
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class LogicalTests
|
||||
{
|
||||
[Test]
|
||||
public void If_2_Params_true()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr(@"if(1 = 1, ""T"")");
|
||||
Assert.AreEqual("T", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void If_2_Params_false()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr(@"if(1 = 2, ""T"")");
|
||||
Assert.AreEqual(false, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void If_3_Params_true()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr(@"if(1 = 1, ""T"", ""F"")");
|
||||
Assert.AreEqual("T", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void If_3_Params_false()
|
||||
{
|
||||
Object actual = XLWorkbook.EvaluateExpr(@"if(1 = 2, ""T"", ""F"")");
|
||||
Assert.AreEqual("F", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void If_Comparing_Against_Empty_String()
|
||||
{
|
||||
Object actual;
|
||||
actual = XLWorkbook.EvaluateExpr(@"if(date(2016, 1, 1) = """", ""A"",""B"")");
|
||||
Assert.AreEqual("B", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"if("""" = date(2016, 1, 1), ""A"",""B"")");
|
||||
Assert.AreEqual("B", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"if("""" = 123, ""A"",""B"")");
|
||||
Assert.AreEqual("B", actual);
|
||||
|
||||
actual = XLWorkbook.EvaluateExpr(@"if("""" = """", ""A"",""B"")");
|
||||
Assert.AreEqual("A", actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void If_Case_Insensitivity()
|
||||
{
|
||||
Object actual;
|
||||
actual = XLWorkbook.EvaluateExpr(@"IF(""text""=""TEXT"", 1, 2)");
|
||||
Assert.AreEqual(1, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
// Keep this file CodeMaid organised and cleaned
|
||||
using ClosedXML.Excel;
|
||||
using ClosedXML.Excel.CalcEngine.Exceptions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class LookupTests
|
||||
{
|
||||
private XLWorkbook workbook;
|
||||
|
||||
#region Setup and teardown
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Dispose()
|
||||
{
|
||||
workbook.Dispose();
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// Make sure tests run on a deterministic culture
|
||||
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
|
||||
workbook = SetupWorkbook();
|
||||
}
|
||||
|
||||
private XLWorkbook SetupWorkbook()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet("Data");
|
||||
var data = new object[]
|
||||
{
|
||||
new {Id=1, OrderDate = DateTime.Parse("2015-01-06"), Region = "East", Rep = "Jones", Item = "Pencil", Units = 95, UnitCost = 1.99, Total = 189.05 },
|
||||
new {Id=2, OrderDate = DateTime.Parse("2015-01-23"), Region = "Central", Rep = "Kivell", Item = "Binder", Units = 50, UnitCost = 19.99, Total = 999.5},
|
||||
new {Id=3, OrderDate = DateTime.Parse("2015-02-09"), Region = "Central", Rep = "Jardine", Item = "Pencil", Units = 36, UnitCost = 4.99, Total = 179.64},
|
||||
new {Id=4, OrderDate = DateTime.Parse("2015-02-26"), Region = "Central", Rep = "Gill", Item = "Pen", Units = 27, UnitCost = 19.99, Total = 539.73},
|
||||
new {Id=5, OrderDate = DateTime.Parse("2015-03-15"), Region = "West", Rep = "Sorvino", Item = "Pencil", Units = 56, UnitCost = 2.99, Total = 167.44},
|
||||
new {Id=6, OrderDate = DateTime.Parse("2015-04-01"), Region = "East", Rep = "Jones", Item = "Binder", Units = 60, UnitCost = 4.99, Total = 299.4},
|
||||
new {Id=7, OrderDate = DateTime.Parse("2015-04-18"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 75, UnitCost = 1.99, Total = 149.25},
|
||||
new {Id=8, OrderDate = DateTime.Parse("2015-05-05"), Region = "Central", Rep = "Jardine", Item = "Pencil", Units = 90, UnitCost = 4.99, Total = 449.1},
|
||||
new {Id=9, OrderDate = DateTime.Parse("2015-05-22"), Region = "West", Rep = "Thompson", Item = "Pencil", Units = 32, UnitCost = 1.99, Total = 63.68},
|
||||
new {Id=10, OrderDate = DateTime.Parse("2015-06-08"), Region = "East", Rep = "Jones", Item = "Binder", Units = 60, UnitCost = 8.99, Total = 539.4},
|
||||
new {Id=11, OrderDate = DateTime.Parse("2015-06-25"), Region = "Central", Rep = "Morgan", Item = "Pencil", Units = 90, UnitCost = 4.99, Total = 449.1},
|
||||
new {Id=12, OrderDate = DateTime.Parse("2015-07-12"), Region = "East", Rep = "Howard", Item = "Binder", Units = 29, UnitCost = 1.99, Total = 57.71},
|
||||
new {Id=13, OrderDate = DateTime.Parse("2015-07-29"), Region = "East", Rep = "Parent", Item = "Binder", Units = 81, UnitCost = 19.99, Total = 1619.19},
|
||||
new {Id=14, OrderDate = DateTime.Parse("2015-08-15"), Region = "East", Rep = "Jones", Item = "Pencil", Units = 35, UnitCost = 4.99, Total = 174.65},
|
||||
new {Id=15, OrderDate = DateTime.Parse("2015-09-01"), Region = "Central", Rep = "Smith", Item = "Desk", Units = 2, UnitCost = 125, Total = 250},
|
||||
new {Id=16, OrderDate = DateTime.Parse("2015-09-18"), Region = "East", Rep = "Jones", Item = "Pen Set", Units = 16, UnitCost = 15.99, Total = 255.84},
|
||||
new {Id=17, OrderDate = DateTime.Parse("2015-10-05"), Region = "Central", Rep = "Morgan", Item = "Binder", Units = 28, UnitCost = 8.99, Total = 251.72},
|
||||
new {Id=18, OrderDate = DateTime.Parse("2015-10-22"), Region = "East", Rep = "Jones", Item = "Pen", Units = 64, UnitCost = 8.99, Total = 575.36},
|
||||
new {Id=19, OrderDate = DateTime.Parse("2015-11-08"), Region = "East", Rep = "Parent", Item = "Pen", Units = 15, UnitCost = 19.99, Total = 299.85},
|
||||
new {Id=20, OrderDate = DateTime.Parse("2015-11-25"), Region = "Central", Rep = "Kivell", Item = "Pen Set", Units = 96, UnitCost = 4.99, Total = 479.04},
|
||||
new {Id=21, OrderDate = DateTime.Parse("2015-12-12"), Region = "Central", Rep = "Smith", Item = "Pencil", Units = 67, UnitCost = 1.29, Total = 86.43},
|
||||
new {Id=22, OrderDate = DateTime.Parse("2015-12-29"), Region = "East", Rep = "Parent", Item = "Pen Set", Units = 74, UnitCost = 15.99, Total = 1183.26},
|
||||
new {Id=23, OrderDate = DateTime.Parse("2016-01-15"), Region = "Central", Rep = "Gill", Item = "Binder", Units = 46, UnitCost = 8.99, Total = 413.54},
|
||||
new {Id=24, OrderDate = DateTime.Parse("2016-02-01"), Region = "Central", Rep = "Smith", Item = "Binder", Units = 87, UnitCost = 15, Total = 1305},
|
||||
new {Id=25, OrderDate = DateTime.Parse("2016-02-18"), Region = "East", Rep = "Jones", Item = "Binder", Units = 4, UnitCost = 4.99, Total = 19.96},
|
||||
new {Id=26, OrderDate = DateTime.Parse("2016-03-07"), Region = "West", Rep = "Sorvino", Item = "Binder", Units = 7, UnitCost = 19.99, Total = 139.93},
|
||||
new {Id=27, OrderDate = DateTime.Parse("2016-03-24"), Region = "Central", Rep = "Jardine", Item = "Pen Set", Units = 50, UnitCost = 4.99, Total = 249.5},
|
||||
new {Id=28, OrderDate = DateTime.Parse("2016-04-10"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 66, UnitCost = 1.99, Total = 131.34},
|
||||
new {Id=29, OrderDate = DateTime.Parse("2016-04-27"), Region = "East", Rep = "Howard", Item = "Pen", Units = 96, UnitCost = 4.99, Total = 479.04},
|
||||
new {Id=30, OrderDate = DateTime.Parse("2016-05-14"), Region = "Central", Rep = "Gill", Item = "Pencil", Units = 53, UnitCost = 1.29, Total = 68.37},
|
||||
new {Id=31, OrderDate = DateTime.Parse("2016-05-31"), Region = "Central", Rep = "Gill", Item = "Binder", Units = 80, UnitCost = 8.99, Total = 719.2},
|
||||
new {Id=32, OrderDate = DateTime.Parse("2016-06-17"), Region = "Central", Rep = "Kivell", Item = "Desk", Units = 5, UnitCost = 125, Total = 625},
|
||||
new {Id=33, OrderDate = DateTime.Parse("2016-07-04"), Region = "East", Rep = "Jones", Item = "Pen Set", Units = 62, UnitCost = 4.99, Total = 309.38},
|
||||
new {Id=34, OrderDate = DateTime.Parse("2016-07-21"), Region = "Central", Rep = "Morgan", Item = "Pen Set", Units = 55, UnitCost = 12.49, Total = 686.95},
|
||||
new {Id=35, OrderDate = DateTime.Parse("2016-08-07"), Region = "Central", Rep = "Kivell", Item = "Pen Set", Units = 42, UnitCost = 23.95, Total = 1005.9},
|
||||
new {Id=36, OrderDate = DateTime.Parse("2016-08-24"), Region = "West", Rep = "Sorvino", Item = "Desk", Units = 3, UnitCost = 275, Total = 825},
|
||||
new {Id=37, OrderDate = DateTime.Parse("2016-09-10"), Region = "Central", Rep = "Gill", Item = "Pencil", Units = 7, UnitCost = 1.29, Total = 9.03},
|
||||
new {Id=38, OrderDate = DateTime.Parse("2016-09-27"), Region = "West", Rep = "Sorvino", Item = "Pen", Units = 76, UnitCost = 1.99, Total = 151.24},
|
||||
new {Id=39, OrderDate = DateTime.Parse("2016-10-14"), Region = "West", Rep = "Thompson", Item = "Binder", Units = 57, UnitCost = 19.99, Total = 1139.43},
|
||||
new {Id=40, OrderDate = DateTime.Parse("2016-10-31"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 14, UnitCost = 1.29, Total = 18.06},
|
||||
new {Id=41, OrderDate = DateTime.Parse("2016-11-17"), Region = "Central", Rep = "Jardine", Item = "Binder", Units = 11, UnitCost = 4.99, Total = 54.89},
|
||||
new {Id=42, OrderDate = DateTime.Parse("2016-12-04"), Region = "Central", Rep = "Jardine", Item = "Binder", Units = 94, UnitCost = 19.99, Total = 1879.06},
|
||||
new {Id=43, OrderDate = DateTime.Parse("2016-12-21"), Region = "Central", Rep = "Andrews", Item = "Binder", Units = 28, UnitCost = 4.99, Total = 139.72}
|
||||
};
|
||||
ws.FirstCell()
|
||||
.CellBelow()
|
||||
.CellRight()
|
||||
.InsertTable(data);
|
||||
|
||||
return wb;
|
||||
}
|
||||
|
||||
#endregion Setup and teardown
|
||||
|
||||
[Test]
|
||||
public void Hlookup()
|
||||
{
|
||||
// Range lookup false
|
||||
var value = workbook.Evaluate(@"=HLOOKUP(""Total"",Data!$B$2:$I$71,4,FALSE)");
|
||||
Assert.AreEqual(179.64, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Hyperlink()
|
||||
{
|
||||
XLHyperlink hl;
|
||||
hl = XLWorkbook.EvaluateExpr("HYPERLINK(\"http://github.com/ClosedXML/ClosedXML\")") as XLHyperlink;
|
||||
Assert.IsNotNull(hl);
|
||||
Assert.AreEqual("http://github.com/ClosedXML/ClosedXML", hl.ExternalAddress.ToString());
|
||||
Assert.AreEqual(string.Empty, hl.Tooltip);
|
||||
|
||||
hl = XLWorkbook.EvaluateExpr("HYPERLINK(\"mailto:jsmith@github.com\", \"jsmith@github.com\")") as XLHyperlink;
|
||||
Assert.IsNotNull(hl);
|
||||
Assert.AreEqual("mailto:jsmith@github.com", hl.ExternalAddress.ToString());
|
||||
Assert.AreEqual("jsmith@github.com", hl.Tooltip);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Index()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
Assert.AreEqual("Kivell", ws.Evaluate(@"=INDEX(B2:J12, 3, 4)"));
|
||||
|
||||
// We don't support optional parameter fully here yet.
|
||||
// Supposedly, if you omit e.g. the row number, then ROW() of the calling cell should be assumed
|
||||
// Assert.AreEqual("Gill", ws.Evaluate(@"=INDEX(B2:J12, , 4)"));
|
||||
|
||||
Assert.AreEqual("Rep", ws.Evaluate(@"=INDEX(B2:I2, 4)"));
|
||||
|
||||
Assert.AreEqual(3, ws.Evaluate(@"=INDEX(B2:B20, 4)"));
|
||||
Assert.AreEqual(3, ws.Evaluate(@"=INDEX(B2:B20, 4, 1)"));
|
||||
Assert.AreEqual(3, ws.Evaluate(@"=INDEX(B2:B20, 4, )"));
|
||||
|
||||
Assert.AreEqual("Rep", ws.Evaluate(@"=INDEX(B2:J2, 1, 4)"));
|
||||
Assert.AreEqual("Rep", ws.Evaluate(@"=INDEX(B2:J2, , 4)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Index_Exceptions()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:I10, 20, 1)"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:I10, 1, 10)"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:I2, 10)"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:I2, 4, 1)"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:I2, 4, )"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:B10, 20)"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:B10, 20, )"));
|
||||
Assert.Throws<CellReferenceException>(() => ws.Evaluate(@"INDEX(B2:B10, , 4)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Match()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
|
||||
Object value;
|
||||
value = ws.Evaluate(@"=MATCH(""Rep"", B2:I2, 0)");
|
||||
Assert.AreEqual(4, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""Rep"", A2:Z2, 0)");
|
||||
Assert.AreEqual(5, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""REP"", B2:I2, 0)");
|
||||
Assert.AreEqual(4, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(95, B3:I3, 0)");
|
||||
Assert.AreEqual(6, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(DATE(2015,1,6), B3:I3, 0)");
|
||||
Assert.AreEqual(2, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(1.99, 3:3, 0)");
|
||||
Assert.AreEqual(8, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(43, B:B, 0)");
|
||||
Assert.AreEqual(45, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""cENtraL"", D3:D45, 0)");
|
||||
Assert.AreEqual(2, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(4.99, H:H, 0)");
|
||||
Assert.AreEqual(5, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""Rapture"", B2:I2, 1)");
|
||||
Assert.AreEqual(2, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(22.5, B3:B45, 1)");
|
||||
Assert.AreEqual(22, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""Rep"", B2:I2)");
|
||||
Assert.AreEqual(4, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(""Rep"", B2:I2, 1)");
|
||||
Assert.AreEqual(4, value);
|
||||
|
||||
value = ws.Evaluate(@"=MATCH(40, G3:G6, -1)");
|
||||
Assert.AreEqual(2, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Match_Exceptions()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
Assert.Throws<CellValueException>(() => ws.Evaluate(@"=MATCH(""Rep"", B2:I5)"));
|
||||
Assert.Throws<NoValueAvailableException>(() => ws.Evaluate(@"=MATCH(""Dummy"", B2:I2, 0)"));
|
||||
Assert.Throws<NoValueAvailableException>(() => ws.Evaluate(@"=MATCH(4.5,B3:B45,-1)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Vlookup()
|
||||
{
|
||||
// Range lookup false
|
||||
var value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,3,FALSE)");
|
||||
Assert.AreEqual("Central", value);
|
||||
|
||||
value = workbook.Evaluate("=VLOOKUP(DATE(2015,5,22),Data!C:I,7,FALSE)");
|
||||
Assert.AreEqual(63.68, value);
|
||||
|
||||
value = workbook.Evaluate(@"=VLOOKUP(""Central"",Data!D:E,2,FALSE)");
|
||||
Assert.AreEqual("Kivell", value);
|
||||
|
||||
// Case insensitive lookup
|
||||
value = workbook.Evaluate(@"=VLOOKUP(""central"",Data!D:E,2,FALSE)");
|
||||
Assert.AreEqual("Kivell", value);
|
||||
|
||||
// Range lookup true
|
||||
value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,TRUE)");
|
||||
Assert.AreEqual(179.64, value);
|
||||
|
||||
value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8)");
|
||||
Assert.AreEqual(179.64, value);
|
||||
|
||||
value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,)");
|
||||
Assert.AreEqual(179.64, value);
|
||||
|
||||
value = workbook.Evaluate("=VLOOKUP(14.5,Data!$B$2:$I$71,8,TRUE)");
|
||||
Assert.AreEqual(174.65, value);
|
||||
|
||||
value = workbook.Evaluate("=VLOOKUP(50,Data!$B$2:$I$71,8,TRUE)");
|
||||
Assert.AreEqual(139.72, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Vlookup_Exceptions()
|
||||
{
|
||||
Assert.Throws<NoValueAvailableException>(() => workbook.Evaluate(@"=VLOOKUP("""",Data!$B$2:$I$71,3,FALSE)"));
|
||||
Assert.Throws<NoValueAvailableException>(() => workbook.Evaluate(@"=VLOOKUP(50,Data!$B$2:$I$71,3,FALSE)"));
|
||||
Assert.Throws<NoValueAvailableException>(() => workbook.Evaluate(@"=VLOOKUP(-1,Data!$B$2:$I$71,2,TRUE)"));
|
||||
|
||||
Assert.Throws<CellReferenceException>(() => workbook.Evaluate(@"=VLOOKUP(20,Data!$B$2:$I$71,9,FALSE)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class PrecedentCellsTests
|
||||
{
|
||||
[Test]
|
||||
public void GetPrecedentRangesPreventsDuplication()
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var sheet1 = wb.AddWorksheet("Sheet1") as XLWorksheet;
|
||||
var sheet2 = wb.AddWorksheet("Sheet2");
|
||||
var formula = "=MAX(A2:E2)/COUNTBLANK(A2:E2)*MAX(B1:C3)+SUM(Sheet2!B1:C3)+SUM($A$2:$E$2)+A2+B$2+$C$2";
|
||||
|
||||
var ranges = sheet1.CalcEngine.GetPrecedentRanges(formula);
|
||||
|
||||
Assert.AreEqual(6, ranges.Count());
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet1" && r.RangeAddress.ToString() == "A2:E2"));
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet1" && r.RangeAddress.ToString() == "B1:C3"));
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet2" && r.RangeAddress.ToString() == "B1:C3"));
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet1" && r.RangeAddress.ToString() == "A2:A2"));
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet1" && r.RangeAddress.ToString() == "B$2:B$2"));
|
||||
Assert.IsTrue(ranges.Any(r => r.RangeAddress.Worksheet.Name == "Sheet1" && r.RangeAddress.ToString() == "$C$2:$C$2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPrecedentRangesDealsWithNamedRanges()
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var sheet1 = wb.AddWorksheet("Sheet1") as XLWorksheet;
|
||||
sheet1.NamedRanges.Add("NAMED_RANGE", sheet1.Range("A2:B3"));
|
||||
var formula = "=SUM(NAMED_RANGE)";
|
||||
|
||||
var ranges = sheet1.CalcEngine.GetPrecedentRanges(formula);
|
||||
|
||||
Assert.AreEqual(1, ranges.Count());
|
||||
Assert.AreEqual("$A$2:$B$3", ranges.First().RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPrecedentCells()
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var sheet1 = wb.AddWorksheet("Sheet1") as XLWorksheet;
|
||||
var sheet2 = wb.AddWorksheet("Sheet2");
|
||||
var formula = "=MAX(A2:E2)/COUNTBLANK(A2:E2)*MAX(B1:C3)+SUM(Sheet2!B1:C3)+SUM($A$2:$E$2)+A2+B$2+$C$2";
|
||||
var expectedAtSheet1 = new string[]
|
||||
{ "A2", "B2", "C2", "D2", "E2", "B1", "C1", "B3", "C3" };
|
||||
var expectedAtSheet2 = new string[]
|
||||
{ "B1", "C1", "B2", "C2", "B3", "C3" };
|
||||
|
||||
var cells = sheet1.CalcEngine.GetPrecedentCells(formula);
|
||||
|
||||
Assert.AreEqual(15, cells.Count());
|
||||
foreach (var address in expectedAtSheet1)
|
||||
{
|
||||
Assert.IsTrue(cells.Any(cell => cell.Address.Worksheet.Name == sheet1.Name && cell.Address.ToString() == address),
|
||||
string.Format("Address {0}!{1} is not presented", sheet1.Name, address));
|
||||
}
|
||||
foreach (var address in expectedAtSheet2)
|
||||
{
|
||||
Assert.IsTrue(cells.Any(cell => cell.Address.Worksheet.Name == sheet2.Name && cell.Address.ToString() == address),
|
||||
string.Format("Address {0}!{1} is not presented", sheet2.Name, address));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
// Keep this file CodeMaid organised and cleaned
|
||||
using ClosedXML.Excel;
|
||||
using ClosedXML.Excel.CalcEngine;
|
||||
using ClosedXML.Excel.CalcEngine.Exceptions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
[TestFixture]
|
||||
public class StatisticalTests
|
||||
{
|
||||
private double tolerance = 1e-6;
|
||||
private XLWorkbook workbook;
|
||||
|
||||
[Test]
|
||||
public void Average()
|
||||
{
|
||||
double value;
|
||||
value = workbook.Evaluate("AVERAGE(-27.5,93.93,64.51,-70.56)").CastTo<double>();
|
||||
Assert.AreEqual(15.095, value, tolerance);
|
||||
|
||||
var ws = workbook.Worksheets.First();
|
||||
value = ws.Evaluate("AVERAGE(G3:G45)").CastTo<double>();
|
||||
Assert.AreEqual(49.3255814, value, tolerance);
|
||||
|
||||
Assert.That(() => ws.Evaluate("AVERAGE(D3:D45)"), Throws.TypeOf<ApplicationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Count()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=COUNT(D3:D45)").CastTo<int>();
|
||||
Assert.AreEqual(0, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNT(G3:G45)").CastTo<int>();
|
||||
Assert.AreEqual(43, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNT(G:G)").CastTo<int>();
|
||||
Assert.AreEqual(43, value);
|
||||
|
||||
value = workbook.Evaluate(@"=COUNT(Data!G:G)").CastTo<int>();
|
||||
Assert.AreEqual(43, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountA()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=COUNTA(D3:D45)").CastTo<int>();
|
||||
Assert.AreEqual(43, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTA(G3:G45)").CastTo<int>();
|
||||
Assert.AreEqual(43, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTA(G:G)").CastTo<int>();
|
||||
Assert.AreEqual(44, value);
|
||||
|
||||
value = workbook.Evaluate(@"=COUNTA(Data!G:G)").CastTo<int>();
|
||||
Assert.AreEqual(44, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountBlank()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=COUNTBLANK(B:B)").CastTo<int>();
|
||||
Assert.AreEqual(1048532, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTBLANK(D43:D49)").CastTo<int>();
|
||||
Assert.AreEqual(4, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTBLANK(E3:E45)").CastTo<int>();
|
||||
Assert.AreEqual(0, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTBLANK(A1)").CastTo<int>();
|
||||
Assert.AreEqual(1, value);
|
||||
|
||||
Assert.Throws<NoValueAvailableException>(() => workbook.Evaluate(@"=COUNTBLANK(E3:E45)"));
|
||||
Assert.Throws<ExpressionParseException>(() => ws.Evaluate(@"=COUNTBLANK()"));
|
||||
Assert.Throws<ExpressionParseException>(() => ws.Evaluate(@"=COUNTBLANK(A3:A45,E3:E45)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountIf()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=COUNTIF(D3:D45,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTIF(D:D,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
|
||||
value = workbook.Evaluate(@"=COUNTIF(Data!D:D,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
}
|
||||
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""J*"")", 13)]
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""*i*"")", 21)]
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""*in*"")", 9)]
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""*i*l"")", 9)]
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""*i?e*"")", 9)]
|
||||
[TestCase(@"=COUNTIF(Data!E:E, ""*o??s*"")", 10)]
|
||||
[TestCase(@"=COUNTIF(Data!X1:X1000, """")", 1000)]
|
||||
[TestCase(@"=COUNTIF(Data!E1:E44, """")", 1)]
|
||||
public void CountIf_ConditionWithWildcards(string formula, int expectedResult)
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
|
||||
int value = ws.Evaluate(formula).CastTo<int>();
|
||||
Assert.AreEqual(expectedResult, value);
|
||||
}
|
||||
|
||||
[TestCase(@"=COUNTIF(A1:A10, 1)", 1)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, 2.0)", 1)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, ""3"")", 2)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, 3)", 2)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, 43831)", 1)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, DATE(2020, 1, 1))", 1)]
|
||||
[TestCase(@"=COUNTIF(A1:A10, TRUE)", 1)]
|
||||
public void CountIf_MixedData(string formula, int expected)
|
||||
{
|
||||
// We follow to Excel's convention.
|
||||
// Excel treats 1 and TRUE as unequal, but 3 and "3" as equal
|
||||
// LibreOffice Calc handles some SUMIF and COUNTIF differently, e.g. it treats 1 and TRUE as equal, but 3 and "3" differently
|
||||
var ws = workbook.Worksheet("MixedData");
|
||||
Assert.AreEqual(expected, ws.Evaluate(formula));
|
||||
}
|
||||
|
||||
[TestCase("x", @"=COUNTIF(A1:A1, ""?"")", 1)]
|
||||
[TestCase("x", @"=COUNTIF(A1:A1, ""~?"")", 0)]
|
||||
[TestCase("?", @"=COUNTIF(A1:A1, ""~?"")", 1)]
|
||||
[TestCase("~?", @"=COUNTIF(A1:A1, ""~?"")", 0)]
|
||||
[TestCase("~?", @"=COUNTIF(A1:A1, ""~~~?"")", 1)]
|
||||
[TestCase("?", @"=COUNTIF(A1:A1, ""~~?"")", 0)]
|
||||
[TestCase("~?", @"=COUNTIF(A1:A1, ""~~?"")", 1)]
|
||||
[TestCase("~x", @"=COUNTIF(A1:A1, ""~~?"")", 1)]
|
||||
[TestCase("*", @"=COUNTIF(A1:A1, ""~*"")", 1)]
|
||||
[TestCase("~*", @"=COUNTIF(A1:A1, ""~*"")", 0)]
|
||||
[TestCase("~*", @"=COUNTIF(A1:A1, ""~~~*"")", 1)]
|
||||
[TestCase("*", @"=COUNTIF(A1:A1, ""~~*"")", 0)]
|
||||
[TestCase("~*", @"=COUNTIF(A1:A1, ""~~*"")", 1)]
|
||||
[TestCase("~x", @"=COUNTIF(A1:A1, ""~~*"")", 1)]
|
||||
[TestCase("~xyz", @"=COUNTIF(A1:A1, ""~~*"")", 1)]
|
||||
public void CountIf_MoreWildcards(string cellContent, string formula, int expectedResult)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
ws.Cell(1, 1).Value = cellContent;
|
||||
|
||||
Assert.AreEqual(expectedResult, (double)ws.Evaluate(formula));
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("=COUNTIFS(B1:D1, \"=Yes\")", 1)]
|
||||
[TestCase("=COUNTIFS(B1:B4, \"=Yes\", C1:C4, \"=Yes\")", 2)]
|
||||
[TestCase("= COUNTIFS(B4:D4, \"=Yes\", B2:D2, \"=Yes\")", 1)]
|
||||
public void CountIfs_ReferenceExample1FromExcelDocumentations(
|
||||
string formula,
|
||||
int expectedOutcome)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
wb.ReferenceStyle = XLReferenceStyle.A1;
|
||||
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
ws.Cell(1, 1).Value = "Davidoski";
|
||||
ws.Cell(1, 2).Value = "Yes";
|
||||
ws.Cell(1, 3).Value = "No";
|
||||
ws.Cell(1, 4).Value = "No";
|
||||
|
||||
ws.Cell(2, 1).Value = "Burke";
|
||||
ws.Cell(2, 2).Value = "Yes";
|
||||
ws.Cell(2, 3).Value = "Yes";
|
||||
ws.Cell(2, 4).Value = "No";
|
||||
|
||||
ws.Cell(3, 1).Value = "Sundaram";
|
||||
ws.Cell(3, 2).Value = "Yes";
|
||||
ws.Cell(3, 3).Value = "Yes";
|
||||
ws.Cell(3, 4).Value = "Yes";
|
||||
|
||||
ws.Cell(4, 1).Value = "Levitan";
|
||||
ws.Cell(4, 2).Value = "No";
|
||||
ws.Cell(4, 3).Value = "Yes";
|
||||
ws.Cell(4, 4).Value = "Yes";
|
||||
|
||||
Assert.AreEqual(expectedOutcome, ws.Evaluate(formula));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountIfs_SingleCondition()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=COUNTIFS(D3:D45,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
|
||||
value = ws.Evaluate(@"=COUNTIFS(D:D,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
|
||||
value = workbook.Evaluate(@"=COUNTIFS(Data!D:D,""Central"")").CastTo<int>();
|
||||
Assert.AreEqual(24, value);
|
||||
}
|
||||
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""J*"")", 13)]
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""*i*"")", 21)]
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""*in*"")", 9)]
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""*i*l"")", 9)]
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""*i?e*"")", 9)]
|
||||
[TestCase(@"=COUNTIFS(Data!E:E, ""*o??s*"")", 10)]
|
||||
[TestCase(@"=COUNTIFS(Data!X1:X1000, """")", 1000)]
|
||||
[TestCase(@"=COUNTIFS(Data!E1:E44, """")", 1)]
|
||||
public void CountIfs_SingleConditionWithWildcards(string formula, int expectedResult)
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
|
||||
int value = ws.Evaluate(formula).CastTo<int>();
|
||||
Assert.AreEqual(expectedResult, value);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Dispose()
|
||||
{
|
||||
workbook.Dispose();
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// Make sure tests run on a deterministic culture
|
||||
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
|
||||
workbook = SetupWorkbook();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Max()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=MAX(D3:D45)").CastTo<int>();
|
||||
Assert.AreEqual(0, value);
|
||||
|
||||
value = ws.Evaluate(@"=MAX(G3:G45)").CastTo<int>();
|
||||
Assert.AreEqual(96, value);
|
||||
|
||||
value = ws.Evaluate(@"=MAX(G:G)").CastTo<int>();
|
||||
Assert.AreEqual(96, value);
|
||||
|
||||
value = workbook.Evaluate(@"=MAX(Data!G:G)").CastTo<int>();
|
||||
Assert.AreEqual(96, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Min()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int value;
|
||||
value = ws.Evaluate(@"=MIN(D3:D45)").CastTo<int>();
|
||||
Assert.AreEqual(0, value);
|
||||
|
||||
value = ws.Evaluate(@"=MIN(G3:G45)").CastTo<int>();
|
||||
Assert.AreEqual(2, value);
|
||||
|
||||
value = ws.Evaluate(@"=MIN(G:G)").CastTo<int>();
|
||||
Assert.AreEqual(2, value);
|
||||
|
||||
value = workbook.Evaluate(@"=MIN(Data!G:G)").CastTo<int>();
|
||||
Assert.AreEqual(2, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StDev()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
double value;
|
||||
Assert.That(() => ws.Evaluate(@"=STDEV(D3:D45)"), Throws.TypeOf<ApplicationException>());
|
||||
|
||||
value = ws.Evaluate(@"=STDEV(H3:H45)").CastTo<double>();
|
||||
Assert.AreEqual(47.34511769, value, tolerance);
|
||||
|
||||
value = ws.Evaluate(@"=STDEV(H:H)").CastTo<double>();
|
||||
Assert.AreEqual(47.34511769, value, tolerance);
|
||||
|
||||
value = workbook.Evaluate(@"=STDEV(Data!H:H)").CastTo<double>();
|
||||
Assert.AreEqual(47.34511769, value, tolerance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StDevP()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
double value;
|
||||
Assert.That(() => ws.Evaluate(@"=STDEVP(D3:D45)"), Throws.InvalidOperationException);
|
||||
|
||||
value = ws.Evaluate(@"=STDEVP(H3:H45)").CastTo<double>();
|
||||
Assert.AreEqual(46.79135458, value, tolerance);
|
||||
|
||||
value = ws.Evaluate(@"=STDEVP(H:H)").CastTo<double>();
|
||||
Assert.AreEqual(46.79135458, value, tolerance);
|
||||
|
||||
value = workbook.Evaluate(@"=STDEVP(Data!H:H)").CastTo<double>();
|
||||
Assert.AreEqual(46.79135458, value, tolerance);
|
||||
}
|
||||
|
||||
[TestCase(@"=SUMIF(A1:A10, 1, A1:A10)", 1)]
|
||||
[TestCase(@"=SUMIF(A1:A10, 2.0, A1:A10)", 2)]
|
||||
[TestCase(@"=SUMIF(A1:A10, 3, A1:A10)", 3)]
|
||||
[TestCase(@"=SUMIF(A1:A10, ""3"", A1:A10)", 3)]
|
||||
[TestCase(@"=SUMIF(A1:A10, 43831, A1:A10)", 43831)]
|
||||
[TestCase(@"=SUMIF(A1:A10, DATE(2020, 1, 1), A1:A10)", 43831)]
|
||||
[TestCase(@"=SUMIF(A1:A10, TRUE, A1:A10)", 0)]
|
||||
public void SumIf_MixedData(string formula, double expected)
|
||||
{
|
||||
// We follow to Excel's convention.
|
||||
// Excel treats 1 and TRUE as unequal, but 3 and "3" as equal
|
||||
// LibreOffice Calc handles some SUMIF and COUNTIF differently, e.g. it treats 1 and TRUE as equal, but 3 and "3" differently
|
||||
var ws = workbook.Worksheet("MixedData");
|
||||
Assert.AreEqual(expected, ws.Evaluate(formula));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("COUNT(G:I,G:G,H:I)", 258d, Description = "COUNT overlapping columns")]
|
||||
[TestCase("COUNT(6:8,6:6,7:8)", 30d, Description = "COUNT overlapping rows")]
|
||||
[TestCase("COUNTBLANK(H:J)", 3145640d, Description = "COUNTBLANK columns")]
|
||||
[TestCase("COUNTBLANK(7:9)", 49128d, Description = "COUNTBLANK rows")]
|
||||
[TestCase("COUNT(1:1048576)", 216d, Description = "COUNT worksheet")]
|
||||
[TestCase("COUNTBLANK(1:1048576)", 17179868831d, Description = "COUNTBLANK worksheet")]
|
||||
[TestCase("SUM(H:J)", 20501.15d, Description = "SUM columns")]
|
||||
[TestCase("SUM(4:5)", 85366.12d, Description = "SUM rows")]
|
||||
[TestCase("SUMIF(G:G,50,H:H)", 24.98d, Description = "SUMIF columns")]
|
||||
[TestCase("SUMIF(G23:G52,\"\",H3:H32)", 53.24d, Description = "SUMIF ranges")]
|
||||
[TestCase("SUMIFS(H:H,G:G,50,I:I,\">900\")", 19.99d, Description = "SUMIFS columns")]
|
||||
public void TallySkipsEmptyCells(string formulaA1, double expectedResult)
|
||||
{
|
||||
using (var wb = SetupWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.First();
|
||||
//Let's pre-initialize cells we need so they didn't affect the result
|
||||
ws.Range("A1:J45").Style.Fill.BackgroundColor = XLColor.Amber;
|
||||
ws.Cell("ZZ1000").Value = 1;
|
||||
int initialCount = (ws as XLWorksheet).Internals.CellsCollection.Count;
|
||||
|
||||
var actualResult = (double)ws.Evaluate(formulaA1);
|
||||
int cellsCount = (ws as XLWorksheet).Internals.CellsCollection.Count;
|
||||
|
||||
Assert.AreEqual(expectedResult, actualResult, tolerance);
|
||||
Assert.AreEqual(initialCount, cellsCount);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Var()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
double value;
|
||||
Assert.That(() => ws.Evaluate(@"=VAR(D3:D45)"), Throws.InvalidOperationException);
|
||||
|
||||
value = ws.Evaluate(@"=VAR(H3:H45)").CastTo<double>();
|
||||
Assert.AreEqual(2241.560169, value, tolerance);
|
||||
|
||||
value = ws.Evaluate(@"=VAR(H:H)").CastTo<double>();
|
||||
Assert.AreEqual(2241.560169, value, tolerance);
|
||||
|
||||
value = workbook.Evaluate(@"=VAR(Data!H:H)").CastTo<double>();
|
||||
Assert.AreEqual(2241.560169, value, tolerance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VarP()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
double value;
|
||||
Assert.That(() => ws.Evaluate(@"=VARP(D3:D45)"), Throws.InvalidOperationException);
|
||||
|
||||
value = ws.Evaluate(@"=VARP(H3:H45)").CastTo<double>();
|
||||
Assert.AreEqual(2189.430863, value, tolerance);
|
||||
|
||||
value = ws.Evaluate(@"=VARP(H:H)").CastTo<double>();
|
||||
Assert.AreEqual(2189.430863, value, tolerance);
|
||||
|
||||
value = workbook.Evaluate(@"=VARP(Data!H:H)").CastTo<double>();
|
||||
Assert.AreEqual(2189.430863, value, tolerance);
|
||||
}
|
||||
|
||||
private XLWorkbook SetupWorkbook()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws1 = wb.AddWorksheet("Data");
|
||||
var data = new object[]
|
||||
{
|
||||
new {Id=1, OrderDate = DateTime.Parse("2015-01-06"), Region = "East", Rep = "Jones", Item = "Pencil", Units = 95, UnitCost = 1.99, Total = 189.05 },
|
||||
new {Id=2, OrderDate = DateTime.Parse("2015-01-23"), Region = "Central", Rep = "Kivell", Item = "Binder", Units = 50, UnitCost = 19.99, Total = 999.5},
|
||||
new {Id=3, OrderDate = DateTime.Parse("2015-02-09"), Region = "Central", Rep = "Jardine", Item = "Pencil", Units = 36, UnitCost = 4.99, Total = 179.64},
|
||||
new {Id=4, OrderDate = DateTime.Parse("2015-02-26"), Region = "Central", Rep = "Gill", Item = "Pen", Units = 27, UnitCost = 19.99, Total = 539.73},
|
||||
new {Id=5, OrderDate = DateTime.Parse("2015-03-15"), Region = "West", Rep = "Sorvino", Item = "Pencil", Units = 56, UnitCost = 2.99, Total = 167.44},
|
||||
new {Id=6, OrderDate = DateTime.Parse("2015-04-01"), Region = "East", Rep = "Jones", Item = "Binder", Units = 60, UnitCost = 4.99, Total = 299.4},
|
||||
new {Id=7, OrderDate = DateTime.Parse("2015-04-18"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 75, UnitCost = 1.99, Total = 149.25},
|
||||
new {Id=8, OrderDate = DateTime.Parse("2015-05-05"), Region = "Central", Rep = "Jardine", Item = "Pencil", Units = 90, UnitCost = 4.99, Total = 449.1},
|
||||
new {Id=9, OrderDate = DateTime.Parse("2015-05-22"), Region = "West", Rep = "Thompson", Item = "Pencil", Units = 32, UnitCost = 1.99, Total = 63.68},
|
||||
new {Id=10, OrderDate = DateTime.Parse("2015-06-08"), Region = "East", Rep = "Jones", Item = "Binder", Units = 60, UnitCost = 8.99, Total = 539.4},
|
||||
new {Id=11, OrderDate = DateTime.Parse("2015-06-25"), Region = "Central", Rep = "Morgan", Item = "Pencil", Units = 90, UnitCost = 4.99, Total = 449.1},
|
||||
new {Id=12, OrderDate = DateTime.Parse("2015-07-12"), Region = "East", Rep = "Howard", Item = "Binder", Units = 29, UnitCost = 1.99, Total = 57.71},
|
||||
new {Id=13, OrderDate = DateTime.Parse("2015-07-29"), Region = "East", Rep = "Parent", Item = "Binder", Units = 81, UnitCost = 19.99, Total = 1619.19},
|
||||
new {Id=14, OrderDate = DateTime.Parse("2015-08-15"), Region = "East", Rep = "Jones", Item = "Pencil", Units = 35, UnitCost = 4.99, Total = 174.65},
|
||||
new {Id=15, OrderDate = DateTime.Parse("2015-09-01"), Region = "Central", Rep = "Smith", Item = "Desk", Units = 2, UnitCost = 125, Total = 250},
|
||||
new {Id=16, OrderDate = DateTime.Parse("2015-09-18"), Region = "East", Rep = "Jones", Item = "Pen Set", Units = 16, UnitCost = 15.99, Total = 255.84},
|
||||
new {Id=17, OrderDate = DateTime.Parse("2015-10-05"), Region = "Central", Rep = "Morgan", Item = "Binder", Units = 28, UnitCost = 8.99, Total = 251.72},
|
||||
new {Id=18, OrderDate = DateTime.Parse("2015-10-22"), Region = "East", Rep = "Jones", Item = "Pen", Units = 64, UnitCost = 8.99, Total = 575.36},
|
||||
new {Id=19, OrderDate = DateTime.Parse("2015-11-08"), Region = "East", Rep = "Parent", Item = "Pen", Units = 15, UnitCost = 19.99, Total = 299.85},
|
||||
new {Id=20, OrderDate = DateTime.Parse("2015-11-25"), Region = "Central", Rep = "Kivell", Item = "Pen Set", Units = 96, UnitCost = 4.99, Total = 479.04},
|
||||
new {Id=21, OrderDate = DateTime.Parse("2015-12-12"), Region = "Central", Rep = "Smith", Item = "Pencil", Units = 67, UnitCost = 1.29, Total = 86.43},
|
||||
new {Id=22, OrderDate = DateTime.Parse("2015-12-29"), Region = "East", Rep = "Parent", Item = "Pen Set", Units = 74, UnitCost = 15.99, Total = 1183.26},
|
||||
new {Id=23, OrderDate = DateTime.Parse("2016-01-15"), Region = "Central", Rep = "Gill", Item = "Binder", Units = 46, UnitCost = 8.99, Total = 413.54},
|
||||
new {Id=24, OrderDate = DateTime.Parse("2016-02-01"), Region = "Central", Rep = "Smith", Item = "Binder", Units = 87, UnitCost = 15, Total = 1305},
|
||||
new {Id=25, OrderDate = DateTime.Parse("2016-02-18"), Region = "East", Rep = "Jones", Item = "Binder", Units = 4, UnitCost = 4.99, Total = 19.96},
|
||||
new {Id=26, OrderDate = DateTime.Parse("2016-03-07"), Region = "West", Rep = "Sorvino", Item = "Binder", Units = 7, UnitCost = 19.99, Total = 139.93},
|
||||
new {Id=27, OrderDate = DateTime.Parse("2016-03-24"), Region = "Central", Rep = "Jardine", Item = "Pen Set", Units = 50, UnitCost = 4.99, Total = 249.5},
|
||||
new {Id=28, OrderDate = DateTime.Parse("2016-04-10"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 66, UnitCost = 1.99, Total = 131.34},
|
||||
new {Id=29, OrderDate = DateTime.Parse("2016-04-27"), Region = "East", Rep = "Howard", Item = "Pen", Units = 96, UnitCost = 4.99, Total = 479.04},
|
||||
new {Id=30, OrderDate = DateTime.Parse("2016-05-14"), Region = "Central", Rep = "Gill", Item = "Pencil", Units = 53, UnitCost = 1.29, Total = 68.37},
|
||||
new {Id=31, OrderDate = DateTime.Parse("2016-05-31"), Region = "Central", Rep = "Gill", Item = "Binder", Units = 80, UnitCost = 8.99, Total = 719.2},
|
||||
new {Id=32, OrderDate = DateTime.Parse("2016-06-17"), Region = "Central", Rep = "Kivell", Item = "Desk", Units = 5, UnitCost = 125, Total = 625},
|
||||
new {Id=33, OrderDate = DateTime.Parse("2016-07-04"), Region = "East", Rep = "Jones", Item = "Pen Set", Units = 62, UnitCost = 4.99, Total = 309.38},
|
||||
new {Id=34, OrderDate = DateTime.Parse("2016-07-21"), Region = "Central", Rep = "Morgan", Item = "Pen Set", Units = 55, UnitCost = 12.49, Total = 686.95},
|
||||
new {Id=35, OrderDate = DateTime.Parse("2016-08-07"), Region = "Central", Rep = "Kivell", Item = "Pen Set", Units = 42, UnitCost = 23.95, Total = 1005.9},
|
||||
new {Id=36, OrderDate = DateTime.Parse("2016-08-24"), Region = "West", Rep = "Sorvino", Item = "Desk", Units = 3, UnitCost = 275, Total = 825},
|
||||
new {Id=37, OrderDate = DateTime.Parse("2016-09-10"), Region = "Central", Rep = "Gill", Item = "Pencil", Units = 7, UnitCost = 1.29, Total = 9.03},
|
||||
new {Id=38, OrderDate = DateTime.Parse("2016-09-27"), Region = "West", Rep = "Sorvino", Item = "Pen", Units = 76, UnitCost = 1.99, Total = 151.24},
|
||||
new {Id=39, OrderDate = DateTime.Parse("2016-10-14"), Region = "West", Rep = "Thompson", Item = "Binder", Units = 57, UnitCost = 19.99, Total = 1139.43},
|
||||
new {Id=40, OrderDate = DateTime.Parse("2016-10-31"), Region = "Central", Rep = "Andrews", Item = "Pencil", Units = 14, UnitCost = 1.29, Total = 18.06},
|
||||
new {Id=41, OrderDate = DateTime.Parse("2016-11-17"), Region = "Central", Rep = "Jardine", Item = "Binder", Units = 11, UnitCost = 4.99, Total = 54.89},
|
||||
new {Id=42, OrderDate = DateTime.Parse("2016-12-04"), Region = "Central", Rep = "Jardine", Item = "Binder", Units = 94, UnitCost = 19.99, Total = 1879.06},
|
||||
new {Id=43, OrderDate = DateTime.Parse("2016-12-21"), Region = "Central", Rep = "Andrews", Item = "Binder", Units = 28, UnitCost = 4.99, Total = 139.72}
|
||||
};
|
||||
|
||||
ws1.FirstCell()
|
||||
.CellBelow()
|
||||
.CellRight()
|
||||
.InsertTable(data, "Table1");
|
||||
|
||||
var ws2 = wb.AddWorksheet("MixedData");
|
||||
ws2.FirstCell().InsertData(new object[] { 1, 2.0, "3", 3, new DateTime(2020, 1, 1), true, new TimeSpan(10, 5, 30, 10) });
|
||||
|
||||
return wb;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,26 @@
|
||||
using ClosedXML.Excel.CalcEngine.Functions;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.CalcEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for UnitTest1
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class XLMathTests
|
||||
{
|
||||
[Test]
|
||||
public void IsEven()
|
||||
{
|
||||
Assert.IsTrue(XLMath.IsEven(2));
|
||||
Assert.IsFalse(XLMath.IsEven(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsOdd()
|
||||
{
|
||||
Assert.IsTrue(XLMath.IsOdd(3));
|
||||
Assert.IsFalse(XLMath.IsOdd(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user