From 288e76df7e873c661ac4c387dd708bbf9a4aca23 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Wed, 9 Dec 2009 00:50:11 +0000 Subject: [PATCH] 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 --- .../hssf/record/formula/eval/AreaEval.java | 17 +------ .../record/formula/eval/AreaEvalBase.java | 5 +- .../formula/functions/BooleanFunction.java | 10 ++-- .../record/formula/functions/Columns.java | 6 +-- .../record/formula/functions/CountUtils.java | 10 ++-- .../record/formula/functions/Countblank.java | 6 +-- .../record/formula/functions/Countif.java | 6 +-- .../record/formula/functions/Hlookup.java | 6 +-- .../hssf/record/formula/functions/Index.java | 39 ++++++++++---- .../hssf/record/formula/functions/Lookup.java | 8 +-- .../record/formula/functions/LookupUtils.java | 36 +++++++------ .../hssf/record/formula/functions/Match.java | 6 +-- .../hssf/record/formula/functions/Mode.java | 8 +-- .../hssf/record/formula/functions/Rows.java | 6 +-- .../record/formula/functions/Sumproduct.java | 19 +++---- .../record/formula/functions/Vlookup.java | 6 +-- .../formula/functions/XYNumericFunction.java | 12 ++--- .../org/apache/poi/ss/formula/TwoDEval.java | 51 +++++++++++++++++++ 18 files changed, 158 insertions(+), 99 deletions(-) create mode 100644 src/java/org/apache/poi/ss/formula/TwoDEval.java diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java index 7428ad7163..4c5fb9f681 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java @@ -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 * null (possibly {@link BlankEval}). The specified indexes should be absolute diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java index d435264ae5..12e21cf9ad 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java @@ -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() { diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java index 0165e501a5..e3381a0ae9 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java @@ -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 * @@ -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(); } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Index.java b/src/java/org/apache/poi/hssf/record/formula/functions/Index.java index d4b2519335..c005adffa4 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Index.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Index.java @@ -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 { * true. 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); } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java b/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java index 6a2bafe7e6..09baff5dbb 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java @@ -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.

@@ -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; diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java index b6a9d7bc8b..430565c597 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java @@ -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 null 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) { diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Match.java b/src/java/org/apache/poi/hssf/record/formula/functions/Match.java index c2208196fa..d774c67bc1 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Match.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Match.java @@ -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.

@@ -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); } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java index 4280bb11e5..4ede174d21 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java @@ -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 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); } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java index dfde69ae31..91da8e157d 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java @@ -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 diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java index 8c2d2b173b..41de8ef392 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java @@ -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 * @@ -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(); } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java index e2c919489b..2c7a4d3939 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java @@ -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); diff --git a/src/java/org/apache/poi/ss/formula/TwoDEval.java b/src/java/org/apache/poi/ss/formula/TwoDEval.java new file mode 100644 index 0000000000..f2e51459a3 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/TwoDEval.java @@ -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 true 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 true if the area has just a single column, this also includes + * the trivial case when the area has just a single cell. + */ + boolean isColumn(); +} -- 2.39.5