Пример #1
0
 internal void EvalError(EvaluationException ex)
 {
     if (!ignoreErrors)
     {
         Errors.Add(ex);
     }
 }
Пример #2
0
        public void GetCalculatedFieldValues_SingleEntity_EvaluationException()
        {
            long fieldId  = 123;
            long entityId = 456;
            CalculatedFieldSettings         settings = new CalculatedFieldSettings();
            Mock <ICalculatedFieldProvider> mockProvider;
            IReadOnlyCollection <CalculatedFieldSingleResult> mockEvaluatorResult;
            IReadOnlyCollection <CalculatedFieldResult>       mockProviderResult;
            EvaluationException exception;
            object actualResult;

            // Mock provider
            exception           = new EvaluationException("Test error");
            mockEvaluatorResult = new[] { new CalculatedFieldSingleResult(entityId, exception) };
            mockProviderResult  = new[] { new CalculatedFieldResult(fieldId, mockEvaluatorResult) };
            mockProvider        = new Mock <ICalculatedFieldProvider>(MockBehavior.Strict);
            mockProvider
            .Setup(p => p.GetCalculatedFieldValues(
                       It.Is <IReadOnlyCollection <long> >(fields => fields.Count == 1 && fields.First() == fieldId),
                       It.Is <IReadOnlyCollection <long> >(fields => fields.Count == 1 && fields.First() == entityId),
                       settings))
            .Returns(mockProviderResult);

            // Test extension method
            actualResult = mockProvider.Object.GetCalculatedFieldValue(fieldId, entityId, settings);

            // Verify
            // (Parse exception causes fields to return null)
            Assert.That(actualResult, Is.Null);
            mockProvider.VerifyAll();
        }
Пример #3
0
        private static Function FindFunction(int functionCode)
        {
            //Function func;
            switch (functionCode)
            {
            case 1: return(AggregateFunction.SubtotalInstance(AggregateFunction.AVERAGE));

            case 2: return(Count.SubtotalInstance());

            case 3: return(Counta.SubtotalInstance());

            case 4: return(AggregateFunction.SubtotalInstance(AggregateFunction.MAX));

            case 5: return(AggregateFunction.SubtotalInstance(AggregateFunction.MIN));

            case 6: return(AggregateFunction.SubtotalInstance(AggregateFunction.PRODUCT));

            case 7: return(AggregateFunction.SubtotalInstance(AggregateFunction.STDEV));

            case 8: throw new NotImplementedFunctionException("STDEVP");

            case 9: return(AggregateFunction.SubtotalInstance(AggregateFunction.SUM));

            case 10: throw new NotImplementedFunctionException("VAR");

            case 11: throw new NotImplementedFunctionException("VARP");
            }
            if (functionCode > 100 && functionCode < 112)
            {
                throw new NotImplementedException("SUBTOTAL - with 'exclude hidden values' option");
            }
            throw EvaluationException.InvalidValue();
        }
Пример #4
0
 /**
  * Returns one column from an <c>AreaEval</c>
  *
  * @(#VALUE!) if colIndex Is negative, (#REF!) if colIndex Is too high
  */
 private ValueVector CreateResultColumnVector(TwoDEval tableArray, int colIndex)
 {
     if (colIndex >= tableArray.Width)
     {
         throw EvaluationException.InvalidRef();
     }
     return(LookupUtils.CreateColumnVector(tableArray, colIndex));
 }
Пример #5
0
 /**
  * Returns one column from an <c>AreaEval</c>
  *
  * @(#VALUE!) if colIndex Is negative, (#REF!) if colIndex Is too high
  */
 private ValueVector CreateResultColumnVector(AreaEval tableArray, int rowIndex)
 {
     if (rowIndex >= tableArray.Height)
     {
         throw EvaluationException.InvalidRef();
     }
     return(LookupUtils.CreateRowVector(tableArray, rowIndex));
 }
