示例#1
0
文件: YearFrac.cs 项目: xoposhiy/npoi
        public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
        {
            int srcCellRow = ec.RowIndex;
            int srcCellCol = ec.ColumnIndex;
            double result;
            try
            {
                int basis = 0; // default
                switch (args.Length)
                {
                    case 3:
                        basis = EvaluateIntArg(args[2], srcCellRow, srcCellCol);
                        break;
                    case 2:
                        //basis = EvaluateIntArg(args[2], srcCellRow, srcCellCol);
                        break;
                    default:
                        return ErrorEval.VALUE_INVALID;
                }
                double startDateVal = EvaluateDateArg(args[0], srcCellRow, srcCellCol);
                double endDateVal = EvaluateDateArg(args[1], srcCellRow, srcCellCol);
                result = YearFracCalculator.Calculate(startDateVal, endDateVal, basis);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }

            return new NumberEval(result);
        }
        public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
        {
            int nIncomingArgs = args.Length;
            if (nIncomingArgs < 1)
            {
                throw new Exception("function name argument missing");
            }

            ValueEval nameArg = args[0];
            String functionName = string.Empty ;
            if (nameArg is NameEval)
            {
                functionName = ((NameEval)nameArg).FunctionName;
            }
            else if (nameArg is NameXEval)
            {
                functionName = ec.GetWorkbook().ResolveNameXText(((NameXEval)nameArg).Ptg);
            }
            else
            {
                throw new Exception("First argument should be a NameEval, but got ("
                        + nameArg.GetType().Name + ")");
            }
            FreeRefFunction targetFunc = ec.FindUserDefinedFunction(functionName);
            if (targetFunc == null)
            {
                throw new NotImplementedException(functionName);
            }
            int nOutGoingArgs = nIncomingArgs - 1;
            ValueEval[] outGoingArgs = new ValueEval[nOutGoingArgs];
            Array.Copy(args, 1, outGoingArgs, 0, nOutGoingArgs);
            return targetFunc.Evaluate(outGoingArgs, ec);
        }
        /**
         * returns the OperationEval concrete impl instance corresponding
         * to the supplied operationPtg
         */
        public static ValueEval Evaluate(OperationPtg ptg, ValueEval[] args,
                OperationEvaluationContext ec)
        {
            if(ptg == null) {
            throw new ArgumentException("ptg must not be null");
            }
            Function result = _instancesByPtgClass[ptg] as Function;

            if (result != null) {
            return  result.Evaluate(args, ec.RowIndex, (short) ec.ColumnIndex);
            }

            if (ptg is AbstractFunctionPtg) {
            AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg;
            int functionIndex = fptg.GetFunctionIndex();
            switch (functionIndex) {
                case NPOI.HSSF.Record.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
                    return Indirect.instance.Evaluate(args, ec);
                case NPOI.HSSF.Record.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
                    return UserDefinedFunction.instance.Evaluate(args, ec);
            }

            return FunctionEval.GetBasicFunction(functionIndex).Evaluate(args, ec.RowIndex, ec.ColumnIndex);
            }
            throw new Exception("Unexpected operation ptg class (" + ptg.GetType().Name + ")");
        }
示例#4
0
        public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
        {
            if (args.Length < 1)
            {
                return ErrorEval.VALUE_INVALID;
            }

            bool isA1style;
            String text;
            try
            {
                ValueEval ve = OperandResolver.GetSingleValue(args[0], ec.RowIndex, ec
                        .ColumnIndex);
                text = OperandResolver.CoerceValueToString(ve);
                switch (args.Length)
                {
                    case 1:
                        isA1style = true;
                        break;
                    case 2:
                        isA1style = EvaluateBooleanArg(args[1], ec);
                        break;
                    default:
                        return ErrorEval.VALUE_INVALID;
                }
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }

            return EvaluateIndirect(ec, text, isA1style);
        }
示例#5
0
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     if (args.Length != 1)
     {
         return ErrorEval.VALUE_INVALID;
     }
     return Evaluate(ec.RowIndex, ec.ColumnIndex, args[0]);
 }
示例#6
0
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     if (args.Length != 1 || !(args[0] is StringEval))
     {
         return ErrorEval.VALUE_INVALID;
     }
     StringEval input = (StringEval)args[0];
     return new StringEval(input.StringValue + "abc2");
 }
示例#7
0
        private static bool EvaluateBooleanArg(ValueEval arg, OperationEvaluationContext ec)
        {
            ValueEval ve = OperandResolver.GetSingleValue(arg, ec.RowIndex, ec.ColumnIndex);

            if (ve == BlankEval.instance || ve == MissingArgEval.instance)
            {
                return false;
            }
            // numeric quantities follow standard bool conversion rules
            // for strings, only "TRUE" and "FALSE" (case insensitive) are valid
            return (bool)OperandResolver.CoerceValueToBoolean(ve, false);
        }
        public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec) 
        {
            if (args.Length != 1)
            {
                return ErrorEval.VALUE_INVALID;
            }

            int val;
            try
            {
                val = EvaluateArgParity(args[0], ec.RowIndex, ec.ColumnIndex);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }

            return BoolEval.ValueOf(val == _desiredParity);
        }
示例#9
0
        public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
        {
            if (args.Length != 2)
            {
                return ErrorEval.VALUE_INVALID;
            }

            try
            {
                double startDateAsNumber = NumericFunction.SingleOperandEvaluate(args[0], ec.RowIndex, ec.ColumnIndex);
                int months = (int)NumericFunction.SingleOperandEvaluate(args[1], ec.RowIndex, ec.ColumnIndex);

                // Excel treats date 0 as 1900-01-00; EOMONTH results in 1900-01-31
                if (startDateAsNumber >= 0.0 && startDateAsNumber < 1.0)
                {
                    startDateAsNumber = 1.0;
                }

                DateTime startDate = DateUtil.GetJavaDate(startDateAsNumber, false);
                //the month
                DateTime dtEnd = startDate.AddMonths(months);
                //next month
                dtEnd = dtEnd.AddMonths(1);
                //first day of next month
                dtEnd = new DateTime(dtEnd.Year, dtEnd.Month, 1);
                //last day of the month
                dtEnd = dtEnd.AddDays(-1);
                

                return new NumberEval(DateUtil.GetExcelDate(dtEnd));
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }
        }
