added fixed arg function interfaces, converted some functions

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@883045 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2009-11-22 07:29:40 +00:00
parent f56c779723
commit 6be8ae88fc
37 changed files with 521 additions and 267 deletions

View File

@ -17,12 +17,13 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
/** /**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/ */
public final class ConcatEval implements Function { public final class ConcatEval extends Fixed2ArgFunction {
public static final Function instance = new ConcatEval(); public static final Function instance = new ConcatEval();
@ -30,29 +31,30 @@ public final class ConcatEval implements Function {
// enforce singleton // enforce singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
if(args.length != 2) { ValueEval ve0;
return ErrorEval.VALUE_INVALID; ValueEval ve1;
}
StringBuffer sb = new StringBuffer();
try { try {
for (int i = 0; i < 2; i++) { ve0 = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
ValueEval ve = OperandResolver.getSingleValue(args[i], srcRow, srcCol);
if (ve instanceof StringValueEval) {
StringValueEval sve = (StringValueEval) ve;
sb.append(sve.getStringValue());
} else if (ve == BlankEval.INSTANCE) {
// do nothing
} else {
throw new RuntimeException("Unexpected value type ("
+ ve.getClass().getName() + ")");
}
}
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }
StringBuilder sb = new StringBuilder();
sb.append(getText(ve0));
sb.append(getText(ve1));
return new StringEval(sb.toString()); return new StringEval(sb.toString());
} }
private Object getText(ValueEval ve) {
if (ve instanceof StringValueEval) {
StringValueEval sve = (StringValueEval) ve;
return sve.getStringValue();
}
if (ve == BlankEval.INSTANCE) {
return "";
}
throw new IllegalAccessError("Unexpected value type ("
+ ve.getClass().getName() + ")");
}
} }

View File

