aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Burch <nick@apache.org>2014-07-25 15:46:05 +0000
committerNick Burch <nick@apache.org>2014-07-25 15:46:05 +0000
commited4ee108b459e4adea6d6c2aebde0cbe78fc43ad (patch)
tree6e061604b8634ffa735205ee36ddb2529e6b7ec6
parenteb66cf9a089050c1d950ab5a9801b40e0c817c7c (diff)
downloadpoi-ed4ee108b459e4adea6d6c2aebde0cbe78fc43ad.tar.gz
poi-ed4ee108b459e4adea6d6c2aebde0cbe78fc43ad.zip
Update the RefEval method signature to cope with multi-sheet references, and have appropriate functions take advantage of this. For bug #55906
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613453 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/poi/ss/formula/LazyRefEval.java15
-rw-r--r--src/java/org/apache/poi/ss/formula/SheetRange.java23
-rw-r--r--src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java2
-rw-r--r--src/java/org/apache/poi/ss/formula/eval/OperandResolver.java6
-rw-r--r--src/java/org/apache/poi/ss/formula/eval/RefEval.java27
-rw-r--r--src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java35
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java25
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/CountUtils.java21
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Countblank.java4
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Countif.java4
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/EDate.java21
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java7
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/LookupUtils.java34
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Match.java8
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Mode.java6
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java6
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/Sumproduct.java7
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/T.java4
-rw-r--r--src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java10
-rw-r--r--src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java9
-rw-r--r--src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java16
-rw-r--r--src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java19
22 files changed, 227 insertions, 82 deletions
diff --git a/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/src/java/org/apache/poi/ss/formula/LazyRefEval.java
index b813cb7ebc..a483992f92 100644
--- a/src/java/org/apache/poi/ss/formula/LazyRefEval.java
+++ b/src/java/org/apache/poi/ss/formula/LazyRefEval.java
@@ -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
index 0000000000..ab7ccab83a
--- /dev/null
+++ b/src/java/org/apache/poi/ss/formula/SheetRange.java
@@ -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();
+}
diff --git a/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java b/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java
index 92200dd642..a69d76d145 100644
--- a/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java
+++ b/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java
@@ -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;
diff --git a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
index eea1a3828c..8e0ea3ba85 100644
--- a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
+++ b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
@@ -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/>
diff --git a/src/java/org/apache/poi/ss/formula/eval/RefEval.java b/src/java/org/apache/poi/ss/formula/eval/RefEval.java
index 768e90a8a5..c8e0296fe2 100644
--- a/src/java/org/apache/poi/ss/formula/eval/RefEval.java
+++ b/src/java/org/apache/poi/ss/formula/eval/RefEval.java
@@ -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
diff --git a/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java b/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java
index 83d20fb49a..bd96c4eb81 100644
--- a/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java
+++ b/src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java
@@ -17,21 +17,46 @@
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() {
diff --git a/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java b/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
index 9e796e7040..0970dc0bb2 100644
--- a/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
@@ -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;
diff --git a/src/java/org/apache/poi/ss/formula/functions/CountUtils.java b/src/java/org/apache/poi/ss/formula/functions/CountUtils.java
index 54a4e7c6ac..6c5fbce7dc 100644
--- a/src/java/org/apache/poi/ss/formula/functions/CountUtils.java
+++ b/src/java/org/apache/poi/ss/formula/functions/CountUtils.java
@@ -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;
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/Countblank.java b/src/java/org/apache/poi/ss/formula/functions/Countblank.java
index 843af7ca7f..522e185a6c 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Countblank.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Countblank.java
@@ -17,12 +17,12 @@
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 {
diff --git a/src/java/org/apache/poi/ss/formula/functions/Countif.java b/src/java/org/apache/poi/ss/formula/functions/Countif.java
index c988864333..ce73b8563f 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Countif.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Countif.java
@@ -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 {
diff --git a/src/java/org/apache/poi/ss/formula/functions/EDate.java b/src/java/org/apache/poi/ss/formula/functions/EDate.java
index 75e5509940..78c773d4a9 100644
--- a/src/java/org/apache/poi/ss/formula/functions/EDate.java
+++ b/src/java/org/apache/poi/ss/formula/functions/EDate.java
@@ -17,13 +17,18 @@
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();
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java b/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java
index 4fed7f9e98..870d08bc75 100644
--- a/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java
@@ -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);
}
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java b/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java
index 46db37e04b..fce2642458 100644
--- a/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java
+++ b/src/java/org/apache/poi/ss/formula/functions/LookupUtils.java
@@ -17,6 +17,10 @@
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/>
diff --git a/src/java/org/apache/poi/ss/formula/functions/Match.java b/src/java/org/apache/poi/ss/formula/functions/Match.java
index 8534222cfb..e4b27f5588 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Match.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Match.java
@@ -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);
diff --git a/src/java/org/apache/poi/ss/formula/functions/Mode.java b/src/java/org/apache/poi/ss/formula/functions/Mode.java
index 2816d7823d..1e13504bbf 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Mode.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Mode.java
@@ -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);
diff --git a/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java b/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java
index 9c89f69dbc..528fa9bf4a 100644
--- a/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java
@@ -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);
diff --git a/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java b/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java
index a7541c683c..8bae16e3b2 100644
--- a/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java
+++ b/src/java/org/apache/poi/ss/formula/functions/Sumproduct.java
@@ -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;
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/T.java b/src/java/org/apache/poi/ss/formula/functions/T.java
index 23fb5928c9..1e74c5b106 100644
--- a/src/java/org/apache/poi/ss/formula/functions/T.java
+++ b/src/java/org/apache/poi/ss/formula/functions/T.java
@@ -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);
diff --git a/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java b/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java
index 10b496769a..da2a0f3127 100644
--- a/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java
@@ -17,13 +17,13 @@
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);
}
}
diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java
index fe28f1cd23..67cbcb2f7a 100644
--- a/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java
+++ b/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java
@@ -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,
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java b/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java
index 31d5250704..e294be59f3 100644
--- a/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java
+++ b/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java
@@ -17,17 +17,17 @@
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) {
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java b/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java
index 6e337003b3..3a5d527b77 100644
--- a/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java
+++ b/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java
@@ -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();
}