git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613453 13f79535-47bb-0310-9956-ffa450edef68pull/11/head
@@ -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) { |
@@ -0,0 +1,23 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.ss.formula; | |||
public interface SheetRange { | |||
public int getFirstSheetIndex(); | |||
public int getLastSheetIndex(); | |||
} |
@@ -22,7 +22,7 @@ import org.apache.poi.ss.formula.eval.ValueEval; | |||
/** | |||
* Evaluator for returning cells or sheets for a range of sheets | |||
*/ | |||
final class SheetRangeEvaluator { | |||
final class SheetRangeEvaluator implements SheetRange { | |||
private final int _firstSheetIndex; | |||
private final int _lastSheetIndex; | |||
private SheetRefEvaluator[] _sheetEvaluators; |
@@ -59,7 +59,7 @@ public final class OperandResolver { | |||
throws EvaluationException { | |||
ValueEval result; | |||
if (arg instanceof RefEval) { | |||
result = ((RefEval) arg).getInnerValueEval(); | |||
result = chooseSingleElementFromRef((RefEval) arg); | |||
} else if (arg instanceof AreaEval) { | |||
result = chooseSingleElementFromArea((AreaEval) arg, srcCellRow, srcCellCol); | |||
} else { | |||
@@ -174,6 +174,10 @@ public final class OperandResolver { | |||
} | |||
return ae.getAbsoluteValue(ae.getFirstRow(), srcCellCol); | |||
} | |||
private static ValueEval chooseSingleElementFromRef(RefEval ref) { | |||
return ref.getInnerValueEval( ref.getFirstSheetIndex() ); | |||
} | |||
/** | |||
* Applies some conversion rules if the supplied value is not already an integer.<br/> |
@@ -17,9 +17,9 @@ | |||
package org.apache.poi.ss.formula.eval; | |||
import org.apache.poi.ss.formula.SheetRange; | |||
/** | |||
* @author Amol S Deshmukh < amolweb at ya hoo dot com > | |||
* | |||
* RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval | |||
* impl should contain reference to the original ReferencePtg or Ref3DPtg as | |||
* well as the final "value" resulting from the evaluation of the cell | |||
@@ -27,12 +27,11 @@ package org.apache.poi.ss.formula.eval; | |||
* value object should be of type NumberEval; if cell type is CELL_TYPE_STRING, | |||
* contained value object should be of type StringEval | |||
*/ | |||
public interface RefEval extends ValueEval { | |||
public interface RefEval extends ValueEval, SheetRange { | |||
/** | |||
* @return the evaluated value of the cell referred to by this RefEval. | |||
* @return the evaluated value of the cell referred to by this RefEval on the given sheet | |||
*/ | |||
ValueEval getInnerValueEval(); | |||
ValueEval getInnerValueEval(int sheetIndex); | |||
/** | |||
* returns the zero based column index. | |||
@@ -43,6 +42,22 @@ public interface RefEval extends ValueEval { | |||
* returns the zero based row index. | |||
*/ | |||
int getRow(); | |||
/** | |||
* returns the first sheet index this applies to | |||
*/ | |||
int getFirstSheetIndex(); | |||
/** | |||
* returns the last sheet index this applies to, which | |||
* will be the same as the first for a 2D and many 3D references | |||
*/ | |||
int getLastSheetIndex(); | |||
/** | |||
* returns the number of sheets this applies to | |||
*/ | |||
int getNumberOfSheets(); | |||
/** | |||
* Creates an {@link AreaEval} offset by a relative amount from this RefEval |
@@ -17,21 +17,46 @@ | |||
package org.apache.poi.ss.formula.eval; | |||
import org.apache.poi.ss.formula.SheetRange; | |||
/** | |||
* Common base class for implementors of {@link RefEval} | |||
* | |||
* @author Josh Micich | |||
*/ | |||
public abstract class RefEvalBase implements RefEval { | |||
private final int _firstSheetIndex; | |||
private final int _lastSheetIndex; | |||
private final int _rowIndex; | |||
private final int _columnIndex; | |||
protected RefEvalBase(int rowIndex, int columnIndex) { | |||
protected RefEvalBase(SheetRange sheetRange, int rowIndex, int columnIndex) { | |||
if (sheetRange == null) { | |||
throw new IllegalArgumentException("sheetRange must not be null"); | |||
} | |||
_firstSheetIndex = sheetRange.getFirstSheetIndex(); | |||
_lastSheetIndex = sheetRange.getLastSheetIndex(); | |||
_rowIndex = rowIndex; | |||
_columnIndex = columnIndex; | |||
} | |||
protected RefEvalBase(int firstSheetIndex, int lastSheetIndex, int rowIndex, int columnIndex) { | |||
_firstSheetIndex = firstSheetIndex; | |||
_lastSheetIndex = lastSheetIndex; | |||
_rowIndex = rowIndex; | |||
_columnIndex = columnIndex; | |||
} | |||
public final int getRow() { | |||
protected RefEvalBase(int onlySheetIndex, int rowIndex, int columnIndex) { | |||
this(onlySheetIndex, onlySheetIndex, rowIndex, columnIndex); | |||
} | |||
public int getNumberOfSheets() { | |||
return _lastSheetIndex-_firstSheetIndex+1; | |||
} | |||
public int getFirstSheetIndex() { | |||
return _firstSheetIndex; | |||
} | |||
public int getLastSheetIndex() { | |||
return _lastSheetIndex; | |||
} | |||
public final int getRow() { | |||
return _rowIndex; | |||
} | |||
public final int getColumn() { |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BoolEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.formula.eval.EvaluationException; | |||
@@ -24,7 +25,6 @@ import org.apache.poi.ss.formula.eval.MissingArgEval; | |||
import org.apache.poi.ss.formula.eval.OperandResolver; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* Here are the general rules concerning Boolean functions: | |||
@@ -61,6 +61,7 @@ public abstract class BooleanFunction implements Function { | |||
* Note: no short-circuit boolean loop exit because any ErrorEvals will override the result | |||
*/ | |||
for (int i=0, iSize=args.length; i<iSize; i++) { | |||
Boolean tempVe; | |||
ValueEval arg = args[i]; | |||
if (arg instanceof TwoDEval) { | |||
TwoDEval ae = (TwoDEval) arg; | |||
@@ -69,7 +70,7 @@ public abstract class BooleanFunction implements Function { | |||
for (int rrIx=0; rrIx<height; rrIx++) { | |||
for (int rcIx=0; rcIx<width; rcIx++) { | |||
ValueEval ve = ae.getValue(rrIx, rcIx); | |||
Boolean tempVe = OperandResolver.coerceValueToBoolean(ve, true); | |||
tempVe = OperandResolver.coerceValueToBoolean(ve, true); | |||
if (tempVe != null) { | |||
result = partialEvaluate(result, tempVe.booleanValue()); | |||
atleastOneNonBlank = true; | |||
@@ -78,17 +79,25 @@ public abstract class BooleanFunction implements Function { | |||
} | |||
continue; | |||
} | |||
Boolean tempVe; | |||
if (arg instanceof RefEval) { | |||
ValueEval ve = ((RefEval) arg).getInnerValueEval(); | |||
tempVe = OperandResolver.coerceValueToBoolean(ve, true); | |||
} else if (arg == MissingArgEval.instance) { | |||
if (arg instanceof RefEval) { | |||
RefEval re = (RefEval) arg; | |||
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) { | |||
ValueEval ve = re.getInnerValueEval(sIx); | |||
tempVe = OperandResolver.coerceValueToBoolean(ve, true); | |||
if (tempVe != null) { | |||
result = partialEvaluate(result, tempVe.booleanValue()); | |||
atleastOneNonBlank = true; | |||
} | |||
} | |||
continue; | |||
} | |||
if (arg == MissingArgEval.instance) { | |||
tempVe = null; // you can leave out parameters, they are simply ignored | |||
} else { | |||
tempVe = OperandResolver.coerceValueToBoolean(arg, false); | |||
} | |||
if (tempVe != null) { | |||
result = partialEvaluate(result, tempVe.booleanValue()); | |||
atleastOneNonBlank = true; |
@@ -17,9 +17,9 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* Common logic for COUNT, COUNTA and COUNTIF | |||
@@ -67,13 +67,18 @@ final class CountUtils { | |||
return result; | |||
} | |||
/** | |||
* @return 1 if the evaluated cell matches the specified criteria | |||
* @return the number of evaluated cells in the range that match the specified criteria | |||
*/ | |||
public static int countMatchingCell(RefEval refEval, I_MatchPredicate criteriaPredicate) { | |||
if(criteriaPredicate.matches(refEval.getInnerValueEval())) { | |||
return 1; | |||
} | |||
return 0; | |||
public static int countMatchingCellsInRef(RefEval refEval, I_MatchPredicate criteriaPredicate) { | |||
int result = 0; | |||
for (int sIx = refEval.getFirstSheetIndex(); sIx <= refEval.getLastSheetIndex(); sIx++) { | |||
ValueEval ve = refEval.getInnerValueEval(sIx); | |||
if(criteriaPredicate.matches(ve)) { | |||
result++; | |||
} | |||
} | |||
return result; | |||
} | |||
public static int countArg(ValueEval eval, I_MatchPredicate criteriaPredicate) { | |||
if (eval == null) { | |||
@@ -83,7 +88,7 @@ final class CountUtils { | |||
return countMatchingCellsInArea((TwoDEval) eval, criteriaPredicate); | |||
} | |||
if (eval instanceof RefEval) { | |||
return CountUtils.countMatchingCell((RefEval) eval, criteriaPredicate); | |||
return CountUtils.countMatchingCellsInRef((RefEval) eval, criteriaPredicate); | |||
} | |||
return criteriaPredicate.matches(eval) ? 1 : 0; | |||
} |
@@ -17,12 +17,12 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.NumberEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* Implementation for the function COUNTBLANK | |||
@@ -41,7 +41,7 @@ public final class Countblank extends Fixed1ArgFunction { | |||
double result; | |||
if (arg0 instanceof RefEval) { | |||
result = CountUtils.countMatchingCell((RefEval) arg0, predicate); | |||
result = CountUtils.countMatchingCellsInRef((RefEval) arg0, predicate); | |||
} else if (arg0 instanceof TwoDEval) { | |||
result = CountUtils.countMatchingCellsInArea((TwoDEval) arg0, predicate); | |||
} else { |
@@ -19,6 +19,7 @@ package org.apache.poi.ss.formula.functions; | |||
import java.util.regex.Pattern; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.BoolEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
@@ -29,7 +30,6 @@ import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.StringEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.functions.CountUtils.I_MatchPredicate; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.usermodel.ErrorConstants; | |||
/** | |||
@@ -444,7 +444,7 @@ public final class Countif extends Fixed2ArgFunction { | |||
private double countMatchingCellsInArea(ValueEval rangeArg, I_MatchPredicate criteriaPredicate) { | |||
if (rangeArg instanceof RefEval) { | |||
return CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate); | |||
return CountUtils.countMatchingCellsInRef((RefEval) rangeArg, criteriaPredicate); | |||
} else if (rangeArg instanceof TwoDEval) { | |||
return CountUtils.countMatchingCellsInArea((TwoDEval) rangeArg, criteriaPredicate); | |||
} else { |
@@ -17,13 +17,18 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.OperationEvaluationContext; | |||
import org.apache.poi.ss.formula.eval.*; | |||
import org.apache.poi.ss.usermodel.DateUtil; | |||
import java.util.Calendar; | |||
import java.util.Date; | |||
import org.apache.poi.ss.formula.OperationEvaluationContext; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.formula.eval.EvaluationException; | |||
import org.apache.poi.ss.formula.eval.NumberEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.usermodel.DateUtil; | |||
/** | |||
* Implementation for Excel EDATE () function. | |||
*/ | |||
@@ -56,7 +61,13 @@ public class EDate implements FreeRefFunction { | |||
return 0; | |||
} | |||
if (arg instanceof RefEval) { | |||
ValueEval innerValueEval = ((RefEval) arg).getInnerValueEval(); | |||
RefEval refEval = (RefEval)arg; | |||
if (refEval.getNumberOfSheets() > 1) { | |||
// Multi-Sheet references are not supported | |||
throw new EvaluationException(ErrorEval.VALUE_INVALID); | |||
} | |||
ValueEval innerValueEval = refEval.getInnerValueEval(refEval.getFirstSheetIndex()); | |||
if(innerValueEval instanceof NumberEval) { | |||
return ((NumberEval) innerValueEval).getNumberValue(); | |||
} |
@@ -76,13 +76,16 @@ public final class LinearRegressionFunction extends Fixed2ArgFunction { | |||
private static final class RefValueArray extends ValueArray { | |||
private final RefEval _ref; | |||
private final int _width; | |||
public RefValueArray(RefEval ref) { | |||
super(1); | |||
super(ref.getNumberOfSheets()); | |||
_ref = ref; | |||
_width = ref.getNumberOfSheets(); | |||
} | |||
protected ValueEval getItemInternal(int index) { | |||
return _ref.getInnerValueEval(); | |||
int sIx = (index % _width) + _ref.getFirstSheetIndex(); | |||
return _ref.getInnerValueEval(sIx); | |||
} | |||
} | |||
@@ -17,6 +17,10 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.BoolEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
@@ -27,10 +31,6 @@ import org.apache.poi.ss.formula.eval.OperandResolver; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.StringEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
/** | |||
* Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH | |||
@@ -104,6 +104,28 @@ final class LookupUtils { | |||
} | |||
} | |||
private static final class SheetVector implements ValueVector { | |||
private final RefEval _re; | |||
private final int _size; | |||
public SheetVector(RefEval re) { | |||
_size = re.getNumberOfSheets(); | |||
_re = re; | |||
} | |||
public ValueEval getItem(int index) { | |||
if(index >= _size) { | |||
throw new ArrayIndexOutOfBoundsException("Specified index (" + index | |||
+ ") is outside the allowed range (0.." + (_size-1) + ")"); | |||
} | |||
int sheetIndex = _re.getFirstSheetIndex() + index; | |||
return _re.getInnerValueEval(sheetIndex); | |||
} | |||
public int getSize() { | |||
return _size; | |||
} | |||
} | |||
public static ValueVector createRowVector(TwoDEval tableArray, int relativeRowIndex) { | |||
return new RowVector(tableArray, relativeRowIndex); | |||
} | |||
@@ -122,6 +144,10 @@ final class LookupUtils { | |||
} | |||
return null; | |||
} | |||
public static ValueVector createVector(RefEval re) { | |||
return new SheetVector(re); | |||
} | |||
/** | |||
* Enumeration to support <b>4</b> valued comparison results.<p/> |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.formula.eval.EvaluationException; | |||
import org.apache.poi.ss.formula.eval.NumberEval; | |||
@@ -28,7 +29,6 @@ import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.functions.LookupUtils.CompareResult; | |||
import org.apache.poi.ss.formula.functions.LookupUtils.LookupValueComparer; | |||
import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* Implementation for the MATCH() Excel function.<p/> | |||
@@ -125,7 +125,11 @@ public final class Match extends Var2or3ArgFunction { | |||
private static ValueVector evaluateLookupRange(ValueEval eval) throws EvaluationException { | |||
if (eval instanceof RefEval) { | |||
RefEval re = (RefEval) eval; | |||
return new SingleValueVector(re.getInnerValueEval()); | |||
if (re.getNumberOfSheets() == 1) { | |||
return new SingleValueVector(re.getInnerValueEval(re.getFirstSheetIndex())); | |||
} else { | |||
return LookupUtils.createVector(re); | |||
} | |||
} | |||
if (eval instanceof TwoDEval) { | |||
ValueVector result = LookupUtils.createVector((TwoDEval)eval); |
@@ -21,6 +21,7 @@ import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.BoolEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
@@ -29,7 +30,6 @@ import org.apache.poi.ss.formula.eval.NumberEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.StringEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > | |||
@@ -106,7 +106,9 @@ public final class Mode implements Function { | |||
} | |||
if (arg instanceof RefEval) { | |||
RefEval re = (RefEval) arg; | |||
collectValue(re.getInnerValueEval(), temp, true); | |||
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) { | |||
collectValue(re.getInnerValueEval(sIx), temp, true); | |||
} | |||
return; | |||
} | |||
collectValue(arg, temp, true); |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.BoolEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
@@ -27,7 +28,6 @@ import org.apache.poi.ss.formula.eval.OperandResolver; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.StringValueEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > | |||
@@ -157,7 +157,9 @@ public abstract class MultiOperandNumericFunction implements Function { | |||
} | |||
if (operand instanceof RefEval) { | |||
RefEval re = (RefEval) operand; | |||
collectValue(re.getInnerValueEval(), true, temp); | |||
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) { | |||
collectValue(re.getInnerValueEval(sIx), true, temp); | |||
} | |||
return; | |||
} | |||
collectValue(operand, false, temp); |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.AreaEval; | |||
import org.apache.poi.ss.formula.eval.BlankEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
@@ -26,7 +27,6 @@ import org.apache.poi.ss.formula.eval.NumericValueEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.StringEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
@@ -99,7 +99,10 @@ public final class Sumproduct implements Function { | |||
ValueEval eval; | |||
if (arg instanceof RefEval) { | |||
RefEval re = (RefEval) arg; | |||
eval = re.getInnerValueEval(); | |||
if (re.getNumberOfSheets() > 1) { | |||
throw new EvaluationException(ErrorEval.VALUE_INVALID); | |||
} | |||
eval = re.getInnerValueEval(re.getFirstSheetIndex()); | |||
} else { | |||
eval = arg; | |||
} |
@@ -35,7 +35,9 @@ public final class T extends Fixed1ArgFunction { | |||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) { | |||
ValueEval arg = arg0; | |||
if (arg instanceof RefEval) { | |||
arg = ((RefEval) arg).getInnerValueEval(); | |||
// always use the first sheet | |||
RefEval re = (RefEval)arg; | |||
arg = re.getInnerValueEval(re.getFirstSheetIndex()); | |||
} else if (arg instanceof AreaEval) { | |||
// when the arg is an area, choose the top left cell | |||
arg = ((AreaEval) arg).getRelativeValue(0, 0); |
@@ -17,13 +17,13 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.formula.eval.EvaluationException; | |||
import org.apache.poi.ss.formula.eval.NumberEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.functions.LookupUtils.ValueVector; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
/** | |||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > | |||
@@ -61,12 +61,16 @@ public abstract class XYNumericFunction extends Fixed2ArgFunction { | |||
private static final class RefValueArray extends ValueArray { | |||
private final RefEval _ref; | |||
private final int _width; | |||
public RefValueArray(RefEval ref) { | |||
super(1); | |||
super(ref.getNumberOfSheets()); | |||
_ref = ref; | |||
_width = ref.getNumberOfSheets(); | |||
} | |||
protected ValueEval getItemInternal(int index) { | |||
return _ref.getInnerValueEval(); | |||
int sIx = (index % _width) + _ref.getFirstSheetIndex(); | |||
return _ref.getInnerValueEval(sIx); | |||
} | |||
} | |||
@@ -20,8 +20,6 @@ package org.apache.poi.ss.formula.eval; | |||
import junit.framework.AssertionFailedError; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.ss.formula.ptg.AreaI; | |||
import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; | |||
import org.apache.poi.hssf.usermodel.HSSFCell; | |||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; | |||
import org.apache.poi.hssf.usermodel.HSSFRow; | |||
@@ -29,6 +27,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.hssf.util.AreaReference; | |||
import org.apache.poi.hssf.util.CellReference; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.ptg.AreaI; | |||
import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; | |||
import org.apache.poi.ss.usermodel.CellValue; | |||
/** | |||
@@ -71,11 +71,10 @@ public final class TestRangeEval extends TestCase { | |||
} | |||
private static final class MockRefEval extends RefEvalBase { | |||
public MockRefEval(int rowIndex, int columnIndex) { | |||
super(rowIndex, columnIndex); | |||
super(-1, -1, rowIndex, columnIndex); | |||
} | |||
public ValueEval getInnerValueEval() { | |||
public ValueEval getInnerValueEval(int sheetIndex) { | |||
throw new RuntimeException("not expected to be called during this test"); | |||
} | |||
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, |
@@ -17,17 +17,17 @@ | |||
package org.apache.poi.ss.formula.functions; | |||
import org.apache.poi.ss.formula.ptg.AreaI; | |||
import org.apache.poi.ss.formula.ptg.AreaPtg; | |||
import org.apache.poi.ss.formula.ptg.Ref3DPtg; | |||
import org.apache.poi.ss.formula.ptg.RefPtg; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.eval.AreaEval; | |||
import org.apache.poi.ss.formula.eval.AreaEvalBase; | |||
import org.apache.poi.ss.formula.eval.NumberEval; | |||
import org.apache.poi.ss.formula.eval.RefEval; | |||
import org.apache.poi.ss.formula.eval.RefEvalBase; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.TwoDEval; | |||
import org.apache.poi.ss.formula.ptg.AreaI; | |||
import org.apache.poi.ss.formula.ptg.AreaPtg; | |||
import org.apache.poi.ss.formula.ptg.Ref3DPtg; | |||
import org.apache.poi.ss.formula.ptg.RefPtg; | |||
/** | |||
* Test helper class for creating mock <code>Eval</code> objects | |||
@@ -157,14 +157,14 @@ public final class EvalFactory { | |||
private static final class MockRefEval extends RefEvalBase { | |||
private final ValueEval _value; | |||
public MockRefEval(RefPtg ptg, ValueEval value) { | |||
super(ptg.getRow(), ptg.getColumn()); | |||
super(-1, -1, ptg.getRow(), ptg.getColumn()); | |||
_value = value; | |||
} | |||
public MockRefEval(Ref3DPtg ptg, ValueEval value) { | |||
super(ptg.getRow(), ptg.getColumn()); | |||
super(-1, -1, ptg.getRow(), ptg.getColumn()); | |||
_value = value; | |||
} | |||
public ValueEval getInnerValueEval() { | |||
public ValueEval getInnerValueEval(int sheetIndex) { | |||
return _value; | |||
} | |||
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { |
@@ -46,14 +46,23 @@ public class TestEDate extends TestCase{ | |||
throw new UnsupportedOperationException(); | |||
} | |||
public ValueEval getInnerValueEval(int sheetIndex) { | |||
return value; | |||
} | |||
public int getNumberOfSheets() { | |||
return 1; | |||
} | |||
public int getFirstSheetIndex() { | |||
return 0; | |||
} | |||
public int getLastSheetIndex() { | |||
return 0; | |||
} | |||
public int getRow() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
public ValueEval getInnerValueEval() { | |||
return value; | |||
} | |||
public int getColumn() { | |||
throw new UnsupportedOperationException(); | |||
} |