]> source.dussan.org Git - poi.git/commitdiff
Update the RefEval method signature to cope with multi-sheet references, and have...
authorNick Burch <nick@apache.org>
Fri, 25 Jul 2014 15:46:05 +0000 (15:46 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Jul 2014 15:46:05 +0000 (15:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613453 13f79535-47bb-0310-9956-ffa450edef68

22 files changed:
src/java/org/apache/poi/ss/formula/LazyRefEval.java
src/java/org/apache/poi/ss/formula/SheetRange.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java
src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
src/java/org/apache/poi/ss/formula/eval/RefEval.java
src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java
src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
src/java/org/apache/poi/ss/formula/functions/CountUtils.java
src/java/org/apache/poi/ss/formula/functions/Countblank.java
src/java/org/apache/poi/ss/formula/functions/Countif.java
src/java/org/apache/poi/ss/formula/functions/EDate.java
src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java
src/java/org/apache/poi/ss/formula/functions/LookupUtils.java
src/java/org/apache/poi/ss/formula/functions/Match.java
src/java/org/apache/poi/ss/formula/functions/Mode.java
src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java
src/java/org/apache/poi/ss/formula/functions/Sumproduct.java
src/java/org/apache/poi/ss/formula/functions/T.java
src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java
src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java
src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java
src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java

index b813cb7ebc67f36ec4b3db6bb2073a081f9f720a..a483992f92384cb29180ffc8877e083fe28c219e 100644 (file)
@@ -26,22 +26,21 @@ import org.apache.poi.ss.util.CellReference;
 
 /**
  * Provides Lazy Evaluation to a 3D Reference
- * 
- * TODO Provide access to multiple sheets where present
  */
 final class LazyRefEval extends RefEvalBase {
        private final SheetRangeEvaluator _evaluator;
 
        public LazyRefEval(int rowIndex, int columnIndex, SheetRangeEvaluator sre) {
-               super(rowIndex, columnIndex);
-               if (sre == null) {
-                       throw new IllegalArgumentException("sre must not be null");
-               }
+               super(sre, rowIndex, columnIndex);
                _evaluator = sre;
        }
 
-       public ValueEval getInnerValueEval() {
-               return _evaluator.getEvalForCell(_evaluator.getFirstSheetIndex(), getRow(), getColumn());
+       @Deprecated
+    public ValueEval getInnerValueEval() {
+        return getInnerValueEval(_evaluator.getFirstSheetIndex());
+    }
+       public ValueEval getInnerValueEval(int sheetIndex) {
+               return _evaluator.getEvalForCell(sheetIndex, getRow(), getColumn());
        }
 
        public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
diff --git a/src/java/org/apache/poi/ss/formula/SheetRange.java b/src/java/org/apache/poi/ss/formula/SheetRange.java
new file mode 100644 (file)
index 0000000..ab7ccab
--- /dev/null
@@ -0,0 +1,23 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula;
+
+public interface SheetRange {
+    public int getFirstSheetIndex();
+    public int getLastSheetIndex();
+}
index 92200dd642678ba3d3eb5a15e35f2c26f340f2a0..a69d76d145ce267c3db59446623acc8611fc0964 100644 (file)
@@ -22,7 +22,7 @@ import org.apache.poi.ss.formula.eval.ValueEval;
 /**
  * Evaluator for returning cells or sheets for a range of sheets
  */
-final class SheetRangeEvaluator {
+final class SheetRangeEvaluator implements SheetRange {
        private final int _firstSheetIndex;
     private final int _lastSheetIndex;
        private SheetRefEvaluator[] _sheetEvaluators;
index eea1a3828c95c0d2ea59e95e46fe9dde995d99d3..8e0ea3ba85f5882597c7b7ef2b6e0b670ae374a1 100644 (file)
@@ -59,7 +59,7 @@ public final class OperandResolver {
                        throws EvaluationException {
                ValueEval result;
                if (arg instanceof RefEval) {
-                       result = ((RefEval) arg).getInnerValueEval();
+                       result = chooseSingleElementFromRef((RefEval) arg);
                } else if (arg instanceof AreaEval) {
                        result = chooseSingleElementFromArea((AreaEval) arg, srcCellRow, srcCellCol);
                } else {
@@ -174,6 +174,10 @@ public final class OperandResolver {
                }
                return ae.getAbsoluteValue(ae.getFirstRow(), srcCellCol);
        }
+       
+       private static ValueEval chooseSingleElementFromRef(RefEval ref) {
+           return ref.getInnerValueEval( ref.getFirstSheetIndex() );
+       }
 
        /**
         * Applies some conversion rules if the supplied value is not already an integer.<br/>
index 768e90a8a5bc346502630775b49ada0aed10fa97..c8e0296fe24ed23f7fd90a7ed4d9c894c70094c2 100644 (file)
@@ -17,9 +17,9 @@
 
 package org.apache.poi.ss.formula.eval;
 
+import org.apache.poi.ss.formula.SheetRange;
+
 /**
- * @author Amol S Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
  * RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval
  * impl should contain reference to the original ReferencePtg or Ref3DPtg as
  * well as the final "value" resulting from the evaluation of the cell
@@ -27,12 +27,11 @@ package org.apache.poi.ss.formula.eval;
  * value object should be of type NumberEval; if cell type is CELL_TYPE_STRING,
  * contained value object should be of type StringEval
  */
-public interface RefEval extends ValueEval {
-
+public interface RefEval extends ValueEval, SheetRange {
     /**
-     * @return the evaluated value of the cell referred to by this RefEval.
+     * @return the evaluated value of the cell referred to by this RefEval on the given sheet
      */
-    ValueEval getInnerValueEval();
+    ValueEval getInnerValueEval(int sheetIndex);
 
     /**
      * returns the zero based column index.
@@ -43,6 +42,22 @@ public interface RefEval extends ValueEval {
      * returns the zero based row index.
      */
     int getRow();
+    
+    /**
+     * returns the first sheet index this applies to
+     */
+    int getFirstSheetIndex();
+
+    /**
+     * returns the last sheet index this applies to, which
+     *  will be the same as the first for a 2D and many 3D references
+     */
+    int getLastSheetIndex();
+    
+    /**
+     * returns the number of sheets this applies to
+     */
+    int getNumberOfSheets();
 
     /**
      * Creates an {@link AreaEval} offset by a relative amount from this RefEval
index 83d20fb49aaee7e1bb353605aba73295db147690..bd96c4eb819abf238b98a9270d882202e27fa483 100644 (file)
 
 package org.apache.poi.ss.formula.eval;
 
+import org.apache.poi.ss.formula.SheetRange;
+
 /**
  * Common base class for implementors of {@link RefEval}
- *
- * @author Josh Micich
  */
 public abstract class RefEvalBase implements RefEval {
-
+    private final int _firstSheetIndex;
+    private final int _lastSheetIndex;
        private final int _rowIndex;
        private final int _columnIndex;
 
-       protected RefEvalBase(int rowIndex, int columnIndex) {
+    protected RefEvalBase(SheetRange sheetRange, int rowIndex, int columnIndex) {
+        if (sheetRange == null) {
+            throw new IllegalArgumentException("sheetRange must not be null");
+        }
+        _firstSheetIndex = sheetRange.getFirstSheetIndex();
+        _lastSheetIndex = sheetRange.getLastSheetIndex();
+        _rowIndex = rowIndex;
+        _columnIndex = columnIndex;
+    }
+       protected RefEvalBase(int firstSheetIndex, int lastSheetIndex, int rowIndex, int columnIndex) {
+           _firstSheetIndex = firstSheetIndex;
+           _lastSheetIndex = lastSheetIndex;
                _rowIndex = rowIndex;
                _columnIndex = columnIndex;
        }
-       public final int getRow() {
+    protected RefEvalBase(int onlySheetIndex, int rowIndex, int columnIndex) {
+        this(onlySheetIndex, onlySheetIndex, rowIndex, columnIndex);
+    }
+    
+       public int getNumberOfSheets() {
+           return _lastSheetIndex-_firstSheetIndex+1;
+    }
+    public int getFirstSheetIndex() {
+        return _firstSheetIndex;
+    }
+    public int getLastSheetIndex() {
+        return _lastSheetIndex;
+    }
+    public final int getRow() {
                return _rowIndex;
        }
        public final int getColumn() {
index 9e796e704027d956c660039ef0729c24f000f2ad..0970dc0bb25f192edb629a0cea832b33384c398d 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.EvaluationException;
@@ -24,7 +25,6 @@ import org.apache.poi.ss.formula.eval.MissingArgEval;
 import org.apache.poi.ss.formula.eval.OperandResolver;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * Here are the general rules concerning Boolean functions:
@@ -61,6 +61,7 @@ public abstract class BooleanFunction implements Function {
                 * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result
                 */
                for (int i=0, iSize=args.length; i<iSize; i++) {
+            Boolean tempVe;
                        ValueEval arg = args[i];
                        if (arg instanceof TwoDEval) {
                                TwoDEval ae = (TwoDEval) arg;
@@ -69,7 +70,7 @@ public abstract class BooleanFunction implements Function {
                                for (int rrIx=0; rrIx<height; rrIx++) {
                                        for (int rcIx=0; rcIx<width; rcIx++) {
                                                ValueEval ve = ae.getValue(rrIx, rcIx);
-                                               Boolean tempVe = OperandResolver.coerceValueToBoolean(ve, true);
+                                               tempVe = OperandResolver.coerceValueToBoolean(ve, true);
                                                if (tempVe != null) {
                                                        result = partialEvaluate(result, tempVe.booleanValue());
                                                        atleastOneNonBlank = true;
@@ -78,17 +79,25 @@ public abstract class BooleanFunction implements Function {
                                }
                                continue;
                        }
-                       Boolean tempVe;
-                       if (arg instanceof RefEval) {
-                               ValueEval ve = ((RefEval) arg).getInnerValueEval();
-                               tempVe = OperandResolver.coerceValueToBoolean(ve, true);
-                       } else if (arg == MissingArgEval.instance) {
+            if (arg instanceof RefEval) {
+                RefEval re = (RefEval) arg;
+                for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
+                    ValueEval ve = re.getInnerValueEval(sIx);
+                    tempVe = OperandResolver.coerceValueToBoolean(ve, true);
+                    if (tempVe != null) {
+                        result = partialEvaluate(result, tempVe.booleanValue());
+                        atleastOneNonBlank = true;
+                    }
+                }
+                continue;
+            }
+                       
+                       if (arg == MissingArgEval.instance) {
                                tempVe = null;          // you can leave out parameters, they are simply ignored
                        } else {
                                tempVe = OperandResolver.coerceValueToBoolean(arg, false);
                        }
 
-
                        if (tempVe != null) {
                                result = partialEvaluate(result, tempVe.booleanValue());
                                atleastOneNonBlank = true;
index 54a4e7c6ac12aaa92e8b504e06b57dc48de888b0..6c5fbce7dcc5925c0ec2a6b69f4b5ba02b9dd494 100644 (file)
@@ -17,9 +17,9 @@
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * Common logic for COUNT, COUNTA and COUNTIF
@@ -67,13 +67,18 @@ final class CountUtils {
                return result;
        }
        /**
-        * @return 1 if the evaluated cell matches the specified criteria
+     * @return the number of evaluated cells in the range that match the specified criteria
         */
-       public static int countMatchingCell(RefEval refEval, I_MatchPredicate criteriaPredicate) {
-               if(criteriaPredicate.matches(refEval.getInnerValueEval())) {
-                       return 1;
-               }
-               return 0;
+       public static int countMatchingCellsInRef(RefEval refEval, I_MatchPredicate criteriaPredicate) {
+           int result = 0;
+           
+           for (int sIx = refEval.getFirstSheetIndex(); sIx <= refEval.getLastSheetIndex(); sIx++) {
+               ValueEval ve = refEval.getInnerValueEval(sIx);
+            if(criteriaPredicate.matches(ve)) {
+                result++;
+            }
+           }
+               return result;
        }
        public static int countArg(ValueEval eval, I_MatchPredicate criteriaPredicate) {
                if (eval == null) {
@@ -83,7 +88,7 @@ final class CountUtils {
                        return countMatchingCellsInArea((TwoDEval) eval, criteriaPredicate);
                }
                if (eval instanceof RefEval) {
-                       return CountUtils.countMatchingCell((RefEval) eval, criteriaPredicate);
+                       return CountUtils.countMatchingCellsInRef((RefEval) eval, criteriaPredicate);
                }
                return criteriaPredicate.matches(eval) ? 1 : 0;
        }
index 843af7ca7f1242e359169faa2a479c78280c6cc2..522e185a6c93e98213d2af7dc653bd64c41c25ba 100644 (file)
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * Implementation for the function COUNTBLANK
@@ -41,7 +41,7 @@ public final class Countblank extends Fixed1ArgFunction {
 
                double result;
                if (arg0 instanceof RefEval) {
-                       result = CountUtils.countMatchingCell((RefEval) arg0, predicate);
+                       result = CountUtils.countMatchingCellsInRef((RefEval) arg0, predicate);
                } else if (arg0 instanceof TwoDEval) {
                        result = CountUtils.countMatchingCellsInArea((TwoDEval) arg0, predicate);
                } else {
index c9888643333814822f35ed8f368bc534d086794b..ce73b8563f50897a65abeae627982c118e9a732d 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.ss.formula.functions;
 
 import java.util.regex.Pattern;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -29,7 +30,6 @@ import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate;
-import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.usermodel.ErrorConstants;
 
 /**
@@ -444,7 +444,7 @@ public final class Countif extends Fixed2ArgFunction {
        private double countMatchingCellsInArea(ValueEval rangeArg, I_MatchPredicate criteriaPredicate) {
 
                if (rangeArg instanceof RefEval) {
-                       return CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate);
+                       return CountUtils.countMatchingCellsInRef((RefEval) rangeArg, criteriaPredicate);
                } else if (rangeArg instanceof TwoDEval) {
                        return CountUtils.countMatchingCellsInArea((TwoDEval) rangeArg, criteriaPredicate);
                } else {
index 75e55099400313e45d07f88521ca17b414561621..78c773d4a96ea60a055ecee11124508a4efaedcc 100644 (file)
 
 package org.apache.poi.ss.formula.functions;
 
-import org.apache.poi.ss.formula.OperationEvaluationContext;
-import org.apache.poi.ss.formula.eval.*;
-import org.apache.poi.ss.usermodel.DateUtil;
-
 import java.util.Calendar;
 import java.util.Date;
 
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.BlankEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.EvaluationException;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.RefEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.usermodel.DateUtil;
+
 /**
  * Implementation for Excel EDATE () function.
  */
@@ -56,7 +61,13 @@ public class EDate implements FreeRefFunction {
             return 0;
         }
         if (arg instanceof RefEval) {
-            ValueEval innerValueEval = ((RefEval) arg).getInnerValueEval();
+            RefEval refEval = (RefEval)arg;
+            if (refEval.getNumberOfSheets() > 1) {
+                // Multi-Sheet references are not supported
+                throw new EvaluationException(ErrorEval.VALUE_INVALID);
+            }
+            
+            ValueEval innerValueEval = refEval.getInnerValueEval(refEval.getFirstSheetIndex());
             if(innerValueEval instanceof NumberEval) {
                 return ((NumberEval) innerValueEval).getNumberValue();
             }
index 4fed7f9e98fe8131813e6470fd7bd072ba2401f1..870d08bc7576414c5713019b4c7f8ee7c1c76520 100644 (file)
@@ -76,13 +76,16 @@ public final class LinearRegressionFunction extends Fixed2ArgFunction {
 
        private static final class RefValueArray extends ValueArray {
                private final RefEval _ref;
+               private final int _width;
                public RefValueArray(RefEval ref) {
-                       super(1);
+                       super(ref.getNumberOfSheets());
                        _ref = ref;
+                       _width = ref.getNumberOfSheets();
                }
 
                protected ValueEval getItemInternal(int index) {
-                       return _ref.getInnerValueEval();
+                   int sIx = (index % _width) + _ref.getFirstSheetIndex(); 
+                       return _ref.getInnerValueEval(sIx);
                }
        }
 
index 46db37e04b7a3d1897f49a9a7fc7767833bfd163..fce2642458b9ccd3591e649671484f3c672cca41 100644 (file)
 
 package org.apache.poi.ss.formula.functions;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -27,10 +31,6 @@ import org.apache.poi.ss.formula.eval.OperandResolver;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH
@@ -104,6 +104,28 @@ final class LookupUtils {
                }
        }
 
+    private static final class SheetVector implements ValueVector {
+        private final RefEval _re;
+        private final int _size;
+
+        public SheetVector(RefEval re) {
+            _size = re.getNumberOfSheets();
+            _re = re;
+        }
+
+        public ValueEval getItem(int index) {
+            if(index >= _size) {
+                throw new ArrayIndexOutOfBoundsException("Specified index (" + index
+                        + ") is outside the allowed range (0.." + (_size-1) + ")");
+            }
+            int sheetIndex = _re.getFirstSheetIndex() + index;
+            return _re.getInnerValueEval(sheetIndex);
+        }
+        public int getSize() {
+            return _size;
+        }
+    }
+
        public static ValueVector createRowVector(TwoDEval tableArray, int relativeRowIndex) {
                return new RowVector(tableArray, relativeRowIndex);
        }
@@ -122,6 +144,10 @@ final class LookupUtils {
                }
                return null;
        }
+       
+       public static ValueVector createVector(RefEval re) {
+           return new SheetVector(re);
+       }
 
        /**
         * Enumeration to support <b>4</b> valued comparison results.<p/>
index 8534222cfb97363058c804824442b7e98297bbe1..e4b27f558820420cca53fed0e07b41c1c85450e8 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.EvaluationException;
 import org.apache.poi.ss.formula.eval.NumberEval;
@@ -28,7 +29,6 @@ import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.LookupUtils.CompareResult;
 import org.apache.poi.ss.formula.functions.LookupUtils.LookupValueComparer;
 import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * Implementation for the MATCH() Excel function.<p/>
@@ -125,7 +125,11 @@ public final class Match extends Var2or3ArgFunction {
        private static ValueVector evaluateLookupRange(ValueEval eval) throws EvaluationException {
                if (eval instanceof RefEval) {
                        RefEval re = (RefEval) eval;
-                       return new SingleValueVector(re.getInnerValueEval());
+                       if (re.getNumberOfSheets() == 1) {
+                           return new SingleValueVector(re.getInnerValueEval(re.getFirstSheetIndex()));
+                       } else {
+                           return LookupUtils.createVector(re);
+                       }
                }
                if (eval instanceof TwoDEval) {
                        ValueVector result = LookupUtils.createVector((TwoDEval)eval);
index 2816d7823def3944854d8803d2ea438b85131a5e..1e13504bbf55551db6c64f33ea0c372dfdd38f69 100644 (file)
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -29,7 +30,6 @@ import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -106,7 +106,9 @@ public final class Mode implements Function {
                }
                if (arg instanceof RefEval) {
                        RefEval re = (RefEval) arg;
-                       collectValue(re.getInnerValueEval(), temp, true);
+                       for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
+                           collectValue(re.getInnerValueEval(sIx), temp, true);
+                       }
                        return;
                }
                collectValue(arg, temp, true);
index 9c89f69dbcf0b2f09405731e10a4c64e264c240f..528fa9bf4aa47248859816871a1504f9ab9bab58 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -27,7 +28,6 @@ import org.apache.poi.ss.formula.eval.OperandResolver;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.StringValueEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -157,7 +157,9 @@ public abstract class MultiOperandNumericFunction implements Function {
                }
                if (operand instanceof RefEval) {
                        RefEval re = (RefEval) operand;
-                       collectValue(re.getInnerValueEval(), true, temp);
+                       for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
+                           collectValue(re.getInnerValueEval(sIx), true, temp);
+                       }
                        return;
                }
                collectValue(operand, false, temp);
index a7541c683c6a0cb35740d0abdae16e4f94f27a4d..8bae16e3b2618b214d438cd04012968e804fc79b 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.AreaEval;
 import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -26,7 +27,6 @@ import org.apache.poi.ss.formula.eval.NumericValueEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
 
 
 /**
@@ -99,7 +99,10 @@ public final class Sumproduct implements Function {
                ValueEval eval;
                if (arg instanceof RefEval) {
                        RefEval re = (RefEval) arg;
-                       eval = re.getInnerValueEval();
+                       if (re.getNumberOfSheets() > 1) {
+                throw new EvaluationException(ErrorEval.VALUE_INVALID);
+                       }
+                       eval = re.getInnerValueEval(re.getFirstSheetIndex());
                } else {
                        eval = arg;
                }
index 23fb5928c9c910bb0e6918d1262744b05c16447a..1e74c5b10622260744d3a94a21cce60bbab2bcc3 100644 (file)
@@ -35,7 +35,9 @@ public final class T extends Fixed1ArgFunction {
     public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
         ValueEval arg = arg0;
         if (arg instanceof RefEval) {
-            arg = ((RefEval) arg).getInnerValueEval();
+            // always use the first sheet
+            RefEval re = (RefEval)arg;
+            arg = re.getInnerValueEval(re.getFirstSheetIndex());
         } else if (arg instanceof AreaEval) {
             // when the arg is an area, choose the top left cell
             arg = ((AreaEval) arg).getRelativeValue(0, 0);
index 10b496769aff002bd9037c06c25f45d59105e50d..da2a0f31274d33bdf7a075876852c4db15b8b006 100644 (file)
 
 package org.apache.poi.ss.formula.functions;
 
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.EvaluationException;
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector;
-import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -61,12 +61,16 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction {
 
        private static final class RefValueArray extends ValueArray {
                private final RefEval _ref;
+        private final int _width;
+        
                public RefValueArray(RefEval ref) {
-                       super(1);
+                       super(ref.getNumberOfSheets());
                        _ref = ref;
+                       _width = ref.getNumberOfSheets();
                }
                protected ValueEval getItemInternal(int index) {
-                       return _ref.getInnerValueEval();
+                   int sIx = (index % _width) + _ref.getFirstSheetIndex(); 
+                       return _ref.getInnerValueEval(sIx);
                }
        }
 
index fe28f1cd2302a1d1dff48a4032b8aca497076f15..67cbcb2f7ad1d885c02f53f9fb0a31abd684f856 100644 (file)
@@ -20,8 +20,6 @@ package org.apache.poi.ss.formula.eval;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.ss.formula.ptg.AreaI;
-import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFRow;
@@ -29,6 +27,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.AreaReference;
 import org.apache.poi.hssf.util.CellReference;
 import org.apache.poi.ss.formula.TwoDEval;
+import org.apache.poi.ss.formula.ptg.AreaI;
+import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea;
 import org.apache.poi.ss.usermodel.CellValue;
 
 /**
@@ -71,11 +71,10 @@ public final class TestRangeEval extends TestCase {
        }
 
        private static final class MockRefEval extends RefEvalBase {
-
                public MockRefEval(int rowIndex, int columnIndex) {
-                       super(rowIndex, columnIndex);
+                       super(-1, -1, rowIndex, columnIndex);
                }
-               public ValueEval getInnerValueEval() {
+               public ValueEval getInnerValueEval(int sheetIndex) {
                        throw new RuntimeException("not expected to be called during this test");
                }
                public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx,
index 31d52507047d12e1100fe8648d401861da5c87ec..e294be59f39f9b5f58c3a1bee4f62d5b2f56c0e8 100644 (file)
 
 package org.apache.poi.ss.formula.functions;
 
-import org.apache.poi.ss.formula.ptg.AreaI;
-import org.apache.poi.ss.formula.ptg.AreaPtg;
-import org.apache.poi.ss.formula.ptg.Ref3DPtg;
-import org.apache.poi.ss.formula.ptg.RefPtg;
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.formula.eval.AreaEval;
 import org.apache.poi.ss.formula.eval.AreaEvalBase;
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.RefEvalBase;
 import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
+import org.apache.poi.ss.formula.ptg.AreaI;
+import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.RefPtg;
 
 /**
  * Test helper class for creating mock <code>Eval</code> objects
@@ -157,14 +157,14 @@ public final class EvalFactory {
        private static final class MockRefEval extends RefEvalBase {
                private final ValueEval _value;
                public MockRefEval(RefPtg ptg, ValueEval value) {
-                       super(ptg.getRow(), ptg.getColumn());
+                       super(-1, -1, ptg.getRow(), ptg.getColumn());
                        _value = value;
                }
                public MockRefEval(Ref3DPtg ptg, ValueEval value) {
-                       super(ptg.getRow(), ptg.getColumn());
+                       super(-1, -1, ptg.getRow(), ptg.getColumn());
                        _value = value;
                }
-               public ValueEval getInnerValueEval() {
+               public ValueEval getInnerValueEval(int sheetIndex) {
                        return _value;
                }
                public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
index 6e337003b3a5d93ffe5b3469181f32ac935005b2..3a5d527b771dc44a000ac88eda35f8d7e7f6e797 100644 (file)
@@ -46,14 +46,23 @@ public class TestEDate extends TestCase{
             throw new UnsupportedOperationException();
         }
 
+        public ValueEval getInnerValueEval(int sheetIndex) {
+            return value;
+        }
+        
+        public int getNumberOfSheets() {
+            return 1;
+        }
+        public int getFirstSheetIndex() {
+            return 0;
+        }
+        public int getLastSheetIndex() {
+            return 0;
+        }        
+        
         public int getRow() {
             throw new UnsupportedOperationException();
         }
-
-        public ValueEval getInnerValueEval() {
-            return value;
-        }
-
         public int getColumn() {
             throw new UnsupportedOperationException();
         }