示例#10
0
文件: Countifs.cs 项目: eatage/npoi
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     Double result = double.NaN;
     if (args.Length == 0 || args.Length % 2 > 0)
     {
         return ErrorEval.VALUE_INVALID;
     }
     for (int i = 0; i < args.Length; )
     {
         ValueEval firstArg = args[i];
         ValueEval secondArg = args[i + 1];
         i += 2;
         NumberEval Evaluate = (NumberEval)new Countif().Evaluate(new ValueEval[] { firstArg, secondArg }, ec.RowIndex, ec.ColumnIndex);
         if (double.IsNaN(result))
         {
             result = Evaluate.NumberValue;
         }
         else if (Evaluate.NumberValue < result)
         {
             result = Evaluate.NumberValue;
         }
     }
     return new NumberEval(double.IsNaN(result) ? 0 : result);
 }
        /**
         * returns an appropriate Eval impl instance for the Ptg. The Ptg must be
         * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
         * StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
         * passed here!
         */
        private ValueEval GetEvalForPtg(Ptg ptg, OperationEvaluationContext ec)
        {
            //  consider converting all these (ptg is XxxPtg) expressions To (ptg.GetType() == XxxPtg.class)

            if (ptg is NamePtg)
            {
                // named ranges, macro functions
                NamePtg        namePtg    = (NamePtg)ptg;
                EvaluationName nameRecord = _workbook.GetName(namePtg);
                if (nameRecord.IsFunctionName)
                {
                    return(new NameEval(nameRecord.NameText));
                }
                if (nameRecord.HasFormula)
                {
                    return(EvaluateNameFormula(nameRecord.NameDefinition, ec));
                }

                throw new Exception("Don't now how To evalate name '" + nameRecord.NameText + "'");
            }
            if (ptg is NameXPtg)
            {
                return(new NameXEval(((NameXPtg)ptg)));
            }

            if (ptg is IntPtg)
            {
                return(new NumberEval(((IntPtg)ptg).Value));
            }
            if (ptg is NumberPtg)
            {
                return(new NumberEval(((NumberPtg)ptg).Value));
            }
            if (ptg is StringPtg)
            {
                return(new StringEval(((StringPtg)ptg).Value));
            }
            if (ptg is BoolPtg)
            {
                return(BoolEval.ValueOf(((BoolPtg)ptg).Value));
            }
            if (ptg is ErrPtg)
            {
                return(ErrorEval.ValueOf(((ErrPtg)ptg).ErrorCode));
            }
            if (ptg is MissingArgPtg)
            {
                return(MissingArgEval.instance);
            }
            if (ptg is AreaErrPtg || ptg is RefErrorPtg ||
                ptg is DeletedArea3DPtg || ptg is DeletedRef3DPtg)
            {
                return(ErrorEval.REF_INVALID);
            }
            if (ptg is Ref3DPtg)
            {
                Ref3DPtg rptg = (Ref3DPtg)ptg;
                return(ec.GetRef3DEval(rptg.Row, rptg.Column, rptg.ExternSheetIndex));
            }
            if (ptg is Area3DPtg)
            {
                Area3DPtg aptg = (Area3DPtg)ptg;
                return(ec.GetArea3DEval(aptg.FirstRow, aptg.FirstColumn, aptg.LastRow, aptg.LastColumn, aptg.ExternSheetIndex));
            }
            if (ptg is RefPtg)
            {
                RefPtg rptg = (RefPtg)ptg;
                return(ec.GetRefEval(rptg.Row, rptg.Column));
            }
            if (ptg is AreaPtg)
            {
                AreaPtg aptg = (AreaPtg)ptg;
                return(ec.GetAreaEval(aptg.FirstRow, aptg.FirstColumn, aptg.LastRow, aptg.LastColumn));
            }

            if (ptg is UnknownPtg)
            {
                // POI uses UnknownPtg when the encoded Ptg array seems To be corrupted.
                // This seems To occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790)
                // In any case, formulas are re-parsed before execution, so UnknownPtg should not Get here
                throw new Exception("UnknownPtg not allowed");
            }

            throw new Exception("Unexpected ptg class (" + ptg.GetType().Name + ")");
        }
