You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC
svn commit: r1890120 [21/43] - in /poi/trunk/poi/src:
main/java/org/apache/poi/ main/java/org/apache/poi/ddf/
main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/
main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/
main/java...
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/NumericFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/NumericFunction.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/NumericFunction.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/NumericFunction.java Sat May 22 20:56:44 2021
@@ -23,218 +23,218 @@ import org.apache.poi.ss.formula.eval.*;
public abstract class NumericFunction implements Function {
- private static final double ZERO = 0.0;
- private static final double TEN = 10.0;
- private static final double LOG_10_TO_BASE_e = Math.log(TEN);
- private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
-
-
- protected static double singleOperandEvaluate(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
- if (arg == null) {
- throw new IllegalArgumentException("arg must not be null");
- }
- ValueEval ve = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
- double result = OperandResolver.coerceValueToDouble(ve);
- checkValue(result);
- return result;
- }
-
- /**
- * @throws EvaluationException (#NUM!) if {@code result} is {@code NaN} or {@code Infinity}
- */
- public static void checkValue(double result) throws EvaluationException {
- if (Double.isNaN(result) || Double.isInfinite(result)) {
- throw new EvaluationException(ErrorEval.NUM_ERROR);
- }
- }
-
- @Override
- public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
- double result;
- try {
- result = eval(args, srcCellRow, srcCellCol);
- checkValue(result);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(result);
- }
-
- protected abstract double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException;
-
- public static final Function ABS = oneDouble(Math::abs);
- public static final Function ACOS = oneDouble(Math::acos);
- public static final Function ACOSH = oneDouble(MathX::acosh);
- public static final Function ASIN = oneDouble(Math::asin);
- public static final Function ASINH = oneDouble(MathX::asinh);
- public static final Function ATAN = oneDouble(Math::atan);
- public static final Function ATANH = oneDouble(MathX::atanh);
- public static final Function COS = oneDouble(Math::cos);
- public static final Function COSH = oneDouble(MathX::cosh);
- public static final Function DEGREES = oneDouble(Math::toDegrees);
- public static final Function DOLLAR = NumericFunction::evaluateDollar;
-
- private static ValueEval evaluateDollar(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- if (args.length != 1 && args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- try {
- double val = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
- double d1 = args.length == 1 ? 2.0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
-
- // second arg converts to int by truncating toward zero
- int nPlaces = (int)d1;
-
- if (nPlaces > 127) {
- return VALUE_INVALID;
- }
-
- // TODO - DOLLAR() function impl is NQR
- // result should be StringEval, with leading '$' and thousands separators
- // current junits are asserting incorrect behaviour
- return new NumberEval(val);
- }catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
-
- public static final Function EXP = oneDouble(d -> Math.pow(Math.E, d));
- public static final Function FACT = oneDouble(MathX::factorial);
- public static final Function INT = oneDouble(d -> Math.round(d-0.5));
- public static final Function LN = oneDouble(Math::log);
- public static final Function LOG10 = oneDouble(d -> Math.log(d) / LOG_10_TO_BASE_e);
- public static final Function RADIANS = oneDouble(Math::toRadians);
- public static final Function SIGN = oneDouble(MathX::sign);
- public static final Function SIN = oneDouble(Math::sin);
- public static final Function SINH = oneDouble(MathX::sinh);
- public static final Function SQRT = oneDouble(Math::sqrt);
- public static final Function TAN = oneDouble(Math::tan);
- public static final Function TANH = oneDouble(MathX::tanh);
-
- /* -------------------------------------------------------------------------- */
-
- public static final Function ATAN2 = twoDouble((d0, d1) ->
- (d0 == ZERO && d1 == ZERO) ? ErrorEval.DIV_ZERO : Math.atan2(d1, d0)
- );
-
- public static final Function CEILING = twoDouble(MathX::ceiling);
-
- public static final Function COMBIN = twoDouble((d0, d1) ->
- (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) ? ErrorEval.NUM_ERROR : MathX.nChooseK((int) d0, (int) d1));
-
- public static final Function FLOOR = twoDouble((d0, d1) ->
- (d1 == ZERO) ? (d0 == ZERO ? ZERO : ErrorEval.DIV_ZERO) : MathX.floor(d0, d1));
-
- public static final Function MOD = twoDouble((d0, d1) ->
- (d1 == ZERO) ? ErrorEval.DIV_ZERO : MathX.mod(d0, d1));
-
- public static final Function POWER = twoDouble(Math::pow);
-
- public static final Function ROUND = twoDouble(MathX::round);
- public static final Function ROUNDDOWN = twoDouble(MathX::roundDown);
- public static final Function ROUNDUP = twoDouble(MathX::roundUp);
- public static final Function TRUNC = NumericFunction::evaluateTrunc;
-
- private static ValueEval evaluateTrunc(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- if (args.length != 1 && args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- try {
- double d0 = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
- double d1 = args.length == 1 ? 0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
- double result = MathX.roundDown(d0, d1);
- checkValue(result);
- return new NumberEval(result);
- }catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
-
- /* -------------------------------------------------------------------------- */
-
- public static final Function LOG = Log::evaluate;
-
- static final NumberEval PI_EVAL = new NumberEval(Math.PI);
- public static final Function PI = NumericFunction::evaluatePI;
-
- private static ValueEval evaluatePI(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- return (args.length != 0) ? ErrorEval.VALUE_INVALID : PI_EVAL;
- }
-
- public static final Function RAND = NumericFunction::evaluateRand;
-
- private static ValueEval evaluateRand(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- return (args.length != 0) ? ErrorEval.VALUE_INVALID : new NumberEval(Math.random());
- }
-
- public static final Function POISSON = Poisson::evaluate;
-
- public static final Function ODD = oneDouble(NumericFunction::evaluateOdd);
-
- private static double evaluateOdd(double d) {
- if (d==0) {
- return 1;
- }
- double dpm = Math.abs(d)+1;
- long x = ((long) dpm) & PARITY_MASK;
- return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x-1 : x+1);
- }
-
-
- public static final Function EVEN = oneDouble(NumericFunction::evaluateEven);
-
- private static double evaluateEven(double d) {
- if (d==0) {
- return 0;
- }
-
- double dpm = Math.abs(d);
- long x = ((long) dpm) & PARITY_MASK;
- return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x : (x + 2));
- }
-
-
- private interface OneDoubleIf {
- double apply(double d);
- }
-
- private static Function oneDouble(OneDoubleIf doubleFun) {
- return (args, srcCellRow, srcCellCol) -> {
- if (args.length != 1) {
- return VALUE_INVALID;
- }
- try {
- double d = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
- double res = doubleFun.apply(d);
- return (Double.isNaN(res) || Double.isInfinite(res)) ? ErrorEval.NUM_ERROR : new NumberEval(res);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- };
- }
-
- private interface TwoDoubleIf {
- Object apply(double d1, double d2);
- }
-
- private static Function twoDouble(TwoDoubleIf doubleFun) {
- return (args, srcCellRow, srcCellCol) -> {
- if (args.length != 2) {
- return VALUE_INVALID;
- }
- try {
- double d1 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
- double d2 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol);
- Object res = doubleFun.apply(d1, d2);
- if (res instanceof ErrorEval) {
- return (ErrorEval)res;
- }
- assert(res instanceof Double);
- double d = (Double)res;
- return (Double.isNaN(d) || Double.isInfinite(d)) ? ErrorEval.NUM_ERROR : new NumberEval(d);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- };
- }
+ private static final double ZERO = 0.0;
+ private static final double TEN = 10.0;
+ private static final double LOG_10_TO_BASE_e = Math.log(TEN);
+ private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
+
+
+ protected static double singleOperandEvaluate(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
+ if (arg == null) {
+ throw new IllegalArgumentException("arg must not be null");
+ }
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
+ double result = OperandResolver.coerceValueToDouble(ve);
+ checkValue(result);
+ return result;
+ }
+
+ /**
+ * @throws EvaluationException (#NUM!) if {@code result} is {@code NaN} or {@code Infinity}
+ */
+ public static void checkValue(double result) throws EvaluationException {
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ throw new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+ }
+
+ @Override
+ public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
+ double result;
+ try {
+ result = eval(args, srcCellRow, srcCellCol);
+ checkValue(result);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(result);
+ }
+
+ protected abstract double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException;
+
+ public static final Function ABS = oneDouble(Math::abs);
+ public static final Function ACOS = oneDouble(Math::acos);
+ public static final Function ACOSH = oneDouble(MathX::acosh);
+ public static final Function ASIN = oneDouble(Math::asin);
+ public static final Function ASINH = oneDouble(MathX::asinh);
+ public static final Function ATAN = oneDouble(Math::atan);
+ public static final Function ATANH = oneDouble(MathX::atanh);
+ public static final Function COS = oneDouble(Math::cos);
+ public static final Function COSH = oneDouble(MathX::cosh);
+ public static final Function DEGREES = oneDouble(Math::toDegrees);
+ public static final Function DOLLAR = NumericFunction::evaluateDollar;
+
+ private static ValueEval evaluateDollar(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ if (args.length != 1 && args.length != 2) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ try {
+ double val = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
+ double d1 = args.length == 1 ? 2.0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
+
+ // second arg converts to int by truncating toward zero
+ int nPlaces = (int)d1;
+
+ if (nPlaces > 127) {
+ return VALUE_INVALID;
+ }
+
+ // TODO - DOLLAR() function impl is NQR
+ // result should be StringEval, with leading '$' and thousands separators
+ // current junits are asserting incorrect behaviour
+ return new NumberEval(val);
+ }catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ }
+
+ public static final Function EXP = oneDouble(d -> Math.pow(Math.E, d));
+ public static final Function FACT = oneDouble(MathX::factorial);
+ public static final Function INT = oneDouble(d -> Math.round(d-0.5));
+ public static final Function LN = oneDouble(Math::log);
+ public static final Function LOG10 = oneDouble(d -> Math.log(d) / LOG_10_TO_BASE_e);
+ public static final Function RADIANS = oneDouble(Math::toRadians);
+ public static final Function SIGN = oneDouble(MathX::sign);
+ public static final Function SIN = oneDouble(Math::sin);
+ public static final Function SINH = oneDouble(MathX::sinh);
+ public static final Function SQRT = oneDouble(Math::sqrt);
+ public static final Function TAN = oneDouble(Math::tan);
+ public static final Function TANH = oneDouble(MathX::tanh);
+
+ /* -------------------------------------------------------------------------- */
+
+ public static final Function ATAN2 = twoDouble((d0, d1) ->
+ (d0 == ZERO && d1 == ZERO) ? ErrorEval.DIV_ZERO : Math.atan2(d1, d0)
+ );
+
+ public static final Function CEILING = twoDouble(MathX::ceiling);
+
+ public static final Function COMBIN = twoDouble((d0, d1) ->
+ (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) ? ErrorEval.NUM_ERROR : MathX.nChooseK((int) d0, (int) d1));
+
+ public static final Function FLOOR = twoDouble((d0, d1) ->
+ (d1 == ZERO) ? (d0 == ZERO ? ZERO : ErrorEval.DIV_ZERO) : MathX.floor(d0, d1));
+
+ public static final Function MOD = twoDouble((d0, d1) ->
+ (d1 == ZERO) ? ErrorEval.DIV_ZERO : MathX.mod(d0, d1));
+
+ public static final Function POWER = twoDouble(Math::pow);
+
+ public static final Function ROUND = twoDouble(MathX::round);
+ public static final Function ROUNDDOWN = twoDouble(MathX::roundDown);
+ public static final Function ROUNDUP = twoDouble(MathX::roundUp);
+ public static final Function TRUNC = NumericFunction::evaluateTrunc;
+
+ private static ValueEval evaluateTrunc(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ if (args.length != 1 && args.length != 2) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ try {
+ double d0 = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
+ double d1 = args.length == 1 ? 0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
+ double result = MathX.roundDown(d0, d1);
+ checkValue(result);
+ return new NumberEval(result);
+ }catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ }
+
+ /* -------------------------------------------------------------------------- */
+
+ public static final Function LOG = Log::evaluate;
+
+ static final NumberEval PI_EVAL = new NumberEval(Math.PI);
+ public static final Function PI = NumericFunction::evaluatePI;
+
+ private static ValueEval evaluatePI(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ return (args.length != 0) ? ErrorEval.VALUE_INVALID : PI_EVAL;
+ }
+
+ public static final Function RAND = NumericFunction::evaluateRand;
+
+ private static ValueEval evaluateRand(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ return (args.length != 0) ? ErrorEval.VALUE_INVALID : new NumberEval(Math.random());
+ }
+
+ public static final Function POISSON = Poisson::evaluate;
+
+ public static final Function ODD = oneDouble(NumericFunction::evaluateOdd);
+
+ private static double evaluateOdd(double d) {
+ if (d==0) {
+ return 1;
+ }
+ double dpm = Math.abs(d)+1;
+ long x = ((long) dpm) & PARITY_MASK;
+ return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x-1 : x+1);
+ }
+
+
+ public static final Function EVEN = oneDouble(NumericFunction::evaluateEven);
+
+ private static double evaluateEven(double d) {
+ if (d==0) {
+ return 0;
+ }
+
+ double dpm = Math.abs(d);
+ long x = ((long) dpm) & PARITY_MASK;
+ return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x : (x + 2));
+ }
+
+
+ private interface OneDoubleIf {
+ double apply(double d);
+ }
+
+ private static Function oneDouble(OneDoubleIf doubleFun) {
+ return (args, srcCellRow, srcCellCol) -> {
+ if (args.length != 1) {
+ return VALUE_INVALID;
+ }
+ try {
+ double d = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
+ double res = doubleFun.apply(d);
+ return (Double.isNaN(res) || Double.isInfinite(res)) ? ErrorEval.NUM_ERROR : new NumberEval(res);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ };
+ }
+
+ private interface TwoDoubleIf {
+ Object apply(double d1, double d2);
+ }
+
+ private static Function twoDouble(TwoDoubleIf doubleFun) {
+ return (args, srcCellRow, srcCellCol) -> {
+ if (args.length != 2) {
+ return VALUE_INVALID;
+ }
+ try {
+ double d1 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
+ double d2 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol);
+ Object res = doubleFun.apply(d1, d2);
+ if (res instanceof ErrorEval) {
+ return (ErrorEval)res;
+ }
+ assert(res instanceof Double);
+ double d = (Double)res;
+ return (Double.isNaN(d) || Double.isInfinite(d)) ? ErrorEval.NUM_ERROR : new NumberEval(d);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ };
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/PPMT.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/PPMT.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/PPMT.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/PPMT.java Sat May 22 20:56:44 2021
@@ -26,30 +26,30 @@ import org.apache.poi.ss.formula.eval.*;
*/
public class PPMT extends NumericFunction {
- @Override
- public double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException {
+ @Override
+ public double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException {
- if(args.length < 4)
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ if(args.length < 4)
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
- double result;
+ double result;
- ValueEval v1 = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+ ValueEval v1 = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
ValueEval v2 = OperandResolver.getSingleValue(args[1], srcCellRow, srcCellCol);
ValueEval v3 = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol);
ValueEval v4 = OperandResolver.getSingleValue(args[3], srcCellRow, srcCellCol);
- double interestRate = OperandResolver.coerceValueToDouble(v1);
+ double interestRate = OperandResolver.coerceValueToDouble(v1);
int period = OperandResolver.coerceValueToInt(v2);
int numberPayments = OperandResolver.coerceValueToInt(v3);
double PV = OperandResolver.coerceValueToDouble(v4);
- result = Finance.ppmt(interestRate, period, numberPayments, PV) ;
+ result = Finance.ppmt(interestRate, period, numberPayments, PV) ;
- checkValue(result);
+ checkValue(result);
- return result;
- }
+ return result;
+ }
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rank.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rank.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rank.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rank.java Sat May 22 20:56:44 2021
@@ -33,10 +33,10 @@ import org.apache.poi.ss.formula.eval.Va
* Returns the rank of a number in a list of numbers. The rank of a number is its size relative to other values in a list.
* Syntax:
- * RANK(number,ref,order)
- * Number is the number whose rank you want to find.
- * Ref is an array of, or a reference to, a list of numbers. Nonnumeric values in ref are ignored.
- * Order is a number specifying how to rank number.
+ * RANK(number,ref,order)
+ * Number is the number whose rank you want to find.
+ * Ref is an array of, or a reference to, a list of numbers. Nonnumeric values in ref are ignored.
+ * Order is a number specifying how to rank number.
* If order is 0 (zero) or omitted, Microsoft Excel ranks number as if ref were a list sorted in descending order.
* If order is any nonzero value, Microsoft Excel ranks number as if ref were a list sorted in ascending order.
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Replace.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Replace.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Replace.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Replace.java Sat May 22 20:56:44 2021
@@ -37,36 +37,36 @@ import org.apache.poi.ss.formula.eval.Va
*/
public final class Replace extends Fixed4ArgFunction {
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2, ValueEval arg3) {
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2, ValueEval arg3) {
- String oldStr;
- int startNum;
- int numChars;
- String newStr;
- try {
- oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- startNum = TextFunction.evaluateIntArg(arg1, srcRowIndex, srcColumnIndex);
- numChars = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex);
- newStr = TextFunction.evaluateStringArg(arg3, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
+ String oldStr;
+ int startNum;
+ int numChars;
+ String newStr;
+ try {
+ oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
+ startNum = TextFunction.evaluateIntArg(arg1, srcRowIndex, srcColumnIndex);
+ numChars = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex);
+ newStr = TextFunction.evaluateStringArg(arg3, srcRowIndex, srcColumnIndex);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
- if (startNum < 1 || numChars < 0) {
- return ErrorEval.VALUE_INVALID;
- }
- StringBuilder strBuff = new StringBuilder(oldStr);
- // remove any characters that should be replaced
- if (startNum <= oldStr.length() && numChars != 0) {
- strBuff.delete(startNum - 1, startNum - 1 + numChars);
- }
- // now insert (or append) newStr
- if (startNum > strBuff.length()) {
- strBuff.append(newStr);
- } else {
- strBuff.insert(startNum - 1, newStr);
- }
- return new StringEval(strBuff.toString());
- }
+ if (startNum < 1 || numChars < 0) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ StringBuilder strBuff = new StringBuilder(oldStr);
+ // remove any characters that should be replaced
+ if (startNum <= oldStr.length() && numChars != 0) {
+ strBuff.delete(startNum - 1, startNum - 1 + numChars);
+ }
+ // now insert (or append) newStr
+ if (startNum > strBuff.length()) {
+ strBuff.append(newStr);
+ } else {
+ strBuff.insert(startNum - 1, newStr);
+ }
+ return new StringEval(strBuff.toString());
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rept.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rept.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rept.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rept.java Sat May 22 20:56:44 2021
@@ -31,7 +31,7 @@ import org.apache.poi.ss.formula.eval.Va
* Repeats text a given number of times. Use REPT to fill a cell with a number of instances of a text string.
*
* text : text The text that you want to repeat.
- * number_times: A positive number specifying the number of times to repeat text.
+ * number_times: A positive number specifying the number of times to repeat text.
*
* If number_times is 0 (zero), REPT returns "" (empty text).
* If this argument contains a decimal value, this function ignores the numbers to the right side of the decimal point.
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rows.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rows.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rows.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Rows.java Sat May 22 20:56:44 2021
@@ -28,16 +28,16 @@ import org.apache.poi.ss.formula.TwoDEva
*/
public final class Rows extends Fixed1ArgFunction {
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- int result;
- if (arg0 instanceof TwoDEval) {
- result = ((TwoDEval) arg0).getHeight();
- } else if (arg0 instanceof RefEval) {
- result = 1;
- } else { // anything else is not valid argument
- return ErrorEval.VALUE_INVALID;
- }
- return new NumberEval(result);
- }
+ int result;
+ if (arg0 instanceof TwoDEval) {
+ result = ((TwoDEval) arg0).getHeight();
+ } else if (arg0 instanceof RefEval) {
+ result = 1;
+ } else { // anything else is not valid argument
+ return ErrorEval.VALUE_INVALID;
+ }
+ return new NumberEval(result);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Slope.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Slope.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Slope.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Slope.java Sat May 22 20:56:44 2021
@@ -32,15 +32,15 @@ import org.apache.poi.ss.formula.functio
*/
public final class Slope extends Fixed2ArgFunction {
- private final LinearRegressionFunction func;
- public Slope() {
- func = new LinearRegressionFunction(FUNCTION.SLOPE);
- }
+ private final LinearRegressionFunction func;
+ public Slope() {
+ func = new LinearRegressionFunction(FUNCTION.SLOPE);
+ }
- @Override
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex,
- ValueEval arg0, ValueEval arg1) {
- return func.evaluate(srcRowIndex, srcColumnIndex, arg0, arg1);
- }
+ @Override
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex,
+ ValueEval arg0, ValueEval arg1) {
+ return func.evaluate(srcRowIndex, srcColumnIndex, arg0, arg1);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Substitute.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Substitute.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Substitute.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Substitute.java Sat May 22 20:56:44 2021
@@ -28,82 +28,82 @@ import org.apache.poi.ss.formula.eval.Va
*/
public final class Substitute extends Var3or4ArgFunction {
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2) {
- String result;
- try {
- String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
- String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
-
- result = replaceAllOccurrences(oldStr, searchStr, newStr);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new StringEval(result);
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2, ValueEval arg3) {
- String result;
- try {
- String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
- String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
-
- int instanceNumber = TextFunction.evaluateIntArg(arg3, srcRowIndex, srcColumnIndex);
- if (instanceNumber < 1) {
- return ErrorEval.VALUE_INVALID;
- }
- result = replaceOneOccurrence(oldStr, searchStr, newStr, instanceNumber);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new StringEval(result);
- }
-
- private static String replaceAllOccurrences(String oldStr, String searchStr, String newStr) {
- // avoid endless loop when searching for nothing
- if (searchStr.length() < 1) {
- return oldStr;
- }
-
- StringBuilder sb = new StringBuilder();
- int startIndex = 0;
- while (true) {
- int nextMatch = oldStr.indexOf(searchStr, startIndex);
- if (nextMatch < 0) {
- // store everything from end of last match to end of string
- sb.append(oldStr.substring(startIndex));
- return sb.toString();
- }
- // store everything from end of last match to start of this match
- sb.append(oldStr, startIndex, nextMatch);
- sb.append(newStr);
- startIndex = nextMatch + searchStr.length();
- }
- }
-
- private static String replaceOneOccurrence(String oldStr, String searchStr, String newStr, int instanceNumber) {
- // avoid endless loop when searching for nothing
- if (searchStr.length() < 1) {
- return oldStr;
- }
- int startIndex = 0;
- int count=0;
- while (true) {
- int nextMatch = oldStr.indexOf(searchStr, startIndex);
- if (nextMatch < 0) {
- // not enough occurrences found - leave unchanged
- return oldStr;
- }
- count++;
- if (count == instanceNumber) {
- return oldStr.substring(0, nextMatch) +
- newStr +
- oldStr.substring(nextMatch + searchStr.length());
- }
- startIndex = nextMatch + searchStr.length();
- }
- }
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2) {
+ String result;
+ try {
+ String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
+ String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
+ String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
+
+ result = replaceAllOccurrences(oldStr, searchStr, newStr);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new StringEval(result);
+ }
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2, ValueEval arg3) {
+ String result;
+ try {
+ String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
+ String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
+ String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
+
+ int instanceNumber = TextFunction.evaluateIntArg(arg3, srcRowIndex, srcColumnIndex);
+ if (instanceNumber < 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ result = replaceOneOccurrence(oldStr, searchStr, newStr, instanceNumber);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new StringEval(result);
+ }
+
+ private static String replaceAllOccurrences(String oldStr, String searchStr, String newStr) {
+ // avoid endless loop when searching for nothing
+ if (searchStr.length() < 1) {
+ return oldStr;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ int startIndex = 0;
+ while (true) {
+ int nextMatch = oldStr.indexOf(searchStr, startIndex);
+ if (nextMatch < 0) {
+ // store everything from end of last match to end of string
+ sb.append(oldStr.substring(startIndex));
+ return sb.toString();
+ }
+ // store everything from end of last match to start of this match
+ sb.append(oldStr, startIndex, nextMatch);
+ sb.append(newStr);
+ startIndex = nextMatch + searchStr.length();
+ }
+ }
+
+ private static String replaceOneOccurrence(String oldStr, String searchStr, String newStr, int instanceNumber) {
+ // avoid endless loop when searching for nothing
+ if (searchStr.length() < 1) {
+ return oldStr;
+ }
+ int startIndex = 0;
+ int count=0;
+ while (true) {
+ int nextMatch = oldStr.indexOf(searchStr, startIndex);
+ if (nextMatch < 0) {
+ // not enough occurrences found - leave unchanged
+ return oldStr;
+ }
+ count++;
+ if (count == instanceNumber) {
+ return oldStr.substring(0, nextMatch) +
+ newStr +
+ oldStr.substring(nextMatch + searchStr.length());
+ }
+ startIndex = nextMatch + searchStr.length();
+ }
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Subtotal.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Subtotal.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Subtotal.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Subtotal.java Sat May 22 20:56:44 2021
@@ -73,72 +73,72 @@ import org.apache.poi.ss.formula.eval.Va
*/
public class Subtotal implements Function {
- private static Function findFunction(int functionCode) throws EvaluationException {
+ private static Function findFunction(int functionCode) throws EvaluationException {
switch (functionCode) {
- case 1: return subtotalInstance(AggregateFunction.AVERAGE, true);
- case 2: return Count.subtotalInstance(true);
- case 3: return Counta.subtotalInstance(true);
- case 4: return subtotalInstance(AggregateFunction.MAX, true);
- case 5: return subtotalInstance(AggregateFunction.MIN, true);
- case 6: return subtotalInstance(AggregateFunction.PRODUCT, true);
- case 7: return subtotalInstance(AggregateFunction.STDEV, true);
- case 8: throw new NotImplementedFunctionException("STDEVP");
- case 9: return subtotalInstance(AggregateFunction.SUM, true);
- case 10: throw new NotImplementedFunctionException("VAR");
- case 11: throw new NotImplementedFunctionException("VARP");
- case 101: return subtotalInstance(AggregateFunction.AVERAGE, false);
- case 102: return Count.subtotalInstance(false);
- case 103: return Counta.subtotalInstance(false);
- case 104: return subtotalInstance(AggregateFunction.MAX, false);
- case 105: return subtotalInstance(AggregateFunction.MIN, false);
- case 106: return subtotalInstance(AggregateFunction.PRODUCT, false);
- case 107: return subtotalInstance(AggregateFunction.STDEV, false);
- case 108: throw new NotImplementedFunctionException("STDEVP SUBTOTAL with 'exclude hidden values' option");
- case 109: return subtotalInstance(AggregateFunction.SUM, false);
- case 110: throw new NotImplementedFunctionException("VAR SUBTOTAL with 'exclude hidden values' option");
- case 111: throw new NotImplementedFunctionException("VARP SUBTOTAL with 'exclude hidden values' option");
- }
- throw EvaluationException.invalidValue();
- }
-
- @Override
- public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- int nInnerArgs = args.length-1; // -1: first arg is used to select from a basic aggregate function
- if (nInnerArgs < 1) {
- return ErrorEval.VALUE_INVALID;
- }
-
- final Function innerFunc;
- int functionCode;
- try {
- ValueEval ve = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex);
+ case 1: return subtotalInstance(AggregateFunction.AVERAGE, true);
+ case 2: return Count.subtotalInstance(true);
+ case 3: return Counta.subtotalInstance(true);
+ case 4: return subtotalInstance(AggregateFunction.MAX, true);
+ case 5: return subtotalInstance(AggregateFunction.MIN, true);
+ case 6: return subtotalInstance(AggregateFunction.PRODUCT, true);
+ case 7: return subtotalInstance(AggregateFunction.STDEV, true);
+ case 8: throw new NotImplementedFunctionException("STDEVP");
+ case 9: return subtotalInstance(AggregateFunction.SUM, true);
+ case 10: throw new NotImplementedFunctionException("VAR");
+ case 11: throw new NotImplementedFunctionException("VARP");
+ case 101: return subtotalInstance(AggregateFunction.AVERAGE, false);
+ case 102: return Count.subtotalInstance(false);
+ case 103: return Counta.subtotalInstance(false);
+ case 104: return subtotalInstance(AggregateFunction.MAX, false);
+ case 105: return subtotalInstance(AggregateFunction.MIN, false);
+ case 106: return subtotalInstance(AggregateFunction.PRODUCT, false);
+ case 107: return subtotalInstance(AggregateFunction.STDEV, false);
+ case 108: throw new NotImplementedFunctionException("STDEVP SUBTOTAL with 'exclude hidden values' option");
+ case 109: return subtotalInstance(AggregateFunction.SUM, false);
+ case 110: throw new NotImplementedFunctionException("VAR SUBTOTAL with 'exclude hidden values' option");
+ case 111: throw new NotImplementedFunctionException("VARP SUBTOTAL with 'exclude hidden values' option");
+ }
+ throw EvaluationException.invalidValue();
+ }
+
+ @Override
+ public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ int nInnerArgs = args.length-1; // -1: first arg is used to select from a basic aggregate function
+ if (nInnerArgs < 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ final Function innerFunc;
+ int functionCode;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex);
functionCode = OperandResolver.coerceValueToInt(ve);
- innerFunc = findFunction(functionCode);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
-
- // ignore the first arg, this is the function-type, we check for the length above
- final List<ValueEval> list = new ArrayList<>(Arrays.asList(args).subList(1, args.length));
-
- Iterator<ValueEval> it = list.iterator();
-
- // See https://support.office.com/en-us/article/SUBTOTAL-function-7b027003-f060-4ade-9040-e478765b9939
- // "If there are other subtotals within ref1, ref2,... (or nested subtotals), these nested subtotals are ignored to avoid double counting."
- // For array references it is handled in other evaluation steps, but we need to handle this here for references to subtotal-functions
- while(it.hasNext()) {
- ValueEval eval = it.next();
- if(eval instanceof LazyRefEval) {
- LazyRefEval lazyRefEval = (LazyRefEval) eval;
- if(lazyRefEval.isSubTotal()) {
- it.remove();
- }
- if (functionCode > 100 && lazyRefEval.isRowHidden()) {
- it.remove();
- }
- }
- }
+ innerFunc = findFunction(functionCode);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+
+ // ignore the first arg, this is the function-type, we check for the length above
+ final List<ValueEval> list = new ArrayList<>(Arrays.asList(args).subList(1, args.length));
+
+ Iterator<ValueEval> it = list.iterator();
+
+ // See https://support.office.com/en-us/article/SUBTOTAL-function-7b027003-f060-4ade-9040-e478765b9939
+ // "If there are other subtotals within ref1, ref2,... (or nested subtotals), these nested subtotals are ignored to avoid double counting."
+ // For array references it is handled in other evaluation steps, but we need to handle this here for references to subtotal-functions
+ while(it.hasNext()) {
+ ValueEval eval = it.next();
+ if(eval instanceof LazyRefEval) {
+ LazyRefEval lazyRefEval = (LazyRefEval) eval;
+ if(lazyRefEval.isSubTotal()) {
+ it.remove();
+ }
+ if (functionCode > 100 && lazyRefEval.isRowHidden()) {
+ it.remove();
+ }
+ }
+ }
- return innerFunc.evaluate(list.toArray(new ValueEval[0]), srcRowIndex, srcColumnIndex);
- }
+ return innerFunc.evaluate(list.toArray(new ValueEval[0]), srcRowIndex, srcColumnIndex);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumif.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumif.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumif.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumif.java Sat May 22 20:56:44 2021
@@ -39,96 +39,96 @@ import org.apache.poi.ss.formula.functio
*/
public final class Sumif extends Var2or3ArgFunction {
- @Override
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
+ @Override
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
- AreaEval aeRange;
- try {
- aeRange = convertRangeArg(arg0);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeRange);
- }
-
- @Override
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2) {
-
- AreaEval aeRange;
- AreaEval aeSum;
- try {
- aeRange = convertRangeArg(arg0);
- aeSum = createSumRange(arg2, aeRange);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeSum);
- }
-
- private static ValueEval eval(int srcRowIndex, int srcColumnIndex, ValueEval arg1, AreaEval aeRange,
- AreaEval aeSum) {
- // TODO - junit to prove last arg must be srcColumnIndex and not srcRowIndex
- I_MatchPredicate mp = Countif.createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
-
- // handle empty cells
- if(mp == null) {
- return NumberEval.ZERO;
- }
-
- double result = sumMatchingCells(aeRange, mp, aeSum);
- return new NumberEval(result);
- }
-
- private static double sumMatchingCells(AreaEval aeRange, I_MatchPredicate mp, AreaEval aeSum) {
- int height=aeRange.getHeight();
- int width= aeRange.getWidth();
-
- double result = 0.0;
- for (int r=0; r<height; r++) {
- for (int c=0; c<width; c++) {
- result += accumulate(aeRange, mp, aeSum, r, c);
- }
- }
- return result;
- }
-
- private static double accumulate(AreaEval aeRange, I_MatchPredicate mp, AreaEval aeSum, int relRowIndex,
- int relColIndex) {
-
- if (!mp.matches(aeRange.getRelativeValue(relRowIndex, relColIndex))) {
- return 0.0;
- }
- ValueEval addend = aeSum.getRelativeValue(relRowIndex, relColIndex);
- if (addend instanceof NumberEval) {
- return ((NumberEval)addend).getNumberValue();
- }
- // everything else (including string and boolean values) counts as zero
- return 0.0;
- }
-
- /**
- * @return a range of the same dimensions as aeRange using eval to define the top left corner.
- * @throws EvaluationException if eval is not a reference
- */
- private static AreaEval createSumRange(ValueEval eval, AreaEval aeRange) throws EvaluationException {
- if (eval instanceof AreaEval) {
- return ((AreaEval) eval).offset(0, aeRange.getHeight()-1, 0, aeRange.getWidth()-1);
- }
- if (eval instanceof RefEval) {
- return ((RefEval)eval).offset(0, aeRange.getHeight()-1, 0, aeRange.getWidth()-1);
- }
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
-
- private static AreaEval convertRangeArg(ValueEval eval) throws EvaluationException {
- if (eval instanceof AreaEval) {
- return (AreaEval) eval;
- }
- if (eval instanceof RefEval) {
- return ((RefEval)eval).offset(0, 0, 0, 0);
- }
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
+ AreaEval aeRange;
+ try {
+ aeRange = convertRangeArg(arg0);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeRange);
+ }
+
+ @Override
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2) {
+
+ AreaEval aeRange;
+ AreaEval aeSum;
+ try {
+ aeRange = convertRangeArg(arg0);
+ aeSum = createSumRange(arg2, aeRange);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return eval(srcRowIndex, srcColumnIndex, arg1, aeRange, aeSum);
+ }
+
+ private static ValueEval eval(int srcRowIndex, int srcColumnIndex, ValueEval arg1, AreaEval aeRange,
+ AreaEval aeSum) {
+ // TODO - junit to prove last arg must be srcColumnIndex and not srcRowIndex
+ I_MatchPredicate mp = Countif.createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
+
+ // handle empty cells
+ if(mp == null) {
+ return NumberEval.ZERO;
+ }
+
+ double result = sumMatchingCells(aeRange, mp, aeSum);
+ return new NumberEval(result);
+ }
+
+ private static double sumMatchingCells(AreaEval aeRange, I_MatchPredicate mp, AreaEval aeSum) {
+ int height=aeRange.getHeight();
+ int width= aeRange.getWidth();
+
+ double result = 0.0;
+ for (int r=0; r<height; r++) {
+ for (int c=0; c<width; c++) {
+ result += accumulate(aeRange, mp, aeSum, r, c);
+ }
+ }
+ return result;
+ }
+
+ private static double accumulate(AreaEval aeRange, I_MatchPredicate mp, AreaEval aeSum, int relRowIndex,
+ int relColIndex) {
+
+ if (!mp.matches(aeRange.getRelativeValue(relRowIndex, relColIndex))) {
+ return 0.0;
+ }
+ ValueEval addend = aeSum.getRelativeValue(relRowIndex, relColIndex);
+ if (addend instanceof NumberEval) {
+ return ((NumberEval)addend).getNumberValue();
+ }
+ // everything else (including string and boolean values) counts as zero
+ return 0.0;
+ }
+
+ /**
+ * @return a range of the same dimensions as aeRange using eval to define the top left corner.
+ * @throws EvaluationException if eval is not a reference
+ */
+ private static AreaEval createSumRange(ValueEval eval, AreaEval aeRange) throws EvaluationException {
+ if (eval instanceof AreaEval) {
+ return ((AreaEval) eval).offset(0, aeRange.getHeight()-1, 0, aeRange.getWidth()-1);
+ }
+ if (eval instanceof RefEval) {
+ return ((RefEval)eval).offset(0, aeRange.getHeight()-1, 0, aeRange.getWidth()-1);
+ }
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+
+ private static AreaEval convertRangeArg(ValueEval eval) throws EvaluationException {
+ if (eval instanceof AreaEval) {
+ return (AreaEval) eval;
+ }
+ if (eval instanceof RefEval) {
+ return ((RefEval)eval).offset(0, 0, 0, 0);
+ }
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumproduct.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumproduct.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumproduct.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumproduct.java Sat May 22 20:56:44 2021
@@ -46,190 +46,190 @@ import org.apache.poi.ss.formula.eval.Va
* of the <b>n</b>th array<br>
* Assuming each array has the same dimensions (W, H), the result is defined as:<br>
* SUMPRODUCT = Σ<sub><b>i</b>: 1..H</sub>
- * ( Σ<sub><b>j</b>: 1..W</sub>
- * ( Π<sub><b>n</b>: 1..N</sub>
- * A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub>
+ * ( Σ<sub><b>j</b>: 1..W</sub>
+ * ( Π<sub><b>n</b>: 1..N</sub>
+ * A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub>
* )
* )
*/
public final class Sumproduct implements Function {
- @Override
- public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
+ @Override
+ public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
- int maxN = args.length;
+ int maxN = args.length;
- if(maxN < 1) {
- return ErrorEval.VALUE_INVALID;
- }
- ValueEval firstArg = args[0];
- try {
- if(firstArg instanceof NumericValueEval) {
- return evaluateSingleProduct(args);
- }
- if(firstArg instanceof RefEval) {
- return evaluateSingleProduct(args);
- }
- if (firstArg instanceof TwoDEval) {
- TwoDEval ae = (TwoDEval) firstArg;
- if(ae.isRow() && ae.isColumn()) {
- return evaluateSingleProduct(args);
- }
- return evaluateAreaSumProduct(args);
- }
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- throw new RuntimeException("Invalid arg type for SUMPRODUCT: ("
- + firstArg.getClass().getName() + ")");
- }
-
- private static ValueEval evaluateSingleProduct(ValueEval[] evalArgs) throws EvaluationException {
- int maxN = evalArgs.length;
-
- double term = 1D;
- for (ValueEval evalArg : evalArgs) {
- double val = getScalarValue(evalArg);
- term *= val;
- }
- return new NumberEval(term);
- }
-
- private static double getScalarValue(ValueEval arg) throws EvaluationException {
-
- ValueEval eval;
- if (arg instanceof RefEval) {
- RefEval re = (RefEval) arg;
- if (re.getNumberOfSheets() > 1) {
+ if(maxN < 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ ValueEval firstArg = args[0];
+ try {
+ if(firstArg instanceof NumericValueEval) {
+ return evaluateSingleProduct(args);
+ }
+ if(firstArg instanceof RefEval) {
+ return evaluateSingleProduct(args);
+ }
+ if (firstArg instanceof TwoDEval) {
+ TwoDEval ae = (TwoDEval) firstArg;
+ if(ae.isRow() && ae.isColumn()) {
+ return evaluateSingleProduct(args);
+ }
+ return evaluateAreaSumProduct(args);
+ }
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ throw new RuntimeException("Invalid arg type for SUMPRODUCT: ("
+ + firstArg.getClass().getName() + ")");
+ }
+
+ private static ValueEval evaluateSingleProduct(ValueEval[] evalArgs) throws EvaluationException {
+ int maxN = evalArgs.length;
+
+ double term = 1D;
+ for (ValueEval evalArg : evalArgs) {
+ double val = getScalarValue(evalArg);
+ term *= val;
+ }
+ return new NumberEval(term);
+ }
+
+ private static double getScalarValue(ValueEval arg) throws EvaluationException {
+
+ ValueEval eval;
+ if (arg instanceof RefEval) {
+ RefEval re = (RefEval) arg;
+ if (re.getNumberOfSheets() > 1) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- eval = re.getInnerValueEval(re.getFirstSheetIndex());
- } else {
- eval = arg;
- }
-
- if (eval == null) {
- throw new RuntimeException("parameter may not be null");
- }
- if (eval instanceof AreaEval) {
- AreaEval ae = (AreaEval) eval;
- // an area ref can work as a scalar value if it is 1x1
- if(!ae.isColumn() || !ae.isRow()) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- eval = ae.getRelativeValue(0, 0);
- }
-
- return getProductTerm(eval, true);
- }
-
- private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException {
- int maxN = evalArgs.length;
- TwoDEval[] args;
- try {
- args = Arrays.copyOf(evalArgs, maxN, TwoDEval[].class);
- } catch (ArrayStoreException e) {
- // one of the other args was not an AreaRef
- return ErrorEval.VALUE_INVALID;
- }
-
-
- TwoDEval firstArg = args[0];
-
- int height = firstArg.getHeight();
- int width = firstArg.getWidth(); // TODO - junit
-
- // first check dimensions
- if (!areasAllSameSize(args, height, width)) {
- // normally this results in #VALUE!,
- // but errors in individual cells take precedence
- for (int i = 1; i < args.length; i++) {
- throwFirstError(args[i]);
- }
- return ErrorEval.VALUE_INVALID;
- }
-
- double acc = 0;
-
- for (int rrIx=0; rrIx<height; rrIx++) {
- for (int rcIx=0; rcIx<width; rcIx++) {
- double term = 1D;
- for(int n=0; n<maxN; n++) {
- double val = getProductTerm(args[n].getValue(rrIx, rcIx), false);
- term *= val;
- }
- acc += term;
- }
- }
-
- return new NumberEval(acc);
- }
-
- private static void throwFirstError(TwoDEval areaEval) throws EvaluationException {
- int height = areaEval.getHeight();
- int width = areaEval.getWidth();
- for (int rrIx=0; rrIx<height; rrIx++) {
- for (int rcIx=0; rcIx<width; rcIx++) {
- ValueEval ve = areaEval.getValue(rrIx, rcIx);
- if (ve instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) ve);
- }
- }
- }
- }
-
- private static boolean areasAllSameSize(TwoDEval[] args, int height, int width) {
- for (TwoDEval areaEval : args) {
- // check that height and width match
- if (areaEval.getHeight() != height) {
- return false;
- }
- if (areaEval.getWidth() != width) {
- return false;
- }
- }
- return true;
- }
-
-
- /**
- * Determines a {@code double} value for the specified {@code ValueEval}.
- * @param isScalarProduct {@code false} for SUMPRODUCTs over area refs.
- * @throws EvaluationException if {@code ve} represents an error value.
- * <p>
- * Note - string values and empty cells are interpreted differently depending on
- * {@code isScalarProduct}. For scalar products, if any term is blank or a string, the
- * error (#VALUE!) is raised. For area (sum)products, if any term is blank or a string, the
- * result is zero.
- */
- private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvaluationException {
-
- if(ve instanceof BlankEval || ve == null) {
- // TODO - shouldn't BlankEval.INSTANCE be used always instead of null?
- // null seems to occur when the blank cell is part of an area ref (but not reliably)
- if(isScalarProduct) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- return 0;
- }
-
- if(ve instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval)ve);
- }
- if(ve instanceof StringEval) {
- if(isScalarProduct) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- // Note for area SUMPRODUCTs, string values are interpreted as zero
- // even if they would parse as valid numeric values
- return 0;
- }
- if(ve instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) ve;
- return nve.getNumberValue();
- }
- throw new RuntimeException("Unexpected value eval class ("
- + ve.getClass().getName() + ")");
- }
+ }
+ eval = re.getInnerValueEval(re.getFirstSheetIndex());
+ } else {
+ eval = arg;
+ }
+
+ if (eval == null) {
+ throw new RuntimeException("parameter may not be null");
+ }
+ if (eval instanceof AreaEval) {
+ AreaEval ae = (AreaEval) eval;
+ // an area ref can work as a scalar value if it is 1x1
+ if(!ae.isColumn() || !ae.isRow()) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ eval = ae.getRelativeValue(0, 0);
+ }
+
+ return getProductTerm(eval, true);
+ }
+
+ private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException {
+ int maxN = evalArgs.length;
+ TwoDEval[] args;
+ try {
+ args = Arrays.copyOf(evalArgs, maxN, TwoDEval[].class);
+ } catch (ArrayStoreException e) {
+ // one of the other args was not an AreaRef
+ return ErrorEval.VALUE_INVALID;
+ }
+
+
+ TwoDEval firstArg = args[0];
+
+ int height = firstArg.getHeight();
+ int width = firstArg.getWidth(); // TODO - junit
+
+ // first check dimensions
+ if (!areasAllSameSize(args, height, width)) {
+ // normally this results in #VALUE!,
+ // but errors in individual cells take precedence
+ for (int i = 1; i < args.length; i++) {
+ throwFirstError(args[i]);
+ }
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ double acc = 0;
+
+ for (int rrIx=0; rrIx<height; rrIx++) {
+ for (int rcIx=0; rcIx<width; rcIx++) {
+ double term = 1D;
+ for(int n=0; n<maxN; n++) {
+ double val = getProductTerm(args[n].getValue(rrIx, rcIx), false);
+ term *= val;
+ }
+ acc += term;
+ }
+ }
+
+ return new NumberEval(acc);
+ }
+
+ private static void throwFirstError(TwoDEval areaEval) throws EvaluationException {
+ int height = areaEval.getHeight();
+ int width = areaEval.getWidth();
+ for (int rrIx=0; rrIx<height; rrIx++) {
+ for (int rcIx=0; rcIx<width; rcIx++) {
+ ValueEval ve = areaEval.getValue(rrIx, rcIx);
+ if (ve instanceof ErrorEval) {
+ throw new EvaluationException((ErrorEval) ve);
+ }
+ }
+ }
+ }
+
+ private static boolean areasAllSameSize(TwoDEval[] args, int height, int width) {
+ for (TwoDEval areaEval : args) {
+ // check that height and width match
+ if (areaEval.getHeight() != height) {
+ return false;
+ }
+ if (areaEval.getWidth() != width) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Determines a {@code double} value for the specified {@code ValueEval}.
+ * @param isScalarProduct {@code false} for SUMPRODUCTs over area refs.
+ * @throws EvaluationException if {@code ve} represents an error value.
+ * <p>
+ * Note - string values and empty cells are interpreted differently depending on
+ * {@code isScalarProduct}. For scalar products, if any term is blank or a string, the
+ * error (#VALUE!) is raised. For area (sum)products, if any term is blank or a string, the
+ * result is zero.
+ */
+ private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvaluationException {
+
+ if(ve instanceof BlankEval || ve == null) {
+ // TODO - shouldn't BlankEval.INSTANCE be used always instead of null?
+ // null seems to occur when the blank cell is part of an area ref (but not reliably)
+ if(isScalarProduct) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ return 0;
+ }
+
+ if(ve instanceof ErrorEval) {
+ throw new EvaluationException((ErrorEval)ve);
+ }
+ if(ve instanceof StringEval) {
+ if(isScalarProduct) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ // Note for area SUMPRODUCTs, string values are interpreted as zero
+ // even if they would parse as valid numeric values
+ return 0;
+ }
+ if(ve instanceof NumericValueEval) {
+ NumericValueEval nve = (NumericValueEval) ve;
+ return nve.getNumberValue();
+ }
+ throw new RuntimeException("Unexpected value eval class ("
+ + ve.getClass().getName() + ")");
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2my2.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2my2.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2my2.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2my2.java Sat May 22 20:56:44 2021
@@ -29,15 +29,15 @@ package org.apache.poi.ss.formula.functi
*/
public final class Sumx2my2 extends XYNumericFunction {
- private static final Accumulator XSquaredMinusYSquaredAccumulator = new Accumulator() {
- @Override
+ private static final Accumulator XSquaredMinusYSquaredAccumulator = new Accumulator() {
+ @Override
public double accumulate(double x, double y) {
- return x * x - y * y;
- }
- };
+ return x * x - y * y;
+ }
+ };
- @Override
- protected Accumulator createAccumulator() {
- return XSquaredMinusYSquaredAccumulator;
- }
+ @Override
+ protected Accumulator createAccumulator() {
+ return XSquaredMinusYSquaredAccumulator;
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2py2.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2py2.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2py2.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumx2py2.java Sat May 22 20:56:44 2021
@@ -29,15 +29,15 @@ package org.apache.poi.ss.formula.functi
*/
public final class Sumx2py2 extends XYNumericFunction {
- private static final Accumulator XSquaredPlusYSquaredAccumulator = new Accumulator() {
- @Override
+ private static final Accumulator XSquaredPlusYSquaredAccumulator = new Accumulator() {
+ @Override
public double accumulate(double x, double y) {
- return x * x + y * y;
- }
- };
+ return x * x + y * y;
+ }
+ };
- @Override
- protected Accumulator createAccumulator() {
- return XSquaredPlusYSquaredAccumulator;
- }
+ @Override
+ protected Accumulator createAccumulator() {
+ return XSquaredPlusYSquaredAccumulator;
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumxmy2.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumxmy2.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumxmy2.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Sumxmy2.java Sat May 22 20:56:44 2021
@@ -28,16 +28,16 @@ package org.apache.poi.ss.formula.functi
*/
public final class Sumxmy2 extends XYNumericFunction {
- private static final Accumulator XMinusYSquaredAccumulator = new Accumulator() {
- @Override
+ private static final Accumulator XMinusYSquaredAccumulator = new Accumulator() {
+ @Override
public double accumulate(double x, double y) {
- double xmy = x - y;
- return xmy * xmy;
- }
- };
+ double xmy = x - y;
+ return xmy * xmy;
+ }
+ };
- @Override
- protected Accumulator createAccumulator() {
- return XMinusYSquaredAccumulator;
- }
+ @Override
+ protected Accumulator createAccumulator() {
+ return XMinusYSquaredAccumulator;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org