Пример #6
0
        /**
         * Resolves the last (optional) parameter (<b>range_lookup</b>) to the VLOOKUP and HLOOKUP functions.
         * @param rangeLookupArg
         * @param srcCellRow
         * @param srcCellCol
         * @return
         * @throws EvaluationException
         */
        public static bool ResolveRangeLookupArg(ValueEval rangeLookupArg, int srcCellRow, int srcCellCol)
        {
            ValueEval valEval = OperandResolver.GetSingleValue(rangeLookupArg, srcCellRow, srcCellCol);

            if (valEval == MissingArgEval.instance)
            {
                // Tricky:
                // forth arg exists but is not supplied: "=VLOOKUP(A1,A2:A4,2,)"
                return(false);
            }
            if (valEval is BlankEval)
            {
                // Tricky:
                // fourth arg supplied but Evaluates to blank
                // this does not Get the default value
                return(false);
            }
            if (valEval is BoolEval)
            {
                // Happy day flow
                BoolEval boolEval = (BoolEval)valEval;
                return(boolEval.BooleanValue);
            }

            if (valEval is StringEval)
            {
                String stringValue = ((StringEval)valEval).StringValue;
                if (stringValue.Length < 1)
                {
                    // More trickiness:
                    // Empty string Is not the same as BlankEval.  It causes #VALUE! error
                    throw EvaluationException.InvalidValue();
                }
                // TODO move parseBoolean to OperandResolver
                bool?b = Countif.ParseBoolean(stringValue);
                if (b != null)
                {
                    // string Converted to bool OK
                    return(b == true ? true : false);
                }
                //// Even more trickiness:
                //// Note - even if the StringEval represents a number value (for example "1"),
                //// Excel does not resolve it to a bool.
                throw EvaluationException.InvalidValue();
                //// This Is in contrast to the code below,, where NumberEvals values (for
                //// example 0.01) *do* resolve to equivalent bool values.
            }
            if (valEval is NumericValueEval)
            {
                NumericValueEval nve = (NumericValueEval)valEval;
                // zero Is FALSE, everything else Is TRUE
                return(0.0 != nve.NumberValue);
            }
            throw new Exception("Unexpected eval type (" + valEval.GetType().Name + ")");
        }
Пример #7
0
 /**
  * Verify that each <code>criteriaRanges</code> argument contains the same number of rows and columns
  * as the <code>avgRange</code> argument
  *
  * @throws EvaluationException if
  */
 private void ValidateCriteriaRanges(AreaEval[] criteriaRanges, AreaEval avgRange)
 {
     foreach (AreaEval r in criteriaRanges)
     {
         if (r.Height != avgRange.Height ||
             r.Width != avgRange.Width)
         {
             throw EvaluationException.InvalidValue();
         }
     }
 }
Пример #8
0
 /**
  * Verify that each <code>criteriaRanges</code> argument contains the same number of rows and columns
  * as the <code>sumRange</code> argument
  *
  * @throws EvaluationException if
  */
 internal static void ValidateCriteriaRanges(AreaEval[] criteriaRanges, AreaEval sumRange)
 {
     foreach (AreaEval r in criteriaRanges)
     {
         if (r.Height != sumRange.Height ||
             r.Width != sumRange.Width)
         {
             throw EvaluationException.InvalidValue();
         }
     }
 }
Пример #9
0
        /**
         * Returns a double array that contains values for the numeric cells
         * from among the list of operands. Blanks and Blank equivalent cells
         * are ignored. Error operands or cells containing operands of type
         * that are considered invalid and would result in #VALUE! error in
         * excel cause this function to return <c>null</c>.
         *
         * @return never <c>null</c>
         */
        protected double[] GetNumberArray(ValueEval[] operands)
        {
            if (operands.Length > MaxNumOperands)
            {
                throw EvaluationException.InvalidValue();
            }
            DoubleList retval = new DoubleList();

            for (int i = 0, iSize = operands.Length; i < iSize; i++)
            {
                CollectValues(operands[i], retval);
            }
            return(retval.ToArray());
        }
