diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Expression.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Expression.cs index 30f9b7f..cea5599 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Expression.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Expression.cs @@ -473,6 +473,8 @@ _value = value; } + public object Value { get { return _value; } } + // ** object model public override object Evaluate() { diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs index e30ecb1..2a13691 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs @@ -41,7 +41,7 @@ ce.RegisterFunction("LOG10", 1, Log10); //ce.RegisterFunction("MDETERM", 1, MDeterm); //ce.RegisterFunction("MINVERSE", 1, MInverse); - //ce.RegisterFunction("MMULT", MMult, 1); + ce.RegisterFunction("MMULT", 2, MMult); ce.RegisterFunction("MOD", 2, Mod); ce.RegisterFunction("MROUND", 2, MRound); ce.RegisterFunction("MULTINOMIAL", 1, 255, Multinomial); @@ -635,5 +635,17 @@ var t = new Tally(p); return t.Numerics().Sum(v => Math.Pow(v, 2)); } + + private static object MMult(List p) + { + var oExp1 = p[0] as XObjectExpression; + var oExp2 = p[1] as XObjectExpression; + + Double value1 = oExp1 == null ? p[0] : (oExp1.Value as CellRangeReference).Range.FirstCell().GetDouble(); + Double value2 = oExp2 == null ? p[1] : (oExp2.Value as CellRangeReference).Range.FirstCell().GetDouble(); + + //return value1*value2; + return new List {4, 5, 6, 7}; + } } } \ No newline at end of file diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Tally.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Tally.cs index c21be91..3cfc228 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Tally.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Tally.cs @@ -33,7 +33,13 @@ } // handle expressions - _list.Add(e.Evaluate()); + var val = e.Evaluate(); + var valEnumerable = val as IEnumerable; + if (valEnumerable == null) + _list.Add(val); + else + foreach (var v in valEnumerable) + _list.Add(v); } public void AddValue(Object v) @@ -58,14 +64,30 @@ List retVal = new List(); foreach (var value in _list) { - Double tmp; - if (Double.TryParse(value.ToString(), out tmp)) + var vEnumerable = value as IEnumerable; + if (vEnumerable == null) + AddNumericValue(value, retVal); + else { - retVal.Add(tmp); + foreach (var v in vEnumerable) + { + AddNumericValue(v, retVal); + break; + } } } return retVal; } + + private static void AddNumericValue(object value, List retVal) + { + Double tmp; + if (Double.TryParse(value.ToString(), out tmp)) + { + retVal.Add(tmp); + } + } + public double Product() { var nums = Numerics(); diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/XLCalcEngine.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/XLCalcEngine.cs index da29233..ca53ef7 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/XLCalcEngine.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/XLCalcEngine.cs @@ -49,6 +49,8 @@ _ce = ce; } + public IXLRange Range { get { return _range; } } + // ** IValueObject public object GetValue() { diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs index c3c4521..88c9944 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs @@ -370,7 +370,15 @@ ) return _worksheet.Workbook.Worksheet(sName).Cell(cAddress).Value; - return Worksheet.Evaluate(fA1); + var retVal = Worksheet.Evaluate(fA1); + var retValEnumerable = retVal as IEnumerable; + + if (retValEnumerable != null) + foreach (var v in retValEnumerable) + return v; + + + return retVal; } var cellValue = HasRichText ? _richText.ToString() : _cellValue; diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs index 7e4779e..0edfbda 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs +++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/FunctionsTests.cs @@ -475,5 +475,42 @@ actual = XLWorkbook.EvaluateExpr("Fixed(12345.123, 1, FALSE)"); Assert.AreEqual("12345.1", actual); } + + [TestMethod] + public void Sum() + { + var cell = new XLWorkbook().AddWorksheet("Sheet1").FirstCell(); + var fCell = cell.SetValue(1).CellBelow().SetValue(2).CellBelow(); + fCell.FormulaA1 = "sum(A1:A2)"; + + Assert.AreEqual(3.0, fCell.Value); + } + + [TestMethod] + public void MMult() + { + var 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(4.0, actual); + + //ws.Cell("A6").FormulaA1 = "Sum(A5)"; + //actual = ws.Cell("A6").Value; + + //Assert.AreEqual(4.0, actual); + + ws.Cell("A7").FormulaA1 = "Sum(MMult(A1:B2, A3:B4))"; + actual = ws.Cell("A7").Value; + + Assert.AreEqual(102.0, actual); + } } }