Browse Source

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
pull/11/head
Nick Burch 10 years ago
parent
commit
3872e620a7
22 changed files with 227 additions and 82 deletions
  1. 7
    8
      src/java/org/apache/poi/ss/formula/LazyRefEval.java
  2. 23
    0
      src/java/org/apache/poi/ss/formula/SheetRange.java
  3. 1
    1
      src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java
  4. 5
    1
      src/java/org/apache/poi/ss/formula/eval/OperandResolver.java
  5. 21
    6
      src/java/org/apache/poi/ss/formula/eval/RefEval.java
  6. 30
    5
      src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java
  7. 17
    8
      src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
  8. 13
    8
      src/java/org/apache/poi/ss/formula/functions/CountUtils.java
  9. 2
    2
      src/java/org/apache/poi/ss/formula/functions/Countblank.java
  10. 2
    2
      src/java/org/apache/poi/ss/formula/functions/Countif.java
  11. 16
    5
      src/java/org/apache/poi/ss/formula/functions/EDate.java
  12. 5
    2
      src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java
  13. 30
    4
      src/java/org/apache/poi/ss/formula/functions/LookupUtils.java
  14. 6
    2
      src/java/org/apache/poi/ss/formula/functions/Match.java
  15. 4
    2
      src/java/org/apache/poi/ss/formula/functions/Mode.java
  16. 4
    2
      src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java
  17. 5
    2
      src/java/org/apache/poi/ss/formula/functions/Sumproduct.java
  18. 3
    1
      src/java/org/apache/poi/ss/formula/functions/T.java
  19. 7
    3
      src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java
  20. 4
    5
      src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java
  21. 8
    8
      src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java
  22. 14
    5
      src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java

+ 7
- 8
src/java/org/apache/poi/ss/formula/LazyRefEval.java View File

@@ -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
- 0
src/java/org/apache/poi/ss/formula/SheetRange.java View 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();
}

+ 1
- 1
src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java View File

@@ -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;

+ 5
- 1
src/java/org/apache/poi/ss/formula/eval/OperandResolver.java View File

@@ -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/>

+ 21
- 6
src/java/org/apache/poi/ss/formula/eval/RefEval.java View File

@@ -17,9 +17,9 @@

package org.apache.poi.ss.formula.eval;

import org.apache.poi.ss.formula.SheetRange;

/**
* @author Amol S Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
* RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval
* impl should contain reference to the original ReferencePtg or Ref3DPtg as
* well as the final "value" resulting from the evaluation of the cell
@@ -27,12 +27,11 @@ package org.apache.poi.ss.formula.eval;
* value object should be of type NumberEval; if cell type is CELL_TYPE_STRING,
* contained value object should be of type StringEval
*/
public interface RefEval extends ValueEval {

public interface RefEval extends ValueEval, SheetRange {
/**
* @return the evaluated value of the cell referred to by this RefEval.
* @return the evaluated value of the cell referred to by this RefEval on the given sheet
*/
ValueEval getInnerValueEval();
ValueEval getInnerValueEval(int sheetIndex);

/**
* returns the zero based column index.
@@ -43,6 +42,22 @@ public interface RefEval extends ValueEval {
* returns the zero based row index.
*/
int getRow();
/**
* returns the first sheet index this applies to
*/
int getFirstSheetIndex();

/**
* returns the last sheet index this applies to, which
* will be the same as the first for a 2D and many 3D references
*/
int getLastSheetIndex();
/**
* returns the number of sheets this applies to
*/
int getNumberOfSheets();

/**
* Creates an {@link AreaEval} offset by a relative amount from this RefEval

+ 30
- 5
src/java/org/apache/poi/ss/formula/eval/RefEvalBase.java View File

@@ -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
- 8
src/java/org/apache/poi/ss/formula/functions/BooleanFunction.java View File

@@ -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;

+ 13
- 8
src/java/org/apache/poi/ss/formula/functions/CountUtils.java View File

@@ -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;
}

+ 2
- 2
src/java/org/apache/poi/ss/formula/functions/Countblank.java View File

@@ -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 {

+ 2
- 2
src/java/org/apache/poi/ss/formula/functions/Countif.java View File

@@ -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 {

+ 16
- 5
src/java/org/apache/poi/ss/formula/functions/EDate.java View File

@@ -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();
}

+ 5
- 2
src/java/org/apache/poi/ss/formula/functions/LinearRegressionFunction.java View File

@@ -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);
}
}


+ 30
- 4
src/java/org/apache/poi/ss/formula/functions/LookupUtils.java View File

@@ -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/>

+ 6
- 2
src/java/org/apache/poi/ss/formula/functions/Match.java View File

@@ -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);

+ 4
- 2
src/java/org/apache/poi/ss/formula/functions/Mode.java View File

@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.ss.formula.TwoDEval;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -29,7 +30,6 @@ import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.StringEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.TwoDEval;

/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -106,7 +106,9 @@ public final class Mode implements Function {
}
if (arg instanceof RefEval) {
RefEval re = (RefEval) arg;
collectValue(re.getInnerValueEval(), temp, true);
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
collectValue(re.getInnerValueEval(sIx), temp, true);
}
return;
}
collectValue(arg, temp, true);

+ 4
- 2
src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java View File

@@ -17,6 +17,7 @@

package org.apache.poi.ss.formula.functions;

import org.apache.poi.ss.formula.TwoDEval;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
@@ -27,7 +28,6 @@ import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.StringValueEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.TwoDEval;

/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -157,7 +157,9 @@ public abstract class MultiOperandNumericFunction implements Function {
}
if (operand instanceof RefEval) {
RefEval re = (RefEval) operand;
collectValue(re.getInnerValueEval(), true, temp);
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
collectValue(re.getInnerValueEval(sIx), true, temp);
}
return;
}
collectValue(operand, false, temp);

+ 5
- 2
src/java/org/apache/poi/ss/formula/functions/Sumproduct.java View File

@@ -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;
}

+ 3
- 1
src/java/org/apache/poi/ss/formula/functions/T.java View File

@@ -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);

+ 7
- 3
src/java/org/apache/poi/ss/formula/functions/XYNumericFunction.java View File

@@ -17,13 +17,13 @@

package org.apache.poi.ss.formula.functions;

import org.apache.poi.ss.formula.TwoDEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector;
import org.apache.poi.ss.formula.TwoDEval;

/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -61,12 +61,16 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction {

private static final class RefValueArray extends ValueArray {
private final RefEval _ref;
private final int _width;
public RefValueArray(RefEval ref) {
super(1);
super(ref.getNumberOfSheets());
_ref = ref;
_width = ref.getNumberOfSheets();
}
protected ValueEval getItemInternal(int index) {
return _ref.getInnerValueEval();
int sIx = (index % _width) + _ref.getFirstSheetIndex();
return _ref.getInnerValueEval(sIx);
}
}


+ 4
- 5
src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java View File

@@ -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,

+ 8
- 8
src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java View File

@@ -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) {

+ 14
- 5
src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java View File

@@ -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…
Cancel
Save