Beispiel #1
0
        public ValueEval Evaluate(ValueEval[] args, int srcCellRow, int srcCellCol)
        {
            ValueEval arg3 = null;

            switch (args.Length)
            {
            case 4:
                arg3 = args[3];     // important: assumed array element Is never null
                break;

            case 3:
                break;

            default:
                // wrong number of arguments
                return(ErrorEval.VALUE_INVALID);
            }
            try
            {
                // Evaluation order:
                // arg0 lookup_value, arg1 table_array, arg3 range_lookup, Find lookup value, arg2 row_index, fetch result
                ValueEval   lookupValue   = OperandResolver.GetSingleValue(args[0], srcCellRow, srcCellCol);
                AreaEval    tableArray    = LookupUtils.ResolveTableArrayArg(args[1]);
                bool        IsRangeLookup = LookupUtils.ResolveRangeLookupArg(arg3, srcCellRow, srcCellCol);
                int         colIndex      = LookupUtils.LookupIndexOfValue(lookupValue, LookupUtils.CreateRowVector(tableArray, 0), IsRangeLookup);
                int         rowIndex      = LookupUtils.ResolveRowOrColIndexArg(args[2], srcCellRow, srcCellCol);
                ValueVector resultCol     = CreateResultColumnVector(tableArray, rowIndex);
                return(resultCol.GetItem(colIndex));
            }
            catch (EvaluationException e)
            {
                return(e.GetErrorEval());
            }
        }
Beispiel #2
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));
 }
Beispiel #3
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));
        }
Beispiel #4
0
        private static ValueVector CreateVector(AreaEval ae)
        {
            ValueVector result = LookupUtils.CreateVector(ae);

            if (result != null)
            {
                return(result);
            }
            // extra complexity required to emulate the way LOOKUP can handles these abnormal cases.
            throw new InvalidOperationException("non-vector lookup or result areas not supported yet");
        }
Beispiel #5
0
        private static ValueVector EvaluateLookupRange(ValueEval eval)
        {
            if (eval is RefEval)
            {
                RefEval re = (RefEval)eval;
                if (re.NumberOfSheets == 1)
                {
                    return(new SingleValueVector(re.GetInnerValueEval(re.FirstSheetIndex)));
                }
                else
                {
                    return(LookupUtils.CreateVector(re));
                }
            }
            if (eval is TwoDEval)
            {
                ValueVector result = LookupUtils.CreateVector((TwoDEval)eval);
                if (result == null)
                {
                    throw new EvaluationException(ErrorEval.NA);
                }
                return(result);
            }

            // Error handling for lookup_range arg Is also Unusual
            if (eval is NumericValueEval)
            {
                throw new EvaluationException(ErrorEval.NA);
            }
            if (eval is StringEval)
            {
                StringEval se = (StringEval)eval;
                double     d  = OperandResolver.ParseDouble(se.StringValue);
                if (double.IsNaN(d))
                {
                    // plain string
                    throw new EvaluationException(ErrorEval.VALUE_INVALID);
                }
                // else looks like a number
                throw new EvaluationException(ErrorEval.NA);
            }
            throw new Exception("Unexpected eval type (" + eval.GetType().Name + ")");
        }
Beispiel #6
0
 public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval lookup_value, ValueEval table_array,
                                    ValueEval col_index, ValueEval range_lookup)
 {
     try
     {
         // Evaluation order:
         // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 col_index, fetch result
         ValueEval   lookupValue   = OperandResolver.GetSingleValue(lookup_value, srcRowIndex, srcColumnIndex);
         TwoDEval    tableArray    = LookupUtils.ResolveTableArrayArg(table_array);
         bool        isRangeLookup = LookupUtils.ResolveRangeLookupArg(range_lookup, srcRowIndex, srcColumnIndex);
         int         rowIndex      = LookupUtils.LookupIndexOfValue(lookupValue, LookupUtils.CreateColumnVector(tableArray, 0), isRangeLookup);
         int         colIndex      = LookupUtils.ResolveRowOrColIndexArg(col_index, srcRowIndex, srcColumnIndex);
         ValueVector resultCol     = CreateResultColumnVector(tableArray, colIndex);
         return(resultCol.GetItem(rowIndex));
     }
     catch (EvaluationException e)
     {
         return(e.GetErrorEval());
     }
 }
Beispiel #7
0
        public ValueEval Evaluate(ValueEval[] args, int srcCellRow, int srcCellCol)
        {
            switch (args.Length)
            {
            case 3:
                break;

            case 2:
                // complex rules to choose lookupVector and resultVector from the single area ref
                throw new Exception("Two arg version of LOOKUP not supported yet");

            default:
                return(ErrorEval.VALUE_INVALID);
            }


            try
            {
                ValueEval lookupValue    = OperandResolver.GetSingleValue(args[0], srcCellRow, srcCellCol);
                AreaEval  aeLookupVector = LookupUtils.ResolveTableArrayArg(args[1]);
                AreaEval  aeResultVector = LookupUtils.ResolveTableArrayArg(args[2]);

                ValueVector lookupVector = CreateVector(aeLookupVector);
                ValueVector resultVector = CreateVector(aeResultVector);
                if (lookupVector.Size > resultVector.Size)
                {
                    // Excel seems to handle this by accessing past the end of the result vector.
                    throw new Exception("Lookup vector and result vector of differing sizes not supported yet");
                }
                int index = LookupUtils.LookupIndexOfValue(lookupValue, lookupVector, true);

                return(resultVector.GetItem(index));
            }
            catch (EvaluationException e)
            {
                return(e.GetErrorEval());
            }
        }
Beispiel #8
0
 private static LookupValueComparer CreateLookupComparer(ValueEval lookupValue, bool matchExact)
 {
     return(LookupUtils.CreateLookupComparer(lookupValue, matchExact, true));
 }