/// <summary> /// Returns a value you specify if a formula evaluates to an error; otherwise, /// returns the result of the formula. Use the IFERROR function to trap and /// handle errors in a formula (formula: A sequence of values, cell references, /// names, functions, or operators in a cell that together produce a new value. /// A formula always begins with an equal sign (=).). /// </summary> /// <param name="args"><para> /// The args contains three items: value, value_if_error. /// </para> /// <para> /// Value is the argument that is checked for an error. /// </para> /// <para> /// Value_if_error is the value to return if the formula evaluates to an error. /// The following error types are evaluated: #N/A, #VALUE!, #REF!, #DIV/0!, #NUM!, #NAME?, or #NULL!. /// </para></param> /// <returns> /// A <see cref="T:System.Object" /> value that indicates the evaluate result. /// </returns> public override object Evaluate(object[] args) { base.CheckArgumentsLength(args); bool flag = args[0] is CalcError; if (!flag && (args[0] is CalcReference)) { CalcReference reference = args[0] as CalcReference; if (reference.RangeCount > 1) { return(CalcErrors.Value); } return(new BinaryCompositeConcreteReference(reference.GetSource(), reference.GetRow(0), reference.GetColumn(0), reference.GetRowCount(0), reference.GetColumnCount(0), new Func <object, object, object>(CalcIfErrorFunction.EvaluateSingle), args[1], false)); } if (!flag) { object obj1 = args[0]; if (obj1 != null) { return(obj1); } return((int)0); } return(args[1] ?? ((int)0)); }
/// <summary> /// Returns the result of the operator applied to the operands. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand..</param> /// <param name="context"> /// The <see cref="T:Dt.CalcEngine.CalcEvaluatorContext" /> associate with the operator evaluation. /// </param> /// <returns> /// Result of the operator applied to the operand. /// </returns> public override object Evaluate(object left, object right, CalcEvaluatorContext context) { CalcReference reference = left as CalcReference; CalcReference reference2 = right as CalcReference; if ((reference == null) || (reference2 == null)) { return(CalcErrors.Value); } int rangeCount = reference.RangeCount; int num2 = reference2.RangeCount; ConcreteReference.Range[] areas = new ConcreteReference.Range[rangeCount + num2]; for (int i = 0; i < rangeCount; i++) { int row = reference.GetRow(i); int column = reference.GetColumn(i); int rowCount = reference.GetRowCount(i); int columnCount = reference.GetColumnCount(i); areas[i] = new ConcreteReference.Range(row, column, rowCount, columnCount); } for (int j = 0; j < num2; j++) { int num9 = reference2.GetRow(j); int num10 = reference2.GetColumn(j); int num11 = reference2.GetRowCount(j); int num12 = reference2.GetColumnCount(j); areas[rangeCount + j] = new ConcreteReference.Range(num9, num10, num11, num12); } return(new ConcreteReference(reference.GetSource(), areas)); }
/// <summary> /// Returns the result of the operator applied to the operands. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand..</param> /// <param name="context"> /// The <see cref="T:Dt.CalcEngine.CalcEvaluatorContext" /> associate with the operator evaluation. /// </param> /// <returns> /// Result of the operator applied to the operand. /// </returns> public override object Evaluate(object left, object right, CalcEvaluatorContext context) { CalcReference reference = left as CalcReference; CalcReference reference2 = right as CalcReference; if (((reference == null) || (reference2 == null)) || (((reference.RangeCount != 1) || (reference2.RangeCount != 1)) || !reference.GetSource().Equals(reference2.GetSource()))) { return(CalcErrors.Value); } CalcReference source = reference.GetSource(); if ((source == null) || !source.Equals(reference2.GetSource())) { return(CalcErrors.Value); } int row = reference.GetRow(0); int column = reference.GetColumn(0); int num3 = reference2.GetRow(0); int num4 = reference2.GetColumn(0); int num5 = Math.Max(row, num3); int num6 = Math.Max(column, num4); int rowCount = Math.Min((int)(row + reference.GetRowCount(0)), (int)(num3 + reference2.GetRowCount(0))) - num5; int columnCount = Math.Min((int)(column + reference.GetColumnCount(0)), (int)(num4 + reference2.GetColumnCount(0))) - num6; if ((rowCount >= 1) && (columnCount >= 1)) { return(new ConcreteReference(source, num5, num6, rowCount, columnCount)); } return(CalcErrors.Null); }
/// <summary> /// Reverses the value of its argument. /// </summary> /// <param name="args">The args contains one item : logical. /// Logical is a value or expression that can be evaluated to <see langword="true" /> /// or <see langword="false" />.</param> /// <returns> /// A <see cref="T:System.Boolean" /> value that indicates the evaluate result. /// </returns> public override object Evaluate(object[] args) { base.CheckArgumentsLength(args); CalcReference objA = args[0] as CalcReference; CalcArray array = args[0] as CalcArray; if (!object.ReferenceEquals(objA, null)) { if (objA.RangeCount > 1) { return(CalcErrors.Value); } return(new UnaryCompositeConcreteReference(objA.GetSource(), objA.GetRow(0), objA.GetColumn(0), objA.GetRowCount(0), objA.GetColumnCount(0), new Func <object, object>(this.EvaluateSingleValue))); } if (object.ReferenceEquals(array, null)) { return(this.EvaluateSingleValue(args[0])); } object[,] values = new object[array.RowCount, array.ColumnCount]; for (int i = 0; i < array.RowCount; i++) { for (int j = 0; j < array.ColumnCount; j++) { values[i, j] = this.EvaluateSingleValue(array.GetValue(i, j)); } } return(new ConcreteArray <object>(values)); }
/// <summary> /// Returns a reference to a range that is a specified number of /// rows and columns from a cell or range of cells. /// </summary> /// <param name="args"><para> /// The args contains 3 - 5 items: reference, rows, cols, [height], [width]. /// </para> /// <para> /// Reference is the reference from which you want to base the offset. /// </para> /// <para> /// Rows is the number of rows, up or down, that you want the upper-left /// cell to refer to. /// </para> /// <para> /// Cols is the number of columns, to the left or right, that you want /// the upper-left cell of the result to refer to. /// </para> /// <para> /// [Height] is the height, in number of rows, that you want the returned /// reference to be. Height must be a positive number. /// </para> /// <para> /// [Width] is the width, in number of columns, that you want the returned /// reference to be. Width must be a positive number. /// </para></param> /// <returns> /// A <see cref="T:Dt.CalcEngine.CalcReference" /> value that indicates the evaluate result. /// </returns> public override object Evaluate(object[] args) { base.CheckArgumentsLength(args); CalcReference reference = args[0] as CalcReference; if ((reference == null) || (reference.RangeCount != 1)) { return(CalcErrors.Value); } int num = CalcConvert.ToInt(args[1]); int num2 = CalcConvert.ToInt(args[2]); int rowCount = CalcHelper.ArgumentExists(args, 3) ? CalcConvert.ToInt(args[3]) : reference.GetRowCount(0); int columnCount = CalcHelper.ArgumentExists(args, 4) ? CalcConvert.ToInt(args[4]) : reference.GetColumnCount(0); CalcReference source = reference.GetSource(); int row = reference.GetRow(0) + num; int column = reference.GetColumn(0) + num2; if ((rowCount > 0) && (columnCount > 0)) { if ((row < source.GetRow(0)) || ((source.GetRow(0) + source.GetRowCount(0)) < (row + rowCount))) { return(CalcErrors.Reference); } if ((column >= source.GetColumn(0)) && ((source.GetColumn(0) + source.GetColumnCount(0)) >= (column + columnCount))) { return(new ConcreteReference(source, row, column, rowCount, columnCount)); } } return(CalcErrors.Reference); }
/// <summary> /// Adds the cells specified by a given criteria. /// </summary> /// <param name="args"><para> /// The args contains 2 - 3 items: range, criteria, [sum_range]. /// </para> /// <para> /// Range is the range of cells that you want evaluated by criteria. /// </para> /// <para> /// Criteria is the criteria in the form of a number, expression, /// or text that defines which cells will be added. /// </para> /// <para> /// [Sum_range] are the actual cells to add if their corresponding /// cells in range match criteria. /// </para></param> /// <returns> /// A <see cref="T:System.Double" /> value that indicates the evaluate result. /// </returns> public override object Evaluate(object[] args) { base.CheckArgumentsLength(args); object range = args[0]; object criteria = args[1]; if (criteria == null) { throw new ArgumentException("criteria"); } object sumRange = CalcHelper.ArgumentExists(args, 2) ? args[2] : args[0]; CalcReference objA = args[1] as CalcReference; if (!object.ReferenceEquals(objA, null)) { int num = objA.GetRowCount(0); int num2 = objA.GetColumnCount(0); if ((num == 1) && (num2 == 1)) { return(EvaluateSingleCriteria(objA.GetValue(0, 0, 0), range, sumRange)); } return(new TernaryCompositeConcreteReference(objA.GetSource(), objA.GetRow(0), objA.GetColumn(0), num, num2, new Func <object, object, object, object>(CalcSumIfFunction.EvaluateSingleCriteria), range, sumRange)); } CalcArray array = args[1] as CalcArray; if (object.ReferenceEquals(array, null)) { return(EvaluateSingleCriteria(criteria, range, sumRange)); } int rowCount = array.RowCount; int columnCount = array.ColumnCount; object[,] values = new object[rowCount, columnCount]; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { values[i, j] = EvaluateSingleCriteria(array.GetValue(i, j), range, sumRange); } } return(new ConcreteArray <object>(values)); }
private static object EvaluateImp(object[] args, object context) { CalcEvaluatorContext objA = context as CalcEvaluatorContext; if (object.ReferenceEquals(objA, null)) { return(CalcErrors.Value); } bool arrayFormulaMode = objA.ArrayFormulaMode; CalcReference reference = CalcHelper.ArgumentExists(args, 0) ? (args[0] as CalcReference) : (objA.GetReference(new CalcRangeIdentity(objA.Row, objA.Column, objA.RowCount, objA.ColumnCount)) as CalcReference); if ((reference == null) || (reference.RangeCount != 1)) { return(CalcErrors.Value); } if (arrayFormulaMode) { return(new CellInfoReference(reference.GetSource(), reference.GetRow(0), reference.GetColumn(0), reference.GetRowCount(0), reference.GetColumnCount(0), CellInfoReference.CellInfoType.Column)); } return((int)(reference.GetColumn(0) + 1)); }
public static void ExtractAllReferenceExpression(ICalcEvaluator evaluator, CalcExpression root, List <CalcReferenceExpression> nodes) { if (root is CalcBinaryOperatorExpression) { CalcBinaryOperatorExpression expression = root as CalcBinaryOperatorExpression; ExtractAllReferenceExpression(evaluator, expression.Left, nodes); ExtractAllReferenceExpression(evaluator, expression.Right, nodes); } else if (root is CalcParenthesesExpression) { CalcParenthesesExpression expression2 = root as CalcParenthesesExpression; ExtractAllReferenceExpression(evaluator, expression2.Arg, nodes); } else if (root is CalcExternalNameExpression) { CalcExternalNameExpression expression3 = root as CalcExternalNameExpression; ICalcSource source = expression3.Source; if (source != null) { CalcExpression expression4 = source.GetDefinedName(expression3.Name, -1, -1); if (expression4 != null) { ExtractAllReferenceExpression(evaluator, expression4, nodes); } } } else if (root is CalcFunctionExpression) { CalcFunctionExpression expr = root as CalcFunctionExpression; Worksheet worksheet = evaluator as Worksheet; if (worksheet != null) { CalcEvaluatorContext context = new CalcEvaluatorContext(worksheet, false, worksheet.ActiveRowIndex, worksheet.ActiveColumnIndex, 1, 1); object obj2 = new CalcEvaluator().Evaluate(expr, context, true, true); if (obj2 is CalcReference) { CalcReference reference = obj2 as CalcReference; int row = reference.GetRow(0); int rowCount = reference.GetRowCount(0); int column = reference.GetColumn(0); int columnCount = reference.GetColumnCount(0); ICalcSource source2 = null; CalcReference reference2 = reference.GetSource(); // hdt MethodInfo info = reference2.GetType().GetRuntimeMethod("GetContext", null); if (info != null) { source2 = info.Invoke(reference2, null) as ICalcSource; } if (source2 == null) { source2 = worksheet; } CalcExternalRangeExpression expression6 = CreateExternalRangeExpressionByCount(source2, row, column, rowCount, columnCount, false, false, false, false); nodes.Add(expression6); } } } else if (root is CalcReferenceExpression) { nodes.Add(root as CalcReferenceExpression); } }