Пример #10
0
        /// <summary>
        /// Evaluates the identifier/template instance as usual.
        /// If the id points to a variable, the initializer/dynamic value will be evaluated using its initializer.
        ///
        /// If ImplicitlyExecute is false but value evaluation is switched on, an InternalOverloadValue-object will be returned
        /// that keeps all overloads passed via 'overloads'
        /// </summary>
        ISemantic TryDoCTFEOrGetValueRefs(AbstractType[] overloads, IExpression idOrTemplateInstance, bool ImplicitlyExecute = true, ISymbolValue[] executionArguments = null)
        {
            if (overloads == null || overloads.Length == 0)
            {
                throw new EvaluationException(idOrTemplateInstance, "No symbols found");
            }

            var r  = overloads[0];
            var ex = new EvaluationException(idOrTemplateInstance, "Ambiguous expression", overloads);

            if (r is MemberSymbol)
            {
                var mr = (MemberSymbol)r;

                // If we've got a function here, execute it
                if (mr.Definition is DMethod)
                {
                    if (ImplicitlyExecute)
                    {
                        if (overloads.Length > 1)
                        {
                            throw ex;
                        }
                        return(FunctionEvaluation.Execute((DMethod)mr.Definition, executionArguments, ValueProvider));
                    }

                    return(new InternalOverloadValue(overloads, idOrTemplateInstance));
                }
                else if (mr.Definition is DVariable)
                {
                    if (overloads.Length > 1)
                    {
                        throw ex;
                    }
                    return(new VariableValue((DVariable)mr.Definition, mr.Base, idOrTemplateInstance));
                }
            }
            else if (r is UserDefinedType)
            {
                if (overloads.Length > 1)
                {
                    throw ex;
                }
                return(new TypeValue(r, idOrTemplateInstance));
            }

            return(null);
        }
Пример #11
0
        /**
         * The second argument (table_array) should be an area ref, but can actually be a cell ref, in
         * which case it Is interpreted as a 1x1 area ref.  Other scalar values cause #VALUE! error.
         */
        public static AreaEval ResolveTableArrayArg(ValueEval eval)
        {
            if (eval is AreaEval)
            {
                return((AreaEval)eval);
            }

            if (eval is RefEval)
            {
                RefEval refEval = (RefEval)eval;
                // Make this cell ref look like a 1x1 area ref.

                // It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
                return(refEval.Offset(0, 0, 0, 0));
            }
            throw EvaluationException.InvalidValue();
        }
Пример #12
0
        /**
         * Processes the third argument to VLOOKUP, or HLOOKUP (<b>col_index_num</b>
         * or <b>row_index_num</b> respectively).<br/>
         * Sample behaviour:
         *    <table border="0" cellpAdding="1" cellspacing="2" summary="Sample behaviour">
         *      <tr><th>Input Return</th><th>Value </th><th>Thrown Error</th></tr>
         *      <tr><td>5</td><td>4</td><td> </td></tr>
         *      <tr><td>2.9</td><td>2</td><td> </td></tr>
         *      <tr><td>"5"</td><td>4</td><td> </td></tr>
         *      <tr><td>"2.18e1"</td><td>21</td><td> </td></tr>
         *      <tr><td>"-$2"</td><td>-3</td><td>*</td></tr>
         *      <tr><td>FALSE</td><td>-1</td><td>*</td></tr>
         *      <tr><td>TRUE</td><td>0</td><td> </td></tr>
         *      <tr><td>"TRUE"</td><td> </td><td>#REF!</td></tr>
         *      <tr><td>"abc"</td><td> </td><td>#REF!</td></tr>
         *      <tr><td>""</td><td> </td><td>#REF!</td></tr>
         *      <tr><td>&lt;blank&gt;</td><td> </td><td>#VALUE!</td></tr>
         *    </table><br/>
         *
         *  * Note - out of range errors (both too high and too low) are handled by the caller.
         * @return column or row index as a zero-based value
         *
         */

        public static int ResolveRowOrColIndexArg(ValueEval rowColIndexArg, int srcCellRow, int srcCellCol)
        {
            if (rowColIndexArg == null)
            {
                throw new ArgumentException("argument must not be null");
            }

            ValueEval veRowColIndexArg;

            try
            {
                veRowColIndexArg = OperandResolver.GetSingleValue(rowColIndexArg, srcCellRow, (short)srcCellCol);
            }
            catch (EvaluationException)
            {
                // All errors get translated to #REF!
                throw EvaluationException.InvalidRef();
            }
            int oneBasedIndex;

            if (veRowColIndexArg is StringEval)
            {
                StringEval se     = (StringEval)veRowColIndexArg;
                string     strVal = se.StringValue;
                Double     dVal   = OperandResolver.ParseDouble(strVal);
                if (Double.IsNaN(dVal))
                {
                    // String does not resolve to a number. Raise #REF! error.
                    throw EvaluationException.InvalidRef();
                    // This includes text booleans "TRUE" and "FALSE".  They are not valid.
                }
                // else - numeric value parses OK
            }
            // actual BoolEval values get interpreted as FALSE->0 and TRUE->1
            oneBasedIndex = OperandResolver.CoerceValueToInt(veRowColIndexArg);
            if (oneBasedIndex < 1)
            {
                // note this is asymmetric with the errors when the index is too large (#REF!)
                throw EvaluationException.InvalidValue();
            }
            return(oneBasedIndex - 1); // convert to zero based
        }
