mirror of https://github.com/apache/poi.git
Added getRow() and getColumn() functions to TwoDEval to simplify logic in INDEX implementation.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@893063 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4b14bbc353
commit
5126999358
|
@ -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.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
|
@ -53,7 +52,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
|||
int columnIx = 0;
|
||||
try {
|
||||
int rowIx = resolveIndexArg(arg1, srcRowIndex, srcColumnIndex);
|
||||
|
||||
|
||||
if (!reference.isColumn()) {
|
||||
if (!reference.isRow()) {
|
||||
// always an error with 2-D area refs
|
||||
|
@ -65,7 +64,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
|||
columnIx = rowIx;
|
||||
rowIx = 0;
|
||||
}
|
||||
|
||||
|
||||
return getValueFromArea(reference, rowIx, columnIx);
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
|
@ -125,45 +124,27 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
|
|||
throws EvaluationException {
|
||||
assert pRowIx >= 0;
|
||||
assert pColumnIx >= 0;
|
||||
|
||||
int width = ae.getWidth();
|
||||
int height = ae.getHeight();
|
||||
|
||||
int relFirstRowIx;
|
||||
int relLastRowIx;
|
||||
|
||||
if ((pRowIx == 0)) {
|
||||
relFirstRowIx = 0;
|
||||
relLastRowIx = height-1;
|
||||
} else {
|
||||
TwoDEval result = ae;
|
||||
|
||||
if (pRowIx != 0) {
|
||||
// Slightly irregular logic for bounds checking errors
|
||||
if (pRowIx > height) {
|
||||
if (pRowIx > ae.getHeight()) {
|
||||
// high bounds check fail gives #REF! if arg was explicitly passed
|
||||
throw new EvaluationException(ErrorEval.REF_INVALID);
|
||||
}
|
||||
int rowIx = pRowIx-1;
|
||||
relFirstRowIx = rowIx;
|
||||
relLastRowIx = rowIx;
|
||||
result = result.getRow(pRowIx-1);
|
||||
}
|
||||
|
||||
int relFirstColIx;
|
||||
int relLastColIx;
|
||||
if ((pColumnIx == 0)) {
|
||||
relFirstColIx = 0;
|
||||
relLastColIx = width-1;
|
||||
} else {
|
||||
if (pColumnIx != 0) {
|
||||
// Slightly irregular logic for bounds checking errors
|
||||
if (pColumnIx > width) {
|
||||
if (pColumnIx > ae.getWidth()) {
|
||||
// high bounds check fail gives #REF! if arg was explicitly passed
|
||||
throw new EvaluationException(ErrorEval.REF_INVALID);
|
||||
}
|
||||
int columnIx = pColumnIx-1;
|
||||
relFirstColIx = columnIx;
|
||||
relLastColIx = columnIx;
|
||||
result = result.getColumn(pColumnIx-1);
|
||||
}
|
||||
|
||||
AreaEval x = ((AreaEval) ae);
|
||||
return x.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,23 @@ final class LazyAreaEval extends AreaEvalBase {
|
|||
|
||||
return new LazyAreaEval(area, _evaluator);
|
||||
}
|
||||
public LazyAreaEval getRow(int rowIndex) {
|
||||
if (rowIndex >= getHeight()) {
|
||||
throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
|
||||
+ ". Allowable range is (0.." + getHeight() + ").");
|
||||
}
|
||||
int absRowIx = getFirstRow() + rowIndex;
|
||||
return new LazyAreaEval(absRowIx, getFirstColumn(), absRowIx, getLastColumn(), _evaluator);
|
||||
}
|
||||
public LazyAreaEval getColumn(int columnIndex) {
|
||||
if (columnIndex >= getWidth()) {
|
||||
throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
|
||||
+ ". Allowable range is (0.." + getWidth() + ").");
|
||||
}
|
||||
int absColIx = getFirstColumn() + columnIndex;
|
||||
return new LazyAreaEval(getFirstRow(), absColIx, getLastRow(), absColIx, _evaluator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
|
||||
CellReference crB = new CellReference(getLastRow(), getLastColumn());
|
||||
|
|
|
@ -28,11 +28,11 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
|||
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
|
||||
* @param rowIndex relative row index (zero based)
|
||||
* @param columnIndex relative column index (zero based)
|
||||
* @return element at the specified row and column position
|
||||
*/
|
||||
public ValueEval getValue(int row, int col);
|
||||
ValueEval getValue(int rowIndex, int columnIndex);
|
||||
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
|
@ -48,4 +48,15 @@ public interface TwoDEval extends ValueEval {
|
|||
* the trivial case when the area has just a single cell.
|
||||
*/
|
||||
boolean isColumn();
|
||||
|
||||
/**
|
||||
* @param rowIndex relative row index (zero based)
|
||||
* @return a single row {@link TwoDEval}
|
||||
*/
|
||||
TwoDEval getRow(int rowIndex);
|
||||
/**
|
||||
* @param columnIndex relative column index (zero based)
|
||||
* @return a single column {@link TwoDEval}
|
||||
*/
|
||||
TwoDEval getColumn(int columnIndex);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
|
|||
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.usermodel.CellValue;
|
||||
|
||||
/**
|
||||
|
@ -90,6 +91,9 @@ public final class TestRangeEval extends TestCase {
|
|||
public MockAreaEval(AreaI ptg) {
|
||||
super(ptg);
|
||||
}
|
||||
private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
|
||||
super(firstRow, firstColumn, lastRow, lastColumn);
|
||||
}
|
||||
public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
|
||||
throw new RuntimeException("not expected to be called during this test");
|
||||
}
|
||||
|
@ -100,6 +104,20 @@ public final class TestRangeEval extends TestCase {
|
|||
|
||||
return new MockAreaEval(area);
|
||||
}
|
||||
public TwoDEval getRow(int rowIndex) {
|
||||
if (rowIndex >= getHeight()) {
|
||||
throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
|
||||
+ ". Allowable range is (0.." + getHeight() + ").");
|
||||
}
|
||||
return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
|
||||
}
|
||||
public TwoDEval getColumn(int columnIndex) {
|
||||
if (columnIndex >= getWidth()) {
|
||||
throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
|
||||
+ ". Allowable range is (0.." + getWidth() + ").");
|
||||
}
|
||||
return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRangeUsingOffsetFunc_bug46948() {
|
||||
|
|
|
@ -27,6 +27,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.RefEvalBase;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
||||
/**
|
||||
* Test helper class for creating mock <code>Eval</code> objects
|
||||
|
@ -119,7 +120,7 @@ public final class EvalFactory {
|
|||
int width = relLastColIx - relFirstColIx + 1;
|
||||
ValueEval[] result = new ValueEval[height * width];
|
||||
for (int r=0; r<height; r++) {
|
||||
int srcRowIx = r + relFirstRowIx;
|
||||
int srcRowIx = r + relFirstRowIx;
|
||||
for (int c=0; c<width; c++) {
|
||||
int srcColIx = c + relFirstColIx;
|
||||
int destIx = r * width + c;
|
||||
|
@ -129,6 +130,28 @@ public final class EvalFactory {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
public TwoDEval getRow(int rowIndex) {
|
||||
if (rowIndex >= getHeight()) {
|
||||
throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
|
||||
+ ". Allowable range is (0.." + getHeight() + ").");
|
||||
}
|
||||
ValueEval[] values = new ValueEval[getWidth()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = getRelativeValue(rowIndex, i);
|
||||
}
|
||||
return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn(), values);
|
||||
}
|
||||
public TwoDEval getColumn(int columnIndex) {
|
||||
if (columnIndex >= getWidth()) {
|
||||
throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
|
||||
+ ". Allowable range is (0.." + getWidth() + ").");
|
||||
}
|
||||
ValueEval[] values = new ValueEval[getHeight()];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = getRelativeValue(i, columnIndex);
|
||||
}
|
||||
return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex, values);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MockRefEval extends RefEvalBase {
|
||||
|
|
Loading…
Reference in New Issue