示例#12
0
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(IEvaluationCell srcCell, int sheetIndex,
                    int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            bool shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
                    : !_stabilityClassifier.IsCellFinal(sheetIndex, rowIndex, columnIndex);
            ValueEval result;
            if (srcCell == null || srcCell.CellType != CellType.FORMULA)
            {
                result = GetValueFromNonFormulaCell(srcCell);
                if (shouldCellDependencyBeRecorded)
                {
                    tracker.AcceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
                }
                return result;
            }

            FormulaCellCacheEntry cce = _cache.GetOrCreateFormulaCellEntry(srcCell);
            if (shouldCellDependencyBeRecorded || cce.IsInputSensitive)
            {
                tracker.AcceptFormulaDependency(cce);
            }
            IEvaluationListener evalListener = _evaluationListener;
            if (cce.GetValue() == null)
            {
                if (!tracker.StartEvaluate(cce))
                {
                    return ErrorEval.CIRCULAR_REF_ERROR;
                }
                OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

                try
                {
                    Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
                    if (evalListener == null)
                    {
                        result = EvaluateFormula(ec, ptgs);
                    }
                    else
                    {
                        evalListener.OnStartEvaluate(srcCell, cce);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                catch (NotImplementedException e)
                {
                    throw AddExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
                }
                finally
                {
                    tracker.EndEvaluate(cce);
                }
            }
            else
            {
                if (evalListener != null)
                {
                    evalListener.OnCacheHit(sheetIndex, rowIndex, columnIndex, cce.GetValue());
                }
                return cce.GetValue();
            }
            if (IsDebugLogEnabled())
            {
                String sheetName = GetSheetName(sheetIndex);
                CellReference cr = new CellReference(rowIndex, columnIndex);
                LogDebug("Evaluated " + sheetName + "!" + cr.FormatAsString() + " To " + cce.GetValue().ToString());
            }
            // Usually (result === cce.getValue())
            // But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null)
            // When circular references are detected, the cache entry is only updated for
            // the top evaluation frame
            //return cce.GetValue();
            return result;
        }
示例#13
0
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     throw new NotImplementedException("not implemented");
 }
示例#14
0
        private OperationEvaluationContext CreateContext()
        {
            HSSFWorkbook wb = new HSSFWorkbook();
            ISheet sheet = wb.CreateSheet();
            IRow row = sheet.CreateRow(0);
            ICell cell = row.CreateCell(0);
            cell.SetCellValue("13.43");
            cell = row.CreateCell(1);
            cell.SetCellValue("8");
            cell = row.CreateCell(2);
            cell.SetCellValue("-8");
            cell = row.CreateCell(3);
            cell.SetCellValue("1");

            HSSFEvaluationWorkbook workbook = HSSFEvaluationWorkbook.Create(wb);
            WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(workbook, new IStabilityClassifier1(), null);
            OperationEvaluationContext ctx = new OperationEvaluationContext(workbookEvaluator,
                    workbook, 0, 0, 0, null);
            return ctx;
        }
        /**
         * returns an appropriate Eval impl instance for the Ptg. The Ptg must be
         * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
         * StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
         * passed here!
         */
        private ValueEval GetEvalForPtg(Ptg ptg, OperationEvaluationContext ec)
        {
            //  consider converting all these (ptg is XxxPtg) expressions To (ptg.GetType() == XxxPtg.class)

            if (ptg is NamePtg)
            {
                // named ranges, macro functions
                NamePtg namePtg = (NamePtg)ptg;
                EvaluationName nameRecord = _workbook.GetName(namePtg);
                if (nameRecord.IsFunctionName)
                {
                    return new NameEval(nameRecord.NameText);
                }
                if (nameRecord.HasFormula)
                {
                    return EvaluateNameFormula(nameRecord.NameDefinition, ec);
                }

                throw new Exception("Don't now how To evalate name '" + nameRecord.NameText + "'");
            }
            if (ptg is NameXPtg)
            {
                return new NameXEval(((NameXPtg)ptg));
            }

            if (ptg is IntPtg)
            {
                return new NumberEval(((IntPtg)ptg).Value);
            }
            if (ptg is NumberPtg)
            {
                return new NumberEval(((NumberPtg)ptg).Value);
            }
            if (ptg is StringPtg)
            {
                return new StringEval(((StringPtg)ptg).Value);
            }
            if (ptg is BoolPtg)
            {
                return BoolEval.ValueOf(((BoolPtg)ptg).Value);
            }
            if (ptg is ErrPtg)
            {
                return ErrorEval.ValueOf(((ErrPtg)ptg).ErrorCode);
            }
            if (ptg is MissingArgPtg)
            {
                return MissingArgEval.instance;
            }
            if (ptg is AreaErrPtg || ptg is RefErrorPtg
                    || ptg is DeletedArea3DPtg || ptg is DeletedRef3DPtg)
            {
                return ErrorEval.REF_INVALID;
            }
            if (ptg is Ref3DPtg)
            {
                Ref3DPtg rptg = (Ref3DPtg)ptg;
                return ec.GetRef3DEval(rptg.Row, rptg.Column, rptg.ExternSheetIndex);
            }
            if (ptg is Area3DPtg)
            {
                Area3DPtg aptg = (Area3DPtg)ptg;
                return ec.GetArea3DEval(aptg.FirstRow, aptg.FirstColumn, aptg.LastRow, aptg.LastColumn, aptg.ExternSheetIndex);
            }
            if (ptg is RefPtg)
            {
                RefPtg rptg = (RefPtg)ptg;
                return ec.GetRefEval(rptg.Row, rptg.Column);
            }
            if (ptg is AreaPtg)
            {
                AreaPtg aptg = (AreaPtg)ptg;
                return ec.GetAreaEval(aptg.FirstRow, aptg.FirstColumn, aptg.LastRow, aptg.LastColumn);
            }

            if (ptg is UnknownPtg)
            {
                // POI uses UnknownPtg when the encoded Ptg array seems To be corrupted.
                // This seems To occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790)
                // In any case, formulas are re-parsed before execution, so UnknownPtg should not Get here
                throw new Exception("UnknownPtg not allowed");
            }

            throw new Exception("Unexpected ptg class (" + ptg.GetType().Name + ")");
        }
示例#16
0
 private static ValueEval InvokeSumifs(ValueEval[] args, OperationEvaluationContext ec)
 {
     return new Sumifs().Evaluate(args, EC);
 }
        // visibility raised for testing
        /* package */
        public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs)
        {
            Stack <ValueEval> stack = new Stack <ValueEval>();

            for (int i = 0, iSize = ptgs.Length; i < iSize; i++)
            {
                // since we don't know how To handle these yet :(
                Ptg ptg = ptgs[i];
                if (ptg is AttrPtg)
                {
                    AttrPtg attrPtg = (AttrPtg)ptg;
                    if (attrPtg.IsSum)
                    {
                        // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator
                        // expects the equivalent function Token
                        byte nArgs = 1;  // tAttrSum always Has 1 parameter
                        ptg = new FuncVarPtg("SUM", nArgs);
                    }
                    if (attrPtg.IsOptimizedChoose)
                    {
                        ValueEval arg0      = stack.Pop();
                        int[]     jumpTable = attrPtg.JumpTable;
                        int       dist;
                        int       nChoices = jumpTable.Length;
                        try {
                            int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                            if (switchIndex < 1 || switchIndex > nChoices)
                            {
                                stack.Push(ErrorEval.VALUE_INVALID);
                                dist = attrPtg.ChooseFuncOffset + 4;                         // +4 for tFuncFar(CHOOSE)
                            }
                            else
                            {
                                dist = jumpTable[switchIndex - 1];
                            }
                        } catch (EvaluationException e) {
                            stack.Push(e.GetErrorEval());
                            dist = attrPtg.ChooseFuncOffset + 4;                     // +4 for tFuncFar(CHOOSE)
                        }
                        // Encoded dist for tAttrChoose includes size of jump table, but
                        // countTokensToBeSkipped() does not (it counts whole tokens).
                        dist -= nChoices * 2 + 2;             // subtract jump table size
                        i    += CountTokensToBeSkipped(ptgs, i, dist);
                        continue;
                    }
                    if (attrPtg.IsOptimizedIf)
                    {
                        ValueEval arg0 = stack.Pop();
                        bool      evaluatedPredicate;
                        try {
                            evaluatedPredicate = If.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                        } catch (EvaluationException e) {
                            stack.Push(e.GetErrorEval());
                            int dist = attrPtg.Data;
                            i      += CountTokensToBeSkipped(ptgs, i, dist);
                            attrPtg = (AttrPtg)ptgs[i];
                            dist    = attrPtg.Data + 1;
                            i      += CountTokensToBeSkipped(ptgs, i, dist);
                            continue;
                        }
                        if (evaluatedPredicate)
                        {
                            // nothing to skip - true param folows
                        }
                        else
                        {
                            int dist = attrPtg.Data;
                            i += CountTokensToBeSkipped(ptgs, i, dist);
                            Ptg nextPtg = ptgs[i + 1];
                            if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg)
                            {
                                // this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
                                i++;
                                stack.Push(BoolEval.FALSE);
                            }
                        }
                        continue;
                    }
                    if (attrPtg.IsSkip)
                    {
                        int dist = attrPtg.Data + 1;
                        i += CountTokensToBeSkipped(ptgs, i, dist);
                        if (stack.Peek() == MissingArgEval.instance)
                        {
                            stack.Pop();
                            stack.Push(BlankEval.instance);
                        }
                        continue;
                    }
                }
                if (ptg is ControlPtg)
                {
                    // skip Parentheses, Attr, etc
                    continue;
                }
                if (ptg is MemFuncPtg)
                {
                    // can ignore, rest of Tokens for this expression are in OK RPN order
                    continue;
                }
                if (ptg is MemErrPtg)
                {
                    continue;
                }

                ValueEval opResult;
                if (ptg is OperationPtg)
                {
                    OperationPtg optg = (OperationPtg)ptg;

                    if (optg is UnionPtg)
                    {
                        continue;
                    }

                    int         numops = optg.NumberOfOperands;
                    ValueEval[] ops    = new ValueEval[numops];

                    // storing the ops in reverse order since they are popping
                    for (int j = numops - 1; j >= 0; j--)
                    {
                        ValueEval p = (ValueEval)stack.Pop();
                        ops[j] = p;
                    }
                    //				logDebug("Invoke " + operation + " (nAgs=" + numops + ")");
                    opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec);
                }
                else
                {
                    opResult = GetEvalForPtg(ptg, ec);
                }
                if (opResult == null)
                {
                    throw new Exception("Evaluation result must not be null");
                }
                //			logDebug("push " + opResult);
                stack.Push(opResult);
            }

            ValueEval value = ((ValueEval)stack.Pop());

            if (stack.Count != 0)
            {
                throw new InvalidOperationException("evaluation stack not empty");
            }
            value = DereferenceValue(value, ec.RowIndex, ec.ColumnIndex);
            if (value == BlankEval.instance)
            {
                // Note Excel behaviour here. A blank value is converted To zero.
                return(NumberEval.ZERO);
                // Formulas _never_ evaluate To blank.  If a formula appears To have evaluated To
                // blank, the actual value is empty string. This can be verified with ISBLANK().
            }
            return(value);
        }
