Created new TwoDEval interface for AreaEvals (in preparation for patch 48292)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@888665 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2ddd88ed0d
commit
18041addf0
@ -17,11 +17,12 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public interface AreaEval extends ValueEval {
|
||||
public interface AreaEval extends TwoDEval {
|
||||
|
||||
/**
|
||||
* returns the 0-based index of the first row in
|
||||
@ -47,20 +48,6 @@ public interface AreaEval extends ValueEval {
|
||||
*/
|
||||
int getLastColumn();
|
||||
|
||||
/**
|
||||
* returns true if the Area's start and end row indexes
|
||||
* are same. This result of this method should agree
|
||||
* with getFirstRow() == getLastRow().
|
||||
*/
|
||||
boolean isRow();
|
||||
|
||||
/**
|
||||
* returns true if the Area's start and end col indexes
|
||||
* are same. This result of this method should agree
|
||||
* with getFirstColumn() == getLastColumn().
|
||||
*/
|
||||
boolean isColumn();
|
||||
|
||||
/**
|
||||
* @return the ValueEval from within this area at the specified row and col index. Never
|
||||
* <code>null</code> (possibly {@link BlankEval}). The specified indexes should be absolute
|
||||
|
@ -66,7 +66,6 @@ public abstract class AreaEvalBase implements AreaEval {
|
||||
public final int getLastRow() {
|
||||
return _lastRow;
|
||||
}
|
||||
|
||||
public final ValueEval getAbsoluteValue(int row, int col) {
|
||||
int rowOffsetIx = row - _firstRow;
|
||||
int colOffsetIx = col - _firstColumn;
|
||||
@ -106,6 +105,10 @@ public abstract class AreaEvalBase implements AreaEval {
|
||||
return _lastRow-_firstRow+1;
|
||||
}
|
||||
|
||||
public final ValueEval getValue(int row, int col) {
|
||||
return getRelativeValue(row, col);
|
||||
}
|
||||
|
||||
public abstract ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
|
||||
|
||||
public int getWidth() {
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Here are the general rules concerning Boolean functions:
|
||||
@ -61,13 +61,13 @@ public abstract class BooleanFunction implements Function {
|
||||
*/
|
||||
for (int i=0, iSize=args.length; i<iSize; i++) {
|
||||
ValueEval arg = args[i];
|
||||
if (arg instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) arg;
|
||||
if (arg instanceof TwoDEval) {
|
||||
TwoDEval ae = (TwoDEval) arg;
|
||||
int height = ae.getHeight();
|
||||
int width = ae.getWidth();
|
||||
for (int rrIx=0; rrIx<height; rrIx++) {
|
||||
for (int rcIx=0; rcIx<width; rcIx++) {
|
||||
ValueEval ve = ae.getRelativeValue(rrIx, rcIx);
|
||||
ValueEval ve = ae.getValue(rrIx, rcIx);
|
||||
Boolean tempVe = OperandResolver.coerceValueToBoolean(ve, true);
|
||||
if (tempVe != null) {
|
||||
result = partialEvaluate(result, tempVe.booleanValue());
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation for Excel COLUMNS function.
|
||||
@ -33,8 +33,8 @@ public final class Columns extends Fixed1ArgFunction {
|
||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
||||
|
||||
int result;
|
||||
if (arg0 instanceof AreaEval) {
|
||||
result = ((AreaEval) arg0).getWidth();
|
||||
if (arg0 instanceof TwoDEval) {
|
||||
result = ((TwoDEval) arg0).getWidth();
|
||||
} else if (arg0 instanceof RefEval) {
|
||||
result = 1;
|
||||
} else { // anything else is not valid argument
|
||||
|
@ -17,9 +17,9 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Common logic for COUNT, COUNTA and COUNTIF
|
||||
@ -41,14 +41,14 @@ final class CountUtils {
|
||||
/**
|
||||
* @return the number of evaluated cells in the range that match the specified criteria
|
||||
*/
|
||||
public static int countMatchingCellsInArea(AreaEval areaEval, I_MatchPredicate criteriaPredicate) {
|
||||
public static int countMatchingCellsInArea(TwoDEval areaEval, I_MatchPredicate criteriaPredicate) {
|
||||
int result = 0;
|
||||
|
||||
int height = areaEval.getHeight();
|
||||
int width = areaEval.getWidth();
|
||||
for (int rrIx=0; rrIx<height; rrIx++) {
|
||||
for (int rcIx=0; rcIx<width; rcIx++) {
|
||||
ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
|
||||
ValueEval ve = areaEval.getValue(rrIx, rcIx);
|
||||
if(criteriaPredicate.matches(ve)) {
|
||||
result++;
|
||||
}
|
||||
@ -69,8 +69,8 @@ final class CountUtils {
|
||||
if (eval == null) {
|
||||
throw new IllegalArgumentException("eval must not be null");
|
||||
}
|
||||
if (eval instanceof AreaEval) {
|
||||
return CountUtils.countMatchingCellsInArea((AreaEval) eval, criteriaPredicate);
|
||||
if (eval instanceof TwoDEval) {
|
||||
return countMatchingCellsInArea((TwoDEval) eval, criteriaPredicate);
|
||||
}
|
||||
if (eval instanceof RefEval) {
|
||||
return CountUtils.countMatchingCell((RefEval) eval, criteriaPredicate);
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation for the function COUNTBLANK
|
||||
@ -42,8 +42,8 @@ public final class Countblank extends Fixed1ArgFunction {
|
||||
double result;
|
||||
if (arg0 instanceof RefEval) {
|
||||
result = CountUtils.countMatchingCell((RefEval) arg0, predicate);
|
||||
} else if (arg0 instanceof AreaEval) {
|
||||
result = CountUtils.countMatchingCellsInArea((AreaEval) arg0, predicate);
|
||||
} else if (arg0 instanceof TwoDEval) {
|
||||
result = CountUtils.countMatchingCellsInArea((TwoDEval) arg0, predicate);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad range arg type (" + arg0.getClass().getName() + ")");
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
@ -30,6 +29,7 @@ import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
import org.apache.poi.ss.usermodel.ErrorConstants;
|
||||
|
||||
/**
|
||||
@ -417,8 +417,8 @@ public final class Countif extends Fixed2ArgFunction {
|
||||
|
||||
if (rangeArg instanceof RefEval) {
|
||||
return CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate);
|
||||
} else if (rangeArg instanceof AreaEval) {
|
||||
return CountUtils.countMatchingCellsInArea((AreaEval) rangeArg, criteriaPredicate);
|
||||
} else if (rangeArg instanceof TwoDEval) {
|
||||
return CountUtils.countMatchingCellsInArea((TwoDEval) rangeArg, criteriaPredicate);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")");
|
||||
}
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
/**
|
||||
* Implementation of the HLOOKUP() function.<p/>
|
||||
*
|
||||
@ -53,7 +53,7 @@ public final class Hlookup extends Var3or4ArgFunction {
|
||||
// Evaluation order:
|
||||
// arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 row_index, fetch result
|
||||
ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
|
||||
AreaEval tableArray = LookupUtils.resolveTableArrayArg(arg1);
|
||||
TwoDEval tableArray = LookupUtils.resolveTableArrayArg(arg1);
|
||||
boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcRowIndex, srcColumnIndex);
|
||||
int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createRowVector(tableArray, 0), isRangeLookup);
|
||||
int rowIndex = LookupUtils.resolveRowOrColIndexArg(arg2, srcRowIndex, srcColumnIndex);
|
||||
@ -71,7 +71,7 @@ public final class Hlookup extends Var3or4ArgFunction {
|
||||
*
|
||||
* @throws EvaluationException (#REF!) if colIndex is too high
|
||||
*/
|
||||
private ValueVector createResultColumnVector(AreaEval tableArray, int rowIndex) throws EvaluationException {
|
||||
private ValueVector createResultColumnVector(TwoDEval tableArray, int rowIndex) throws EvaluationException {
|
||||
if(rowIndex >= tableArray.getHeight()) {
|
||||
throw EvaluationException.invalidRef();
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation for the Excel function INDEX
|
||||
@ -47,7 +48,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
|
||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
|
||||
AreaEval reference = convertFirstArg(arg0);
|
||||
TwoDEval reference = convertFirstArg(arg0);
|
||||
|
||||
boolean colArgWasPassed = false;
|
||||
int columnIx = 0;
|
||||
@ -60,7 +61,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
}
|
||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
|
||||
ValueEval arg2) {
|
||||
AreaEval reference = convertFirstArg(arg0);
|
||||
TwoDEval reference = convertFirstArg(arg0);
|
||||
|
||||
boolean colArgWasPassed = true;
|
||||
try {
|
||||
@ -81,14 +82,14 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
// The formula parser doesn't seem to support this yet. Not sure if the evaluator does either
|
||||
}
|
||||
|
||||
private static AreaEval convertFirstArg(ValueEval arg0) {
|
||||
private static TwoDEval convertFirstArg(ValueEval arg0) {
|
||||
ValueEval firstArg = arg0;
|
||||
if (firstArg instanceof RefEval) {
|
||||
// convert to area ref for simpler code in getValueFromArea()
|
||||
return ((RefEval)firstArg).offset(0, 0, 0, 0);
|
||||
}
|
||||
if((firstArg instanceof AreaEval)) {
|
||||
return (AreaEval) firstArg;
|
||||
if((firstArg instanceof TwoDEval)) {
|
||||
return (TwoDEval) firstArg;
|
||||
}
|
||||
// else the other variation of this function takes an array as the first argument
|
||||
// it seems like interface 'ArrayEval' does not even exist yet
|
||||
@ -117,7 +118,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
* <code>true</code>. This parameter is needed because error codes are slightly
|
||||
* different when only 2 args are passed.
|
||||
*/
|
||||
private static ValueEval getValueFromArea(AreaEval ae, int pRowIx, int pColumnIx,
|
||||
private static ValueEval getValueFromArea(TwoDEval ae, int pRowIx, int pColumnIx,
|
||||
boolean colArgWasPassed, int srcRowIx, int srcColIx) throws EvaluationException {
|
||||
boolean rowArgWasEmpty = pRowIx == 0;
|
||||
boolean colArgWasEmpty = pColumnIx == 0;
|
||||
@ -145,7 +146,13 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
}
|
||||
} else if (ae.isColumn()) {
|
||||
if (rowArgWasEmpty) {
|
||||
rowIx = srcRowIx - ae.getFirstRow();
|
||||
if (ae instanceof AreaEval) {
|
||||
rowIx = srcRowIx - ((AreaEval) ae).getFirstRow();
|
||||
} else {
|
||||
// TODO - ArrayEval
|
||||
// rowIx = relative row of evaluating cell in its array formula cell group
|
||||
throw new RuntimeException("incomplete code - ");
|
||||
}
|
||||
} else {
|
||||
rowIx = pRowIx-1;
|
||||
}
|
||||
@ -164,12 +171,24 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
// Normal case - area ref is 2-D, and both index args were provided
|
||||
// if either arg is missing (or blank) the logic is similar to OperandResolver.getSingleValue()
|
||||
if (rowArgWasEmpty) {
|
||||
rowIx = srcRowIx - ae.getFirstRow();
|
||||
if (ae instanceof AreaEval) {
|
||||
rowIx = srcRowIx - ((AreaEval) ae).getFirstRow();
|
||||
} else {
|
||||
// TODO - ArrayEval
|
||||
// rowIx = relative row of evaluating cell in its array formula cell group
|
||||
throw new RuntimeException("incomplete code - ");
|
||||
}
|
||||
} else {
|
||||
rowIx = pRowIx-1;
|
||||
}
|
||||
if (colArgWasEmpty) {
|
||||
columnIx = srcColIx - ae.getFirstColumn();
|
||||
if (ae instanceof AreaEval) {
|
||||
columnIx = srcColIx - ((AreaEval) ae).getFirstColumn();
|
||||
} else {
|
||||
// TODO - ArrayEval
|
||||
// colIx = relative col of evaluating cell in its array formula cell group
|
||||
throw new RuntimeException("incomplete code - ");
|
||||
}
|
||||
} else {
|
||||
columnIx = pColumnIx-1;
|
||||
}
|
||||
@ -185,7 +204,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
||||
if (rowIx < 0 || columnIx < 0 || rowIx >= height || columnIx >= width) {
|
||||
throw new EvaluationException(ErrorEval.VALUE_INVALID);
|
||||
}
|
||||
return ae.getRelativeValue(rowIx, columnIx);
|
||||
return ae.getValue(rowIx, columnIx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation of Excel function LOOKUP.<p/>
|
||||
@ -48,8 +48,8 @@ public final class Lookup extends Var2or3ArgFunction {
|
||||
ValueEval arg2) {
|
||||
try {
|
||||
ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
|
||||
AreaEval aeLookupVector = LookupUtils.resolveTableArrayArg(arg1);
|
||||
AreaEval aeResultVector = LookupUtils.resolveTableArrayArg(arg2);
|
||||
TwoDEval aeLookupVector = LookupUtils.resolveTableArrayArg(arg1);
|
||||
TwoDEval aeResultVector = LookupUtils.resolveTableArrayArg(arg2);
|
||||
|
||||
ValueVector lookupVector = createVector(aeLookupVector);
|
||||
ValueVector resultVector = createVector(aeResultVector);
|
||||
@ -65,7 +65,7 @@ public final class Lookup extends Var2or3ArgFunction {
|
||||
}
|
||||
}
|
||||
|
||||
private static ValueVector createVector(AreaEval ae) {
|
||||
private static ValueVector createVector(TwoDEval ae) {
|
||||
ValueVector result = LookupUtils.createVector(ae);
|
||||
if (result != null) {
|
||||
return result;
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
@ -28,6 +27,7 @@ import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH
|
||||
@ -47,15 +47,14 @@ final class LookupUtils {
|
||||
|
||||
private static final class RowVector implements ValueVector {
|
||||
|
||||
private final AreaEval _tableArray;
|
||||
private final TwoDEval _tableArray;
|
||||
private final int _size;
|
||||
private final int _rowIndex;
|
||||
|
||||
public RowVector(AreaEval tableArray, int rowIndex) {
|
||||
public RowVector(TwoDEval tableArray, int rowIndex) {
|
||||
_rowIndex = rowIndex;
|
||||
int _rowAbsoluteIndex = tableArray.getFirstRow() + rowIndex;
|
||||
if(!tableArray.containsRow(_rowAbsoluteIndex)) {
|
||||
int lastRowIx = tableArray.getLastRow() - tableArray.getFirstRow();
|
||||
int lastRowIx = tableArray.getHeight() - 1;
|
||||
if(rowIndex < 0 || rowIndex > lastRowIx) {
|
||||
throw new IllegalArgumentException("Specified row index (" + rowIndex
|
||||
+ ") is outside the allowed range (0.." + lastRowIx + ")");
|
||||
}
|
||||
@ -68,7 +67,7 @@ final class LookupUtils {
|
||||
throw new ArrayIndexOutOfBoundsException("Specified index (" + index
|
||||
+ ") is outside the allowed range (0.." + (_size-1) + ")");
|
||||
}
|
||||
return _tableArray.getRelativeValue(_rowIndex, index);
|
||||
return _tableArray.getValue(_rowIndex, index);
|
||||
}
|
||||
public int getSize() {
|
||||
return _size;
|
||||
@ -77,15 +76,14 @@ final class LookupUtils {
|
||||
|
||||
private static final class ColumnVector implements ValueVector {
|
||||
|
||||
private final AreaEval _tableArray;
|
||||
private final TwoDEval _tableArray;
|
||||
private final int _size;
|
||||
private final int _columnIndex;
|
||||
|
||||
public ColumnVector(AreaEval tableArray, int columnIndex) {
|
||||
public ColumnVector(TwoDEval tableArray, int columnIndex) {
|
||||
_columnIndex = columnIndex;
|
||||
int _columnAbsoluteIndex = tableArray.getFirstColumn() + columnIndex;
|
||||
if(!tableArray.containsColumn((short)_columnAbsoluteIndex)) {
|
||||
int lastColIx = tableArray.getLastColumn() - tableArray.getFirstColumn();
|
||||
int lastColIx = tableArray.getWidth()-1;
|
||||
if(columnIndex < 0 || columnIndex > lastColIx) {
|
||||
throw new IllegalArgumentException("Specified column index (" + columnIndex
|
||||
+ ") is outside the allowed range (0.." + lastColIx + ")");
|
||||
}
|
||||
@ -98,23 +96,23 @@ final class LookupUtils {
|
||||
throw new ArrayIndexOutOfBoundsException("Specified index (" + index
|
||||
+ ") is outside the allowed range (0.." + (_size-1) + ")");
|
||||
}
|
||||
return _tableArray.getRelativeValue(index, _columnIndex);
|
||||
return _tableArray.getValue(index, _columnIndex);
|
||||
}
|
||||
public int getSize() {
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
|
||||
public static ValueVector createRowVector(AreaEval tableArray, int relativeRowIndex) {
|
||||
public static ValueVector createRowVector(TwoDEval tableArray, int relativeRowIndex) {
|
||||
return new RowVector(tableArray, relativeRowIndex);
|
||||
}
|
||||
public static ValueVector createColumnVector(AreaEval tableArray, int relativeColumnIndex) {
|
||||
public static ValueVector createColumnVector(TwoDEval tableArray, int relativeColumnIndex) {
|
||||
return new ColumnVector(tableArray, relativeColumnIndex);
|
||||
}
|
||||
/**
|
||||
* @return <code>null</code> if the supplied area is neither a single row nor a single colum
|
||||
*/
|
||||
public static ValueVector createVector(AreaEval ae) {
|
||||
public static ValueVector createVector(TwoDEval ae) {
|
||||
if (ae.isColumn()) {
|
||||
return createColumnVector(ae, 0);
|
||||
}
|
||||
@ -361,9 +359,9 @@ final class LookupUtils {
|
||||
* The second argument (table_array) should be an area ref, but can actually be a cell ref, in
|
||||
* which case it is interpreted as a 1x1 area ref. Other scalar values cause #VALUE! error.
|
||||
*/
|
||||
public static AreaEval resolveTableArrayArg(ValueEval eval) throws EvaluationException {
|
||||
if (eval instanceof AreaEval) {
|
||||
return (AreaEval) eval;
|
||||
public static TwoDEval resolveTableArrayArg(ValueEval eval) throws EvaluationException {
|
||||
if (eval instanceof TwoDEval) {
|
||||
return (TwoDEval) eval;
|
||||
}
|
||||
|
||||
if(eval instanceof RefEval) {
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
@ -29,6 +28,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.CompareResult;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.LookupValueComparer;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation for the MATCH() Excel function.<p/>
|
||||
@ -130,8 +130,8 @@ public final class Match extends Var2or3ArgFunction {
|
||||
RefEval re = (RefEval) eval;
|
||||
return new SingleValueVector(re.getInnerValueEval());
|
||||
}
|
||||
if (eval instanceof AreaEval) {
|
||||
ValueVector result = LookupUtils.createVector((AreaEval)eval);
|
||||
if (eval instanceof TwoDEval) {
|
||||
ValueVector result = LookupUtils.createVector((TwoDEval)eval);
|
||||
if (result == null) {
|
||||
throw new EvaluationException(ErrorEval.NA);
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
@ -30,6 +29,7 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
@ -92,13 +92,13 @@ public final class Mode implements Function {
|
||||
}
|
||||
|
||||
private static void collectValues(ValueEval arg, List<Double> temp) throws EvaluationException {
|
||||
if (arg instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) arg;
|
||||
if (arg instanceof TwoDEval) {
|
||||
TwoDEval ae = (TwoDEval) arg;
|
||||
int width = ae.getWidth();
|
||||
int height = ae.getHeight();
|
||||
for (int rrIx = 0; rrIx < height; rrIx++) {
|
||||
for (int rcIx = 0; rcIx < width; rcIx++) {
|
||||
ValueEval ve1 = ae.getRelativeValue(rrIx, rcIx);
|
||||
ValueEval ve1 = ae.getValue(rrIx, rcIx);
|
||||
collectValue(ve1, temp, false);
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Implementation for Excel ROWS function.
|
||||
@ -33,8 +33,8 @@ public final class Rows extends Fixed1ArgFunction {
|
||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
||||
|
||||
int result;
|
||||
if (arg0 instanceof AreaEval) {
|
||||
result = ((AreaEval) arg0).getHeight();
|
||||
if (arg0 instanceof TwoDEval) {
|
||||
result = ((TwoDEval) arg0).getHeight();
|
||||
} else if (arg0 instanceof RefEval) {
|
||||
result = 1;
|
||||
} else { // anything else is not valid argument
|
||||
|
@ -26,6 +26,7 @@ import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
|
||||
/**
|
||||
@ -68,8 +69,8 @@ public final class Sumproduct implements Function {
|
||||
if(firstArg instanceof RefEval) {
|
||||
return evaluateSingleProduct(args);
|
||||
}
|
||||
if(firstArg instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) firstArg;
|
||||
if (firstArg instanceof TwoDEval) {
|
||||
TwoDEval ae = (TwoDEval) firstArg;
|
||||
if(ae.isRow() && ae.isColumn()) {
|
||||
return evaluateSingleProduct(args);
|
||||
}
|
||||
@ -120,7 +121,7 @@ public final class Sumproduct implements Function {
|
||||
|
||||
private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException {
|
||||
int maxN = evalArgs.length;
|
||||
AreaEval[] args = new AreaEval[maxN];
|
||||
TwoDEval[] args = new TwoDEval[maxN];
|
||||
try {
|
||||
System.arraycopy(evalArgs, 0, args, 0, maxN);
|
||||
} catch (ArrayStoreException e) {
|
||||
@ -129,7 +130,7 @@ public final class Sumproduct implements Function {
|
||||
}
|
||||
|
||||
|
||||
AreaEval firstArg = args[0];
|
||||
TwoDEval firstArg = args[0];
|
||||
|
||||
int height = firstArg.getHeight();
|
||||
int width = firstArg.getWidth(); // TODO - junit
|
||||
@ -150,7 +151,7 @@ public final class Sumproduct implements Function {
|
||||
for (int rcIx=0; rcIx<width; rcIx++) {
|
||||
double term = 1D;
|
||||
for(int n=0; n<maxN; n++) {
|
||||
double val = getProductTerm(args[n].getRelativeValue(rrIx, rcIx), false);
|
||||
double val = getProductTerm(args[n].getValue(rrIx, rcIx), false);
|
||||
term *= val;
|
||||
}
|
||||
acc += term;
|
||||
@ -160,12 +161,12 @@ public final class Sumproduct implements Function {
|
||||
return new NumberEval(acc);
|
||||
}
|
||||
|
||||
private static void throwFirstError(AreaEval areaEval) throws EvaluationException {
|
||||
private static void throwFirstError(TwoDEval areaEval) throws EvaluationException {
|
||||
int height = areaEval.getHeight();
|
||||
int width = areaEval.getWidth();
|
||||
for (int rrIx=0; rrIx<height; rrIx++) {
|
||||
for (int rcIx=0; rcIx<width; rcIx++) {
|
||||
ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
|
||||
ValueEval ve = areaEval.getValue(rrIx, rcIx);
|
||||
if (ve instanceof ErrorEval) {
|
||||
throw new EvaluationException((ErrorEval) ve);
|
||||
}
|
||||
@ -173,9 +174,9 @@ public final class Sumproduct implements Function {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areasAllSameSize(AreaEval[] args, int height, int width) {
|
||||
private static boolean areasAllSameSize(TwoDEval[] args, int height, int width) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
AreaEval areaEval = args[i];
|
||||
TwoDEval areaEval = args[i];
|
||||
// check that height and width match
|
||||
if(areaEval.getHeight() != height) {
|
||||
return false;
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
/**
|
||||
* Implementation of the VLOOKUP() function.<p/>
|
||||
*
|
||||
@ -53,7 +53,7 @@ public final class Vlookup extends Var3or4ArgFunction {
|
||||
// Evaluation order:
|
||||
// arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 col_index, fetch result
|
||||
ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
|
||||
AreaEval tableArray = LookupUtils.resolveTableArrayArg(arg1);
|
||||
TwoDEval tableArray = LookupUtils.resolveTableArrayArg(arg1);
|
||||
boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcRowIndex, srcColumnIndex);
|
||||
int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createColumnVector(tableArray, 0), isRangeLookup);
|
||||
int colIndex = LookupUtils.resolveRowOrColIndexArg(arg2, srcRowIndex, srcColumnIndex);
|
||||
@ -72,7 +72,7 @@ public final class Vlookup extends Var3or4ArgFunction {
|
||||
*
|
||||
* @throws EvaluationException (#REF!) if colIndex is too high
|
||||
*/
|
||||
private ValueVector createResultColumnVector(AreaEval tableArray, int colIndex) throws EvaluationException {
|
||||
private ValueVector createResultColumnVector(TwoDEval tableArray, int colIndex) throws EvaluationException {
|
||||
if(colIndex >= tableArray.getWidth()) {
|
||||
throw EvaluationException.invalidRef();
|
||||
}
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
@ -71,10 +71,10 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction {
|
||||
}
|
||||
|
||||
private static final class AreaValueArray extends ValueArray {
|
||||
private final AreaEval _ae;
|
||||
private final TwoDEval _ae;
|
||||
private final int _width;
|
||||
|
||||
public AreaValueArray(AreaEval ae) {
|
||||
public AreaValueArray(TwoDEval ae) {
|
||||
super(ae.getWidth() * ae.getHeight());
|
||||
_ae = ae;
|
||||
_width = ae.getWidth();
|
||||
@ -82,7 +82,7 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction {
|
||||
protected ValueEval getItemInternal(int index) {
|
||||
int rowIx = index / _width;
|
||||
int colIx = index % _width;
|
||||
return _ae.getRelativeValue(rowIx, colIx);
|
||||
return _ae.getValue(rowIx, colIx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,8 +166,8 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction {
|
||||
if (arg instanceof ErrorEval) {
|
||||
throw new EvaluationException((ErrorEval) arg);
|
||||
}
|
||||
if (arg instanceof AreaEval) {
|
||||
return new AreaValueArray((AreaEval) arg);
|
||||
if (arg instanceof TwoDEval) {
|
||||
return new AreaValueArray((TwoDEval) arg);
|
||||
}
|
||||
if (arg instanceof RefEval) {
|
||||
return new RefValueArray((RefEval) arg);
|
||||
|
51
src/java/org/apache/poi/ss/formula/TwoDEval.java
Normal file
51
src/java/org/apache/poi/ss/formula/TwoDEval.java
Normal file
@ -0,0 +1,51 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
/**
|
||||
* Common interface of {@link AreaEval} and {@link ArrayEval}
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public interface TwoDEval extends ValueEval {
|
||||
|
||||
/**
|
||||
* @param row relative row index (zero based)
|
||||
* @param col relative column index (zero based)
|
||||
* @return element at the specified row and col position
|
||||
*/
|
||||
public ValueEval getValue(int row, int col);
|
||||
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the area has just a single row, this also includes
|
||||
* the trivial case when the area has just a single cell.
|
||||
*/
|
||||
boolean isRow();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the area has just a single column, this also includes
|
||||
* the trivial case when the area has just a single cell.
|
||||
*/
|
||||
boolean isColumn();
|
||||
}
|
Loading…
Reference in New Issue
Block a user