Пример #13
0
 private static void CollectValue(ValueEval arg, IList temp, bool mustBeNumber)
 {
     if (arg is ErrorEval)
     {
         throw new EvaluationException((ErrorEval)arg);
     }
     if (arg == BlankEval.instance || arg is BoolEval || arg is StringEval)
     {
         if (mustBeNumber)
         {
             throw EvaluationException.InvalidValue();
         }
         return;
     }
     if (arg is NumberEval)
     {
         temp.Add(((NumberEval)arg).NumberValue);
         return;
     }
     throw new InvalidOperationException("Unexpected value type (" + arg.GetType().Name + ")");
 }
Пример #14
0
		internal void EvalError(EvaluationException ex)
		{
			if(!ignoreErrors)
				Errors.Add(ex);
		}
Пример #15
0
        /// <summary>
        /// Evaluates the identifier/template instance as usual.
        /// If the id points to a variable, the initializer/dynamic value will be evaluated using its initializer.
        /// 
        /// If ImplicitlyExecute is false but value evaluation is switched on, an InternalOverloadValue-object will be returned
        /// that keeps all overloads passed via 'overloads'
        /// </summary>
        ISemantic TryDoCTFEOrGetValueRefs(AbstractType[] overloads, IExpression idOrTemplateInstance, bool ImplicitlyExecute = true, ISymbolValue[] executionArguments=null)
        {
            if (overloads == null || overloads.Length == 0)
                throw new EvaluationException(idOrTemplateInstance, "No symbols found");

            var r = overloads[0];
            var ex = new EvaluationException(idOrTemplateInstance, "Ambiguous expression", overloads);

            if (r is MemberSymbol)
            {
                var mr = (MemberSymbol)r;

                // If we've got a function here, execute it
                if (mr.Definition is DMethod)
                {
                    if (ImplicitlyExecute)
                    {
                        if (overloads.Length > 1)
                            throw ex;
                        return FunctionEvaluation.Execute((DMethod)mr.Definition, executionArguments, ValueProvider);
                    }

                    return new InternalOverloadValue(overloads, idOrTemplateInstance);
                }
                else if (mr.Definition is DVariable)
                {
                    if (overloads.Length > 1)
                        throw ex;
                    return new VariableValue((DVariable)mr.Definition, mr.Base, idOrTemplateInstance);
                }
            }
            else if (r is UserDefinedType)
            {
                if (overloads.Length > 1)
                    throw ex;
                return new TypeValue(r, idOrTemplateInstance);
            }

            return null;
        }
 /// <summary>
 /// Evaluation exception constructor
 /// </summary>
 /// <param name="entityId"></param>
 /// <param name="exception">An EvaluationException is a calculation runtime error. Due to bad data only, not due to internal code errors or invalid scripts.</param>
 public CalculatedFieldSingleResult(long entityId, EvaluationException exception)
 {
     EntityId            = entityId;
     EvaluationException = exception;
 }