示例#18
0
 private static ValueEval EvaluateFormula(Ptg[] ptgs)
 {
     OperationEvaluationContext ec = new OperationEvaluationContext(null, null, 0, 0, 0, null);
     return new WorkbookEvaluator(null, null, null).EvaluateFormula(ec, ptgs);
 }
示例#19
0
 internal ValueEval EvaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec)
 {
     if (ptgs.Length == 1)
     {
         return GetEvalForPtg(ptgs[0], ec);
     }
     return EvaluateFormula(ec, ptgs);
 }
示例#20
0
        /**
         * returns an appropriate Eval impl instance for the Ptg. The Ptg must be
         * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
         * StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
         * passed here!
         */
        private ValueEval GetEvalForPtg(Ptg ptg, OperationEvaluationContext ec)
        {
            //  consider converting all these (ptg is XxxPtg) expressions To (ptg.GetType() == XxxPtg.class)

            if (ptg is NamePtg)
            {
                // Named ranges, macro functions
                NamePtg namePtg = (NamePtg)ptg;
                IEvaluationName nameRecord = _workbook.GetName(namePtg);
                return GetEvalForNameRecord(nameRecord, ec);
            }
            if (ptg is NameXPtg) 
            {
                // Externally defined named ranges or macro functions
                return ProcessNameEval(ec.GetNameXEval((NameXPtg)ptg), ec);
            }
            if (ptg is NameXPxg)
            {
                // Externally defined named ranges or macro functions
                return ProcessNameEval(ec.GetNameXEval((NameXPxg)ptg), ec);
            }
            if (ptg is IntPtg)
            {
                return new NumberEval(((IntPtg)ptg).Value);
            }
            if (ptg is NumberPtg)
            {
                return new NumberEval(((NumberPtg)ptg).Value);
            }
            if (ptg is StringPtg)
            {
                return new StringEval(((StringPtg)ptg).Value);
            }
            if (ptg is BoolPtg)
            {
                return BoolEval.ValueOf(((BoolPtg)ptg).Value);
            }
            if (ptg is ErrPtg)
            {
                return ErrorEval.ValueOf(((ErrPtg)ptg).ErrorCode);
            }
            if (ptg is MissingArgPtg)
            {
                return MissingArgEval.instance;
            }
            if (ptg is AreaErrPtg || ptg is RefErrorPtg
                    || ptg is DeletedArea3DPtg || ptg is DeletedRef3DPtg)
            {
                return ErrorEval.REF_INVALID;
            }
            if (ptg is Ref3DPtg)
            {
                return ec.GetRef3DEval((Ref3DPtg)ptg);
            }

            if (ptg is Ref3DPxg)
            {
                return ec.GetRef3DEval((Ref3DPxg)ptg);
            }
            if (ptg is Area3DPtg) {
               return ec.GetArea3DEval((Area3DPtg)ptg);
           }
           if (ptg is Area3DPxg) {
               return ec.GetArea3DEval((Area3DPxg)ptg);
           }

            if (ptg is RefPtg)
            {
                RefPtg rptg = (RefPtg)ptg;
                return ec.GetRefEval(rptg.Row, rptg.Column);
            }
            if (ptg is AreaPtg)
            {
                AreaPtg aptg = (AreaPtg)ptg;
                return ec.GetAreaEval(aptg.FirstRow, aptg.FirstColumn, aptg.LastRow, aptg.LastColumn);
            }

            if (ptg is UnknownPtg)
            {
                // POI uses UnknownPtg when the encoded Ptg array seems To be corrupted.
                // This seems To occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790)
                // In any case, formulas are re-parsed before execution, so UnknownPtg should not Get here
                throw new RuntimeException("UnknownPtg not allowed");
            }
            if (ptg is ExpPtg)
            {
                // ExpPtg is used for array formulas and shared formulas.
                // it is currently unsupported, and may not even get implemented here
                throw new RuntimeException("ExpPtg currently not supported");
            }
            throw new RuntimeException("Unexpected ptg class (" + ptg.GetType().Name + ")");
        }