@ -17,12 +17,13 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
/** /**
* @author Josh Micich * @author Josh Micich
*/ */
public final class IntersectionEval implements Function { public final class IntersectionEval extends Fixed2ArgFunction {
public static final Function instance = new IntersectionEval(); public static final Function instance = new IntersectionEval();
@ -30,14 +31,11 @@ public final class IntersectionEval implements Function {
// enforces singleton // enforces singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
if(args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
try { try {
AreaEval reA = evaluateRef(args[0]); AreaEval reA = evaluateRef(arg0);
AreaEval reB = evaluateRef(args[1]); AreaEval reB = evaluateRef(arg1);
AreaEval result = resolveRange(reA, reB); AreaEval result = resolveRange(reA, reB);
if (result == null) { if (result == null) {
return ErrorEval.NULL_INTERSECTION; return ErrorEval.NULL_INTERSECTION;

View File

@ -17,6 +17,7 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
@ -24,7 +25,7 @@ import org.apache.poi.hssf.record.formula.functions.Function;
* Implementation of Excel formula token '%'. <p/> * Implementation of Excel formula token '%'. <p/>
* @author Josh Micich * @author Josh Micich
*/ */
public final class PercentEval implements Function { public final class PercentEval extends Fixed1ArgFunction {
public static final Function instance = new PercentEval(); public static final Function instance = new PercentEval();
@ -32,13 +33,10 @@ public final class PercentEval implements Function {
// enforce singleton // enforce singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
double d; double d;
try { try {
ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol); ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
d = OperandResolver.coerceValueToDouble(ve); d = OperandResolver.coerceValueToDouble(ve);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();

View File

@ -17,6 +17,7 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
@ -24,7 +25,7 @@ import org.apache.poi.hssf.record.formula.functions.Function;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class RangeEval implements Function { public final class RangeEval extends Fixed2ArgFunction {
public static final Function instance = new RangeEval(); public static final Function instance = new RangeEval();
@ -32,14 +33,11 @@ public final class RangeEval implements Function {
// enforces singleton // enforces singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
if(args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
try { try {
AreaEval reA = evaluateRef(args[0]); AreaEval reA = evaluateRef(arg0);
AreaEval reB = evaluateRef(args[1]); AreaEval reB = evaluateRef(arg1);
return resolveRange(reA, reB); return resolveRange(reA, reB);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();

View File

@ -17,6 +17,7 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
import org.apache.poi.ss.util.NumberComparer; import org.apache.poi.ss.util.NumberComparer;
@ -25,7 +26,7 @@ import org.apache.poi.ss.util.NumberComparer;
* *
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*/ */
public abstract class RelationalOperationEval implements Function { public abstract class RelationalOperationEval extends Fixed2ArgFunction {
/** /**
* Converts a standard compare result (-1, 0, 1) to <code>true</code> or <code>false</code> * Converts a standard compare result (-1, 0, 1) to <code>true</code> or <code>false</code>
@ -55,16 +56,13 @@ public abstract class RelationalOperationEval implements Function {
* Blank < Positive numbers * Blank < Positive numbers
* </pre> * </pre>
*/ */
public final ValueEval evaluate(ValueEval[] operands, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
if (operands.length != 2) {
return ErrorEval.VALUE_INVALID;
}
ValueEval vA; ValueEval vA;
ValueEval vB; ValueEval vB;
try { try {
vA = OperandResolver.getSingleValue(operands[0], srcRow, srcCol); vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
vB = OperandResolver.getSingleValue(operands[1], srcRow, srcCol); vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }

View File

@ -17,23 +17,23 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
/** /**
* @author Josh Micich * @author Josh Micich
*/ */
public abstract class TwoOperandNumericOperation implements Function { public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction {
protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException { protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
return OperandResolver.coerceValueToDouble(ve); return OperandResolver.coerceValueToDouble(ve);
} }
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
double result; double result;
try { try {
double d0 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol); double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
double d1 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol); double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
result = evaluate(d0, d1); result = evaluate(d0, d1);
if (result == 0.0) { // this '==' matches +0.0 and -0.0 if (result == 0.0) { // this '==' matches +0.0 and -0.0
// Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^' // Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^'
@ -49,6 +49,7 @@ public abstract class TwoOperandNumericOperation implements Function {
} }
return new NumberEval(result); return new NumberEval(result);
} }
protected abstract double evaluate(double d0, double d1) throws EvaluationException; protected abstract double evaluate(double d0, double d1) throws EvaluationException;
public static final Function AddEval = new TwoOperandNumericOperation() { public static final Function AddEval = new TwoOperandNumericOperation() {

View File

@ -17,14 +17,13 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
/** /**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/ */
public final class UnaryMinusEval implements Function { public final class UnaryMinusEval extends Fixed1ArgFunction {
public static final Function instance = new UnaryMinusEval(); public static final Function instance = new UnaryMinusEval();
@ -32,13 +31,10 @@ public final class UnaryMinusEval implements Function {
// enforce singleton // enforce singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
double d; double d;
try { try {
ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol); ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
d = OperandResolver.coerceValueToDouble(ve); d = OperandResolver.coerceValueToDouble(ve);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();

View File

@ -17,14 +17,14 @@
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
import org.apache.poi.hssf.record.formula.functions.Function; import org.apache.poi.hssf.record.formula.functions.Function;
/** /**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/ */
public final class UnaryPlusEval implements Function { public final class UnaryPlusEval extends Fixed1ArgFunction {
public static final Function instance = new UnaryPlusEval(); public static final Function instance = new UnaryPlusEval();
@ -32,13 +32,10 @@ public final class UnaryPlusEval implements Function {
// enforce singleton // enforce singleton
} }
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) {
if(args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
double d; double d;
try { try {
ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol);
if(ve instanceof StringEval) { if(ve instanceof StringEval) {
// Note - asymmetric with UnaryMinus // Note - asymmetric with UnaryMinus
// -"hello" evaluates to #VALUE! // -"hello" evaluates to #VALUE!

View File

@ -34,7 +34,7 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
* *
* @author Guenter Kickinger g.kickinger@gmx.net * @author Guenter Kickinger g.kickinger@gmx.net
*/ */
public final class CalendarFieldFunction implements Function { public final class CalendarFieldFunction extends Fixed1ArgFunction {
public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR, false); public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR, false);
public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH, true); public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH, true);
@ -48,14 +48,10 @@ public final class CalendarFieldFunction implements Function {
_needsOneBaseAdjustment = needsOneBaseAdjustment; _needsOneBaseAdjustment = needsOneBaseAdjustment;
} }
public ValueEval evaluate(ValueEval[] operands, int srcCellRow, int srcCellCol) { public final ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
if (operands.length != 1) {
return ErrorEval.VALUE_INVALID;
}
int val; int val;
try { try {
ValueEval ve = OperandResolver.getSingleValue(operands[0], srcCellRow, srcCellCol); ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
val = OperandResolver.coerceValueToInt(ve); val = OperandResolver.coerceValueToInt(ve);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();

View File

@ -23,39 +23,32 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval; import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
public final class Column implements Function { public final class Column implements Function0Arg, Function1Arg {
public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
ValueEval retval = null;
int cnum = -1;
switch (evals.length) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
default: return new NumberEval(srcColumnIndex+1);
retval = ErrorEval.VALUE_INVALID;
case 1:
if (evals[0] instanceof AreaEval) {
AreaEval ae = (AreaEval) evals[0];
cnum = ae.getFirstColumn();
}
else if (evals[0] instanceof RefEval) {
RefEval re = (RefEval) evals[0];
cnum = re.getColumn();
}
else { // anything else is not valid argument
retval = ErrorEval.VALUE_INVALID;
}
break;
case 0:
cnum = srcCellCol;
}
if (retval == null) {
retval = (cnum >= 0)
? new NumberEval(cnum + 1) // +1 since excel colnums are 1 based
: (ValueEval) ErrorEval.VALUE_INVALID;
}
return retval;
} }
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
int rnum;
if (arg0 instanceof AreaEval) {
rnum = ((AreaEval) arg0).getFirstColumn();
} else if (arg0 instanceof RefEval) {
rnum = ((RefEval) arg0).getColumn();
} else {
// anything else is not valid argument
return ErrorEval.VALUE_INVALID;
}
return new NumberEval(rnum + 1);
}
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
switch (args.length) {
case 1:
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
case 0:
return new NumberEval(srcColumnIndex+1);
}
return ErrorEval.VALUE_INVALID;
}
} }

View File

@ -28,27 +28,14 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Columns implements Function { public final class Columns extends Fixed1ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
switch(args.length) {
case 1:
// expected
break;
case 0:
// too few arguments
return ErrorEval.VALUE_INVALID;
default:
// too many arguments
return ErrorEval.VALUE_INVALID;
}
ValueEval firstArg = args[0];
int result; int result;
if (firstArg instanceof AreaEval) { if (arg0 instanceof AreaEval) {
AreaEval ae = (AreaEval) firstArg; result = ((AreaEval) arg0).getWidth();
result = ae.getLastColumn() - ae.getFirstColumn() + 1; } else if (arg0 instanceof RefEval) {
} else if (firstArg instanceof RefEval) {
result = 1; result = 1;
} else { // anything else is not valid argument } else { // anything else is not valid argument
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;

View File

@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.AreaEval; import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval; import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval; import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
@ -36,17 +35,11 @@ import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
* *
* @author Mads Mohr Christensen * @author Mads Mohr Christensen
*/ */
public final class Countblank implements Function { public final class Countblank extends Fixed1ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
if (args.length != 1) {
// TODO - it doesn't seem to be possible to enter COUNTBLANK() into Excel with the wrong arg count
// perhaps this should be an exception
return ErrorEval.VALUE_INVALID;
}
double result; double result;
ValueEval arg0 = args[0];
if (arg0 instanceof RefEval) { if (arg0 instanceof RefEval) {
result = CountUtils.countMatchingCell((RefEval) arg0, predicate); result = CountUtils.countMatchingCell((RefEval) arg0, predicate);
} else if (arg0 instanceof AreaEval) { } else if (arg0 instanceof AreaEval) {

View File

@ -44,7 +44,7 @@ import org.apache.poi.ss.usermodel.ErrorConstants;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Countif implements Function { public final class Countif extends Fixed2ArgFunction {
private static final class CmpOp { private static final class CmpOp {
public static final int NONE = 0; public static final int NONE = 0;
@ -400,23 +400,14 @@ public final class Countif implements Function {
} }
} }
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
switch(args.length) {
case 2:
// expected
break;
default:
// TODO - it doesn't seem to be possible to enter COUNTIF() into Excel with the wrong arg count
// perhaps this should be an exception
return ErrorEval.VALUE_INVALID;
}
I_MatchPredicate mp = createCriteriaPredicate(args[1], srcRowIndex, srcColumnIndex); I_MatchPredicate mp = createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
if(mp == null) { if(mp == null) {
// If the criteria arg is a reference to a blank cell, countif always returns zero. // If the criteria arg is a reference to a blank cell, countif always returns zero.
return NumberEval.ZERO; return NumberEval.ZERO;
} }
double result = countMatchingCellsInArea(args[0], mp); double result = countMatchingCellsInArea(arg0, mp);
return new NumberEval(result); return new NumberEval(result);
} }
/** /**

View File

@ -22,23 +22,37 @@ import java.util.GregorianCalendar;
import org.apache.poi.hssf.record.formula.eval.ErrorEval; import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.EvaluationException; import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFDateUtil;
/** /**
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/ */
public final class DateFunc extends NumericFunction.MultiArg { public final class DateFunc extends Fixed3ArgFunction {
public static final Function instance = new DateFunc(); public static final Function instance = new DateFunc();
private DateFunc() { private DateFunc() {
super(3,3); // no fields to initialise
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
ValueEval arg2) {
double result;
try {
double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
double d2 = NumericFunction.singleOperandEvaluate(arg2, srcRowIndex, srcColumnIndex);
result = evaluate(getYear(d0), (int) (d1 - 1), (int) d2);
NumericFunction.checkValue(result);
} catch (EvaluationException e) {
return e.getErrorEval();
}
return new NumberEval(result);
} }
protected double evaluate(double[] ds) throws EvaluationException { private static double evaluate(int year, int month, int day) throws EvaluationException {
int year = getYear(ds[0]);
int month = (int) ds[1] - 1;
int day = (int) ds[2];
if (year < 0 || month < 0 || day < 0) { if (year < 0 || month < 0 || day < 0) {
throw new EvaluationException(ErrorEval.VALUE_INVALID); throw new EvaluationException(ErrorEval.VALUE_INVALID);

View File

@ -50,12 +50,12 @@ import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Errortype implements Function { public final class Errortype extends Fixed1ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
try { try {
OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
return ErrorEval.NA; return ErrorEval.NA;
} catch (EvaluationException e) { } catch (EvaluationException e) {
int result = translateErrorCodeToErrorTypeValue(e.getErrorEval().getErrorCode()); int result = translateErrorCodeToErrorTypeValue(e.getErrorEval().getErrorCode());

View File

@ -0,0 +1,35 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Convenience base class for functions that only take zero arguments.
*
* @author Josh Micich
*/
public abstract class Fixed0ArgFunction implements Function0Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length != 0) {
return ErrorEval.VALUE_INVALID;
}
return evaluate(srcRowIndex, srcColumnIndex);
}
}

View File

@ -0,0 +1,35 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Convenience base class for functions that must take exactly one argument.
*
* @author Josh Micich
*/
public abstract class Fixed1ArgFunction implements Function1Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
}
}

View File

@ -0,0 +1,35 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Convenience base class for functions that must take exactly two arguments.
*
* @author Josh Micich
*/
public abstract class Fixed2ArgFunction implements Function2Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
}
}

View File

@ -0,0 +1,35 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Convenience base class for functions that must take exactly three arguments.
*
* @author Josh Micich
*/
public abstract class Fixed3ArgFunction implements Function3Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length != 3) {
return ErrorEval.VALUE_INVALID;
}
return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]);
}
}

View File

@ -0,0 +1,35 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Convenience base class for functions that must take exactly four arguments.
*
* @author Josh Micich
*/
public abstract class Fixed4ArgFunction implements Function4Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length != 4) {
return ErrorEval.VALUE_INVALID;
}
return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]);
}
}

View File

@ -0,0 +1,32 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implemented by all functions that can be called with zero arguments
*
* @author Josh Micich
*/
public interface Function0Arg extends Function {
/**
* see {@link Function#evaluate(ValueEval[], int, int)}
*/
ValueEval evaluate(int srcRowIndex, int srcColumnIndex);
}

View File

@ -0,0 +1,32 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implemented by all functions that can be called with one argument
*
* @author Josh Micich
*/
public interface Function1Arg extends Function {
/**
* see {@link Function#evaluate(ValueEval[], int, int)}
*/
ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0);
}

View File

@ -0,0 +1,32 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implemented by all functions that can be called with two arguments
*
* @author Josh Micich
*/
public interface Function2Arg extends Function {
/**
* see {@link Function#evaluate(ValueEval[], int, int)}
*/
ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1);
}

View File

@ -0,0 +1,32 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implemented by all functions that can be called with three arguments
*
* @author Josh Micich
*/
public interface Function3Arg extends Function {
/**
* see {@link Function#evaluate(ValueEval[], int, int)}
*/
ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2);
}

View File

@ -0,0 +1,32 @@
/* ====================================================================
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.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implemented by all functions that can be called with four arguments
*
* @author Josh Micich
*/
public interface Function4Arg extends Function {
/**
* see {@link Function#evaluate(ValueEval[], int, int)}
*/
ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2, ValueEval arg3);
}

View File

@ -25,10 +25,9 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Na implements Function { public final class Na extends Fixed0ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcCellRow, int srcCellCol) {
return ErrorEval.NA; return ErrorEval.NA;
} }
} }

View File

@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
import java.util.Date; import java.util.Date;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFDateUtil;
@ -29,13 +28,9 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
* *
* @author Frank Taffelt * @author Frank Taffelt
*/ */
public final class Now implements Function { public final class Now extends Fixed0ArgFunction {
public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
if (evals.length > 0) {
return ErrorEval.VALUE_INVALID;
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
Date now = new Date(System.currentTimeMillis()); Date now = new Date(System.currentTimeMillis());
return new NumberEval(HSSFDateUtil.getExcelDate(now)); return new NumberEval(HSSFDateUtil.getExcelDate(now));
} }

View File

@ -39,7 +39,10 @@ public abstract class NumericFunction implements Function {
return result; return result;
} }
private static final void checkValue(double result) throws EvaluationException { /**
* @throws EvaluationException (#NUM!) if <tt>result</tt> is <tt>NaN</> or <tt>Infinity</tt>
*/
static final void checkValue(double result) throws EvaluationException {
if (Double.isNaN(result) || Double.isInfinite(result)) { if (Double.isNaN(result) || Double.isInfinite(result)) {
throw new EvaluationException(ErrorEval.NUM_ERROR); throw new EvaluationException(ErrorEval.NUM_ERROR);
} }

View File

@ -37,19 +37,24 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Manda Wilson &lt; wilson at c bio dot msk cc dot org &gt; * @author Manda Wilson &lt; wilson at c bio dot msk cc dot org &gt;
*/ */
public final class Replace extends TextFunction { public final class Replace extends Fixed4ArgFunction {
protected ValueEval evaluateFunc(ValueEval[] args, int srcCellRow, int srcCellCol) public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
throws EvaluationException { ValueEval arg2, ValueEval arg3) {
if (args.length != 4) {
return ErrorEval.VALUE_INVALID; 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 = evaluateStringArg(args[0], srcCellRow, srcCellCol);
int startNum = evaluateIntArg(args[1], srcCellRow, srcCellCol);
int numChars = evaluateIntArg(args[2], srcCellRow, srcCellCol);
String newStr = evaluateStringArg(args[3], srcCellRow, srcCellCol);
if (startNum < 1 || numChars < 0) { if (startNum < 1 || numChars < 0) {
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;
} }

View File

@ -23,39 +23,33 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval; import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
public final class Row implements Function { public final class Row implements Function0Arg, Function1Arg {
public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
ValueEval retval = null; return new NumberEval(srcRowIndex+1);
int rnum = -1; }
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
int rnum;
switch (evals.length) { if (arg0 instanceof AreaEval) {
default: rnum = ((AreaEval) arg0).getFirstRow();
retval = ErrorEval.VALUE_INVALID; } else if (arg0 instanceof RefEval) {
case 1: rnum = ((RefEval) arg0).getRow();
if (evals[0] instanceof AreaEval) { } else {
AreaEval ae = (AreaEval) evals[0]; // anything else is not valid argument
rnum = ae.getFirstRow(); return ErrorEval.VALUE_INVALID;
}
else if (evals[0] instanceof RefEval) {
RefEval re = (RefEval) evals[0];
rnum = re.getRow();
}
else { // anything else is not valid argument
retval = ErrorEval.VALUE_INVALID;
}
break;
case 0:
rnum = srcCellRow;
} }
if (retval == null) { return new NumberEval(rnum + 1);
retval = (rnum >= 0) }
? new NumberEval(rnum + 1) // +1 since excel rownums are 1 based public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
: (ValueEval) ErrorEval.VALUE_INVALID; switch (args.length) {
case 1:
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
case 0:
return new NumberEval(srcRowIndex+1);
} }
return ErrorEval.VALUE_INVALID;
return retval;
} }
} }

View File

@ -28,27 +28,14 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Rows implements Function { public final class Rows extends Fixed1ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
switch(args.length) {
case 1:
// expected
break;
case 0:
// too few arguments
return ErrorEval.VALUE_INVALID;
default:
// too many arguments
return ErrorEval.VALUE_INVALID;
}
ValueEval firstArg = args[0];
int result; int result;
if (firstArg instanceof AreaEval) { if (arg0 instanceof AreaEval) {
AreaEval ae = (AreaEval) firstArg; result = ((AreaEval) arg0).getHeight();
result = ae.getLastRow() - ae.getFirstRow() + 1; } else if (arg0 instanceof RefEval) {
} else if (firstArg instanceof RefEval) {
result = 1; result = 1;
} else { // anything else is not valid argument } else { // anything else is not valid argument
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;

View File

@ -30,16 +30,10 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* cause an empty string result. If the argument is an area, the first (top-left) cell is used * cause an empty string result. If the argument is an area, the first (top-left) cell is used
* (regardless of the coordinates of the evaluating formula cell). * (regardless of the coordinates of the evaluating formula cell).
*/ */
public final class T implements Function { public final class T extends Fixed1ArgFunction {
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
switch (args.length) { ValueEval arg = arg0;
default:
return ErrorEval.VALUE_INVALID;
case 1:
break;
}
ValueEval arg = args[0];
if (arg instanceof RefEval) { if (arg instanceof RefEval) {
arg = ((RefEval) arg).getInnerValueEval(); arg = ((RefEval) arg).getInnerValueEval();
} else if (arg instanceof AreaEval) { } else if (arg instanceof AreaEval) {

View File

@ -29,7 +29,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* Based on POI org.apache.hssf.record.formula.DateFunc.java * Based on POI org.apache.hssf.record.formula.DateFunc.java
*/ */
public final class Time implements Function { public final class Time extends Fixed3ArgFunction {
private static final int SECONDS_PER_MINUTE = 60; private static final int SECONDS_PER_MINUTE = 60;
private static final int SECONDS_PER_HOUR = 3600; private static final int SECONDS_PER_HOUR = 3600;
@ -37,25 +37,23 @@ public final class Time implements Function {
private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR; private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR;
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
if (args.length != 3) { ValueEval arg2) {
return ErrorEval.VALUE_INVALID;
}
double result; double result;
try { try {
result = evaluate(evalArg(args[0]), evalArg(args[1]), evalArg(args[2])); result = evaluate(evalArg(arg0, srcRowIndex, srcColumnIndex), evalArg(arg1, srcRowIndex, srcColumnIndex), evalArg(arg2, srcRowIndex, srcColumnIndex));
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }
return new NumberEval(result); return new NumberEval(result);
} }
private static int evalArg(ValueEval arg) throws EvaluationException { private static int evalArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
if (arg == MissingArgEval.instance) { if (arg == MissingArgEval.instance) {
return 0; return 0;
} }
ValueEval ev = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
// Excel silently truncates double values to integers // Excel silently truncates double values to integers
return OperandResolver.coerceValueToInt(arg); return OperandResolver.coerceValueToInt(ev);
} }
/** /**
* Converts the supplied hours, minutes and seconds to an Excel time value. * Converts the supplied hours, minutes and seconds to an Excel time value.

View File

@ -20,7 +20,6 @@ package org.apache.poi.hssf.record.formula.functions;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFDateUtil;
@ -30,12 +29,9 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
* *
* @author Frank Taffelt * @author Frank Taffelt
*/ */
public final class Today implements Function { public final class Today extends Fixed0ArgFunction {
public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
if (evals.length > 0) {
return ErrorEval.VALUE_INVALID;
}
Calendar now = new GregorianCalendar(); Calendar now = new GregorianCalendar();
now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0); now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0);
@ -43,4 +39,3 @@ public final class Today implements Function {
return new NumberEval(HSSFDateUtil.getExcelDate(now.getTime())); return new NumberEval(HSSFDateUtil.getExcelDate(now.getTime()));
} }
} }

View File

@ -35,19 +35,16 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class Value implements Function { public final class Value extends Fixed1ArgFunction {
/** "1,0000" is valid, "1,00" is not */ /** "1,0000" is valid, "1,00" is not */
private static final int MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR = 4; private static final int MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR = 4;
private static final Double ZERO = new Double(0.0); private static final Double ZERO = new Double(0.0);
public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
ValueEval veText; ValueEval veText;
try { try {
veText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); veText = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }

View File

@ -26,7 +26,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* *
* @author Josh Micich * @author Josh Micich
*/ */
abstract class Var2or3ArgFunction implements Function { abstract class Var2or3ArgFunction implements Function2Arg, Function3Arg {
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
switch (args.length) { switch (args.length) {
@ -37,10 +37,4 @@ abstract class Var2or3ArgFunction implements Function {
} }
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;
} }
public abstract ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
ValueEval arg1, ValueEval arg2);
public abstract ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
ValueEval arg1);
} }

View File

@ -27,9 +27,8 @@ import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
/** /**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/ */
public abstract class XYNumericFunction implements Function { public abstract class XYNumericFunction extends Fixed2ArgFunction {
private static abstract class ValueArray implements ValueVector { private static abstract class ValueArray implements ValueVector {
private final int _size; private final int _size;
@ -96,15 +95,12 @@ public abstract class XYNumericFunction implements Function {
*/ */
protected abstract Accumulator createAccumulator(); protected abstract Accumulator createAccumulator();
public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
if (args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
double result; double result;
try { try {
ValueVector vvX = createValueVector(args[0]); ValueVector vvX = createValueVector(arg0);
ValueVector vvY = createValueVector(args[1]); ValueVector vvY = createValueVector(arg1);
int size = vvX.getSize(); int size = vvX.getSize();
if (size == 0 || vvY.getSize() != size) { if (size == 0 || vvY.getSize() != size) {
return ErrorEval.NA; return ErrorEval.NA;