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
This commit is contained in:
parent
d97867e5be
commit
3872e620a7
@ -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) {
|
||||
|
23
src/java/org/apache/poi/ss/formula/SheetRange.java
Normal file
23
src/java/org/apache/poi/ss/formula/SheetRange.java
Normal file
@ -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();
|
||||
}
|
@ -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;
|
||||
|
@ -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/>
|
||||
|
@ -17,9 +17,9 @@
|
||||
|
||||
package org.apache.poi.ss.formula.eval;
|
||||
|
||||
import org.apache.poi.ss.formula.SheetRange;
|
||||
|
||||
/**
|
||||
* @author Amol S Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
* 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
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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/>
|
||||
|
@ -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);
|
||||
|
@ -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 < amolweb at ya hoo dot com >
|
||||
@ -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);
|
||||
|
@ -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 < amolweb at ya hoo dot com >
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 < amolweb at ya hoo dot com >
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user