示例#21
0
        // visibility raised for testing
        /* package */
        public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs)
        {
            String dbgIndentStr = "";		// always init. to non-null just for defensive avoiding NPE
            if (dbgEvaluationOutputForNextEval)
            {
                // first evaluation call when ouput is desired, so iit. this evaluator instance
                dbgEvaluationOutputIndent = 1;
                dbgEvaluationOutputForNextEval = false;
            }
            if (dbgEvaluationOutputIndent > 0)
            {
                // init. indent string to needed spaces (create as substring vom very long space-only string;
                // limit indendation for deep recursions)
                dbgIndentStr = "                                                                                                    ";
                dbgIndentStr = dbgIndentStr.Substring(0, Math.Min(dbgIndentStr.Length, dbgEvaluationOutputIndent * 2));
                EVAL_LOG.Log(POILogger.WARN, dbgIndentStr
                                   + "- evaluateFormula('" + ec.GetRefEvaluatorForCurrentSheet().SheetName
                                   + "'/" + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString()
                                   + "): " + Arrays.ToString(ptgs).Replace("\\Qorg.apache.poi.ss.formula.ptg.\\E", ""));
                dbgEvaluationOutputIndent++;
            }

            Stack<ValueEval> stack = new Stack<ValueEval>();
            for (int i = 0, iSize = ptgs.Length; i < iSize; i++)
            {

                // since we don't know how To handle these yet :(
                Ptg ptg = ptgs[i];
                if (dbgEvaluationOutputIndent > 0)
                {
                    EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "  * ptg " + i + ": " + ptg.ToString());
                }
                if (ptg is AttrPtg)
                {
                    AttrPtg attrPtg = (AttrPtg)ptg;
                    if (attrPtg.IsSum)
                    {
                        // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator
                        // expects the equivalent function Token
                        //byte nArgs = 1;  // tAttrSum always Has 1 parameter
                        ptg = FuncVarPtg.SUM;//.Create("SUM", nArgs);
                    }
                    if (attrPtg.IsOptimizedChoose)
                    {
                        ValueEval arg0 = stack.Pop();
                        int[] jumpTable = attrPtg.JumpTable;
                        int dist;
                        int nChoices = jumpTable.Length;
                        try
                        {
                            int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                            if (switchIndex < 1 || switchIndex > nChoices)
                            {
                                stack.Push(ErrorEval.VALUE_INVALID);
                                dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
                            }
                            else
                            {
                                dist = jumpTable[switchIndex - 1];
                            }
                        }
                        catch (EvaluationException e)
                        {
                            stack.Push(e.GetErrorEval());
                            dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
                        }
                        // Encoded dist for tAttrChoose includes size of jump table, but
                        // countTokensToBeSkipped() does not (it counts whole tokens).
                        dist -= nChoices * 2 + 2; // subtract jump table size
                        i += CountTokensToBeSkipped(ptgs, i, dist);
                        continue;
                    }
                    if (attrPtg.IsOptimizedIf)
                    {
                        ValueEval arg0 = stack.Pop();
                        bool evaluatedPredicate;
                        try
                        {
                            evaluatedPredicate = If.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                        }
                        catch (EvaluationException e)
                        {
                            stack.Push(e.GetErrorEval());
                            int dist = attrPtg.Data;
                            i += CountTokensToBeSkipped(ptgs, i, dist);
                            attrPtg = (AttrPtg)ptgs[i];
                            dist = attrPtg.Data + 1;
                            i += CountTokensToBeSkipped(ptgs, i, dist);
                            continue;
                        }
                        if (evaluatedPredicate)
                        {
                            // nothing to skip - true param folows
                        }
                        else
                        {
                            int dist = attrPtg.Data;
                            i += CountTokensToBeSkipped(ptgs, i, dist);
                            Ptg nextPtg = ptgs[i + 1];
                            if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg)
                            {
                                // this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
                                i++;
                                stack.Push(BoolEval.FALSE);
                            }
                        }
                        continue;
                    }
                    if (attrPtg.IsSkip)
                    {
                        int dist = attrPtg.Data + 1;
                        i += CountTokensToBeSkipped(ptgs, i, dist);
                        if (stack.Peek() == MissingArgEval.instance)
                        {
                            stack.Pop();
                            stack.Push(BlankEval.instance);
                        }
                        continue;
                    }
                }
                if (ptg is ControlPtg)
                {
                    // skip Parentheses, Attr, etc
                    continue;
                }
                if (ptg is MemFuncPtg|| ptg is MemAreaPtg)
                {
                    // can ignore, rest of Tokens for this expression are in OK RPN order
                    continue;
                }
                if (ptg is MemErrPtg) { continue; }

                ValueEval opResult;
                if (ptg is OperationPtg)
                {
                    OperationPtg optg = (OperationPtg)ptg;

                    if (optg is UnionPtg) { continue; }

                    int numops = optg.NumberOfOperands;
                    ValueEval[] ops = new ValueEval[numops];

                    // storing the ops in reverse order since they are popping
                    for (int j = numops - 1; j >= 0; j--)
                    {
                        ValueEval p = (ValueEval)stack.Pop();
                        ops[j] = p;
                    }
                    //				logDebug("Invoke " + operation + " (nAgs=" + numops + ")");
                    opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec);
                }
                else
                {
                    opResult = GetEvalForPtg(ptg, ec);
                }
                if (opResult == null)
                {
                    throw new Exception("Evaluation result must not be null");
                }
                //			logDebug("push " + opResult);
                stack.Push(opResult);
                if (dbgEvaluationOutputIndent > 0)
                {
                    EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "    = " + opResult.ToString());
                }
            }

            ValueEval value = ((ValueEval)stack.Pop());
            if (stack.Count != 0)
            {
                throw new InvalidOperationException("evaluation stack not empty");
            }
            ValueEval result = DereferenceResult(value, ec.RowIndex, ec.ColumnIndex);
            if (dbgEvaluationOutputIndent > 0)
            {
                EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "finshed eval of "
                                + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString()
                                + ": " + result.ToString());
                dbgEvaluationOutputIndent--;
                if (dbgEvaluationOutputIndent == 1)
                {
                    // this evaluation is done, reset indent to stop logging
                    dbgEvaluationOutputIndent = -1;
                }
            } // if
            return result;
        }
