예제 #1
0
        /// <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));
        }
예제 #2
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));
        }
예제 #3
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)) || (((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);
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
        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));
        }
예제 #8
0
        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);
            }
        }