示例#22
0
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(IEvaluationCell srcCell, int sheetIndex,
                    int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            bool shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
                    : !_stabilityClassifier.IsCellFinal(sheetIndex, rowIndex, columnIndex);
            ValueEval result;
            if (srcCell == null || srcCell.CellType != CellType.Formula)
            {
                result = GetValueFromNonFormulaCell(srcCell);
                if (shouldCellDependencyBeRecorded)
                {
                    tracker.AcceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
                }
                return result;
            }

            FormulaCellCacheEntry cce = _cache.GetOrCreateFormulaCellEntry(srcCell);
            if (shouldCellDependencyBeRecorded || cce.IsInputSensitive)
            {
                tracker.AcceptFormulaDependency(cce);
            }
            IEvaluationListener evalListener = _evaluationListener;
            if (cce.GetValue() == null)
            {
                if (!tracker.StartEvaluate(cce))
                {
                    return ErrorEval.CIRCULAR_REF_ERROR;
                }
                OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

                try
                {
                    Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
                    if (evalListener == null)
                    {
                        result = EvaluateFormula(ec, ptgs);
                    }
                    else
                    {
                        evalListener.OnStartEvaluate(srcCell, cce);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                catch (NotImplementedException e)
                {
                    throw AddExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
                }
                catch (RuntimeException re)
                {
                    if (re.InnerException is WorkbookNotFoundException && _ignoreMissingWorkbooks)
                    {
                        LogInfo(re.InnerException.Message + " - Continuing with cached value!");
                        switch (srcCell.CachedFormulaResultType)
                        {
                            case CellType.Numeric:
                                result = new NumberEval(srcCell.NumericCellValue);
                                break;
                            case CellType.String:
                                result = new StringEval(srcCell.StringCellValue);
                                break;
                            case CellType.Blank:
                                result = BlankEval.instance;
                                break;
                            case CellType.Boolean:
                                result = BoolEval.ValueOf(srcCell.BooleanCellValue);
                                break;
                            case CellType.Error:
                                result = ErrorEval.ValueOf(srcCell.ErrorCellValue);
                                break;
                            case CellType.Formula:
                            default:
                                throw new RuntimeException("Unexpected cell type '" + srcCell.CellType + "' found!");
                        }
                    }
                    else
                    {
                        throw re;
                    }
                }
                finally
                {
                    tracker.EndEvaluate(cce);
                }
            }
            else
            {
                if (evalListener != null)
                {
                    evalListener.OnCacheHit(sheetIndex, rowIndex, columnIndex, cce.GetValue());
                }
                return cce.GetValue();
            }
            if (IsDebugLogEnabled())
            {
                String sheetName = GetSheetName(sheetIndex);
                CellReference cr = new CellReference(rowIndex, columnIndex);
                LogDebug("Evaluated " + sheetName + "!" + cr.FormatAsString() + " To " + cce.GetValue());
            }
            // Usually (result === cce.getValue())
            // But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null)
            // When circular references are detected, the cache entry is only updated for
            // the top evaluation frame
            //return cce.GetValue();
            return result;
        }
示例#23
0
 private ValueEval ProcessNameEval(ValueEval eval, OperationEvaluationContext ec)
 {
     if (eval is ExternalNameEval)
     {
         IEvaluationName name = ((ExternalNameEval)eval).Name;
         return GetEvalForNameRecord(name, ec);
     }
     return eval;
 }
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(EvaluationCell srcCell, int sheetIndex,
                    int rowIndex, int columnIndex, EvaluationTracker tracker)
        {

            if (srcCell == null || srcCell.CellType != CellType.FORMULA)
            {
                ValueEval result = GetValueFromNonFormulaCell(srcCell);
                tracker.AcceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
                return result;
            }

            FormulaCellCacheEntry cce = _cache.GetOrCreateFormulaCellEntry(srcCell);
            tracker.AcceptFormulaDependency(cce);
            IEvaluationListener evalListener = _evaluationListener;
            if (cce.GetValue() == null)
            {
                if (!tracker.StartEvaluate(cce))
                {
                    return ErrorEval.CIRCULAR_REF_ERROR;
                }
                OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

                try
                {
                    ValueEval result;

                    Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
                    if (evalListener == null)
                    {
                        result = EvaluateFormula(ec, ptgs);
                    }
                    else
                    {
                        evalListener.OnStartEvaluate(srcCell, cce);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                finally
                {
                    tracker.EndEvaluate(cce);
                }
            }
            else
            {
                if (evalListener != null)
                {
                    evalListener.OnCacheHit(sheetIndex, rowIndex, columnIndex, cce.GetValue());
                }
                return cce.GetValue();
            }
            if (IsDebugLogEnabled())
            {
                String sheetName = GetSheetName(sheetIndex);
                CellReference cr = new CellReference(rowIndex, columnIndex);
                LogDebug("Evaluated " + sheetName + "!" + cr.FormatAsString() + " To " + cce.GetValue().ToString());
            }
            return cce.GetValue();
        }
示例#25
0
        private static ValueEval EvaluateIndirect(OperationEvaluationContext ec, String text,
                bool isA1style)
        {
            // Search backwards for '!' because sheet names can contain '!'
            int plingPos = text.LastIndexOf('!');

            String workbookName;
            String sheetName;
            String refText; // whitespace around this Gets Trimmed OK
            if (plingPos < 0)
            {
                workbookName = null;
                sheetName = null;
                refText = text;
            }
            else
            {
                String[] parts = ParseWorkbookAndSheetName(text.Substring(0, plingPos));
                if (parts == null)
                {
                    return ErrorEval.REF_INVALID;
                }
                workbookName = parts[0];
                sheetName = parts[1];
                refText = text.Substring(plingPos + 1);
            }

            String refStrPart1;
            String refStrPart2;

            int colonPos = refText.IndexOf(':');
            if (colonPos < 0)
            {
                refStrPart1 = refText.Trim();
                refStrPart2 = null;
            }
            else
            {
                refStrPart1 = refText.Substring(0, colonPos).Trim();
                refStrPart2 = refText.Substring(colonPos + 1).Trim();
            }
            return ec.GetDynamicReference(workbookName, sheetName, refStrPart1, refStrPart2, isA1style);
        }
        // visibility raised for testing
        /* package */
        public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs)
        {

            Stack<ValueEval> stack = new Stack<ValueEval>();
            for (int i = 0, iSize = ptgs.Length; i < iSize; i++)
            {

                // since we don't know how To handle these yet :(
                Ptg ptg = ptgs[i];
                if (ptg is AttrPtg)
                {
                    AttrPtg attrPtg = (AttrPtg)ptg;
                    if (attrPtg.IsSum)
                    {
                        // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator
                        // expects the equivalent function Token
                        byte nArgs = 1;  // tAttrSum always Has 1 parameter
                        ptg = new FuncVarPtg("SUM", nArgs);
                    }
                    				if (attrPtg.IsOptimizedChoose) {
					ValueEval arg0 = stack.Pop();
					int[] jumpTable = attrPtg.JumpTable;
					int dist;
					int nChoices = jumpTable.Length;
					try {
						int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
						if (switchIndex<1 || switchIndex > nChoices) {
							stack.Push(ErrorEval.VALUE_INVALID);
							dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
						} else {
							dist = jumpTable[switchIndex-1];
						}
					} catch (EvaluationException e) {
						stack.Push(e.GetErrorEval());
						dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
					}
					// Encoded dist for tAttrChoose includes size of jump table, but
					// countTokensToBeSkipped() does not (it counts whole tokens).
					dist -= nChoices*2+2; // subtract jump table size
					i+= CountTokensToBeSkipped(ptgs, i, dist);
					continue;
				}
				if (attrPtg.IsOptimizedIf) {
					ValueEval arg0 = stack.Pop();
					bool evaluatedPredicate;
					try {
						evaluatedPredicate = If.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
					} catch (EvaluationException e) {
						stack.Push(e.GetErrorEval());
						int dist = attrPtg.Data;
						i+= CountTokensToBeSkipped(ptgs, i, dist);
						attrPtg = (AttrPtg) ptgs[i];
						dist = attrPtg.Data+1;
						i+= CountTokensToBeSkipped(ptgs, i, dist);
						continue;
					}
					if (evaluatedPredicate) {
						// nothing to skip - true param folows
					} else {
						int dist = attrPtg.Data;
						i+= CountTokensToBeSkipped(ptgs, i, dist);
						Ptg nextPtg = ptgs[i+1];
						if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg) {
							// this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
							i++;
							stack.Push(BoolEval.FALSE);
						}
					}
					continue;
				}
				if (attrPtg.IsSkip) {
					int dist = attrPtg.Data+1;
					i+= CountTokensToBeSkipped(ptgs, i, dist);
					if (stack.Peek() == MissingArgEval.instance) {
						stack.Pop();
						stack.Push(BlankEval.instance);
					}
					continue;
				}
                }
                if (ptg is ControlPtg)
                {
                    // skip Parentheses, Attr, etc
                    continue;
                }
                if (ptg is MemFuncPtg)
                {
                    // can ignore, rest of Tokens for this expression are in OK RPN order
                    continue;
                }
                if (ptg is MemErrPtg) { continue; }

                ValueEval opResult;
                if (ptg is OperationPtg)
                {
                    OperationPtg optg = (OperationPtg)ptg;

                    if (optg is UnionPtg) { continue; }

                    int numops = optg.NumberOfOperands;
                    ValueEval[] ops = new ValueEval[numops];

                    // storing the ops in reverse order since they are popping
                    for (int j = numops - 1; j >= 0; j--)
                    {
                        ValueEval p = (ValueEval)stack.Pop();
                        ops[j] = p;
                    }
                    //				logDebug("Invoke " + operation + " (nAgs=" + numops + ")");
                    opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec);
                }
                else
                {
                    opResult = GetEvalForPtg(ptg, ec);
                }
                if (opResult == null)
                {
                    throw new Exception("Evaluation result must not be null");
                }
                //			logDebug("push " + opResult);
                stack.Push(opResult);
            }

            ValueEval value = ((ValueEval)stack.Pop());
            if (stack.Count != 0)
            {
                throw new InvalidOperationException("evaluation stack not empty");
            }
            value = DereferenceValue(value, ec.RowIndex, ec.ColumnIndex);
            if (value == BlankEval.instance)
            {
                // Note Excel behaviour here. A blank value is converted To zero.
                return NumberEval.ZERO;
                // Formulas _never_ evaluate To blank.  If a formula appears To have evaluated To
                // blank, the actual value is empty string. This can be verified with ISBLANK().
            }
            return value;
        }
示例#27
0
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     return ErrorEval.NUM_ERROR;
 }
 private ValueEval EvaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec)
 {
     if (ptgs.Length > 1)
     {
         throw new Exception("Complex name formulas not supported yet");
     }
     return GetEvalForPtg(ptgs[0], ec);
 }
示例#29
0
 private OperationEvaluationContext CreateContext()
 {
     HSSFWorkbook wb = new HSSFWorkbook();
     wb.CreateSheet();
     HSSFEvaluationWorkbook workbook = HSSFEvaluationWorkbook.Create(wb);
     WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(workbook, new IStabilityClassifier1(), null);
     OperationEvaluationContext ctx = new OperationEvaluationContext(workbookEvaluator,
             workbook, 0, 0, 0, null);
     return ctx;
 }
示例#30
0
 public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec)
 {
     throw new NotImplementedException(_functionName);
 }
        // Fetch the workbook this refers to, and the name as defined with that
        private ValueEval GetExternalNameXEval(ExternalName externName, String workbookName)
        {
            try
            {
                WorkbookEvaluator refWorkbookEvaluator = _bookEvaluator.GetOtherWorkbookEvaluator(workbookName);
                IEvaluationName evaluationName = refWorkbookEvaluator.GetName(externName.Name, externName.Ix - 1);
                if (evaluationName != null && evaluationName.HasFormula)
                {
                    if (evaluationName.NameDefinition.Length > 1)
                    {
                        throw new Exception("Complex name formulas not supported yet");
                    }
                    // Need to Evaluate the reference in the context of the other book
                    OperationEvaluationContext refWorkbookContext = new OperationEvaluationContext(
                            refWorkbookEvaluator, refWorkbookEvaluator.Workbook, -1, -1, -1, _tracker);

                    Ptg ptg = evaluationName.NameDefinition[0];
                    if (ptg is Ref3DPtg)
                    {
                        Ref3DPtg ref3D = (Ref3DPtg)ptg;
                        return refWorkbookContext.GetRef3DEval(ref3D);
                    }
                    else if (ptg is Ref3DPxg)
                    {
                        Ref3DPxg ref3D = (Ref3DPxg)ptg;
                        return refWorkbookContext.GetRef3DEval(ref3D);
                    }
                    else if (ptg is Area3DPtg)
                    {
                        Area3DPtg area3D = (Area3DPtg)ptg;
                        return refWorkbookContext.GetArea3DEval(area3D);
                    }
                    else if (ptg is Area3DPxg)
                    {
                        Area3DPxg area3D = (Area3DPxg)ptg;
                        return refWorkbookContext.GetArea3DEval(area3D);
                    }

                }
                return ErrorEval.REF_INVALID;
            }
            catch (WorkbookNotFoundException)
            {
                return ErrorEval.REF_INVALID;
            }
        }
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(EvaluationCell srcCell, int sheetIndex,
                                      int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            if (srcCell == null || srcCell.CellType != CellType.FORMULA)
            {
                ValueEval result = GetValueFromNonFormulaCell(srcCell);
                tracker.AcceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
                return(result);
            }

            FormulaCellCacheEntry cce = _cache.GetOrCreateFormulaCellEntry(srcCell);

            tracker.AcceptFormulaDependency(cce);
            IEvaluationListener evalListener = _evaluationListener;

            if (cce.GetValue() == null)
            {
                if (!tracker.StartEvaluate(cce))
                {
                    return(ErrorEval.CIRCULAR_REF_ERROR);
                }
                OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

                try
                {
                    ValueEval result;

                    Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
                    if (evalListener == null)
                    {
                        result = EvaluateFormula(ec, ptgs);
                    }
                    else
                    {
                        evalListener.OnStartEvaluate(srcCell, cce);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                finally
                {
                    tracker.EndEvaluate(cce);
                }
            }
            else
            {
                if (evalListener != null)
                {
                    evalListener.OnCacheHit(sheetIndex, rowIndex, columnIndex, cce.GetValue());
                }
                return(cce.GetValue());
            }
            if (IsDebugLogEnabled())
            {
                String        sheetName = GetSheetName(sheetIndex);
                CellReference cr        = new CellReference(rowIndex, columnIndex);
                LogDebug("Evaluated " + sheetName + "!" + cr.FormatAsString() + " To " + cce.GetValue().ToString());
            }
            return(cce.GetValue());
        }
示例#33
0
        private ValueEval GetEvalForNameRecord(IEvaluationName nameRecord, OperationEvaluationContext ec)
        {
            if (nameRecord.IsFunctionName)
            {
                return new FunctionNameEval(nameRecord.NameText);
            }
            if (nameRecord.HasFormula)
            {
                return EvaluateNameFormula(nameRecord.NameDefinition, ec);
            }

            throw new Exception("Don't now how to Evalate name '" + nameRecord.NameText + "'");
        }