Function[] retval = new Function[368];
retval[0] = new Count();
- retval[ID.IF] = new If();
+ retval[ID.IF] = new IfFunc();
retval[2] = LogicalFunction.ISNA;
retval[3] = LogicalFunction.ISERROR;
retval[ID.SUM] = AggregateFunction.SUM;
retval[5] = AggregateFunction.AVERAGE;
retval[6] = AggregateFunction.MIN;
retval[7] = AggregateFunction.MAX;
- retval[8] = new Row(); // ROW
+ retval[8] = new RowFunc(); // ROW
retval[9] = new Column();
retval[10] = new Na();
retval[11] = new Npv();
retval[63] = NumericFunction.RAND;
retval[64] = new Match();
retval[65] = DateFunc.instance;
- retval[66] = new Time();
+ retval[66] = new TimeFunc();
retval[67] = CalendarFieldFunction.DAY;
retval[68] = CalendarFieldFunction.MONTH;
retval[69] = CalendarFieldFunction.YEAR;
/**
+ * Implementation for the Excel function DATE
+ *
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/
public final class DateFunc extends Fixed3ArgFunction {
return new NumberEval(result);
}
- private static double evaluate(int year, int month, int day) throws EvaluationException {
+ private static double evaluate(int year, int month, int pDay) throws EvaluationException {
- if (year < 0 || month < 0 || day < 0) {
+ if (year < 0 || month < 0 || pDay < 0) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
- if (year == 1900 && month == Calendar.FEBRUARY && day == 29) {
+ if (year == 1900 && month == Calendar.FEBRUARY && pDay == 29) {
return 60.0;
}
+ int day = pDay;
if (year == 1900) {
if ((month == Calendar.JANUARY && day >= 60) ||
(month == Calendar.FEBRUARY && day >= 30)) {
+++ /dev/null
-/* ====================================================================
- 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.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
-import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class If extends Var2or3ArgFunction {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
- boolean b;
- try {
- b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (b) {
- if (arg1 == MissingArgEval.instance) {
- return BlankEval.instance;
- }
- return arg1;
- }
- return BoolEval.FALSE;
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2) {
- boolean b;
- try {
- b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (b) {
- if (arg1 == MissingArgEval.instance) {
- return BlankEval.instance;
- }
- return arg1;
- }
- if (arg2 == MissingArgEval.instance) {
- return BlankEval.instance;
- }
- return arg2;
- }
-
- public static boolean evaluateFirstArg(ValueEval arg, int srcCellRow, int srcCellCol)
- throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
- Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
- if (b == null) {
- return false;
- }
- return b.booleanValue();
- }
-}
--- /dev/null
+/* ====================================================================
+ 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.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implementation for the Excel function IF
+ *
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ */
+public final class IfFunc extends Var2or3ArgFunction {
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
+ boolean b;
+ try {
+ b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (b) {
+ if (arg1 == MissingArgEval.instance) {
+ return BlankEval.instance;
+ }
+ return arg1;
+ }
+ return BoolEval.FALSE;
+ }
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2) {
+ boolean b;
+ try {
+ b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (b) {
+ if (arg1 == MissingArgEval.instance) {
+ return BlankEval.instance;
+ }
+ return arg1;
+ }
+ if (arg2 == MissingArgEval.instance) {
+ return BlankEval.instance;
+ }
+ return arg2;
+ }
+
+ public static boolean evaluateFirstArg(ValueEval arg, int srcCellRow, int srcCellCol)
+ throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
+ if (b == null) {
+ return false;
+ }
+ return b.booleanValue();
+ }
+}
+++ /dev/null
-/* ====================================================================
- 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.AreaEval;
-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.RefEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-public final class Row implements Function0Arg, Function1Arg {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
- return new NumberEval(srcRowIndex+1);
- }
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- int rnum;
-
- if (arg0 instanceof AreaEval) {
- rnum = ((AreaEval) arg0).getFirstRow();
- } else if (arg0 instanceof RefEval) {
- rnum = ((RefEval) arg0).getRow();
- } 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(srcRowIndex+1);
- }
- return ErrorEval.VALUE_INVALID;
- }
-
-}
--- /dev/null
+/* ====================================================================
+ 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.AreaEval;
+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.RefEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implementation for the Excel function ROW
+ *
+ * @author Josh Micich
+ */
+public final class RowFunc implements Function0Arg, Function1Arg {
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
+ return new NumberEval(srcRowIndex+1);
+ }
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+ int rnum;
+
+ if (arg0 instanceof AreaEval) {
+ rnum = ((AreaEval) arg0).getFirstRow();
+ } else if (arg0 instanceof RefEval) {
+ rnum = ((RefEval) arg0).getRow();
+ } 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(srcRowIndex+1);
+ }
+ return ErrorEval.VALUE_INVALID;
+ }
+}
+++ /dev/null
-/* ====================================================================
- 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.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Steven Butler (sebutler @ gmail dot com)
- *
- * Based on POI org.apache.hssf.record.formula.DateFunc.java
- */
-public final class Time extends Fixed3ArgFunction {
-
- private static final int SECONDS_PER_MINUTE = 60;
- private static final int SECONDS_PER_HOUR = 3600;
- private static final int HOURS_PER_DAY = 24;
- private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR;
-
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2) {
- double result;
- try {
- result = evaluate(evalArg(arg0, srcRowIndex, srcColumnIndex), evalArg(arg1, srcRowIndex, srcColumnIndex), evalArg(arg2, srcRowIndex, srcColumnIndex));
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(result);
- }
- private static int evalArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
- if (arg == MissingArgEval.instance) {
- return 0;
- }
- ValueEval ev = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
- // Excel silently truncates double values to integers
- return OperandResolver.coerceValueToInt(ev);
- }
- /**
- * Converts the supplied hours, minutes and seconds to an Excel time value.
- *
- *
- * @param ds array of 3 doubles containing hours, minutes and seconds.
- * Non-integer inputs are truncated to an integer before further calculation
- * of the time value.
- * @return An Excel representation of a time of day.
- * If the time value represents more than a day, the days are removed from
- * the result, leaving only the time of day component.
- * @throws org.apache.poi.hssf.record.formula.eval.EvaluationException
- * If any of the arguments are greater than 32767 or the hours
- * minutes and seconds when combined form a time value less than 0, the function
- * evaluates to an error.
- */
- private static double evaluate(int hours, int minutes, int seconds) throws EvaluationException {
-
- if (hours > 32767 || minutes > 32767 || seconds > 32767) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- int totalSeconds = hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
-
- if (totalSeconds < 0) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- return (totalSeconds % SECONDS_PER_DAY) / (double)SECONDS_PER_DAY;
- }
-}
--- /dev/null
+/* ====================================================================
+ 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.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implementation for the Excel function TIME
+ *
+ * @author Steven Butler (sebutler @ gmail dot com)
+ *
+ * Based on POI {@link DateFunc}
+ */
+public final class TimeFunc extends Fixed3ArgFunction {
+
+ private static final int SECONDS_PER_MINUTE = 60;
+ private static final int SECONDS_PER_HOUR = 3600;
+ private static final int HOURS_PER_DAY = 24;
+ private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR;
+
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+ ValueEval arg2) {
+ double result;
+ try {
+ result = evaluate(evalArg(arg0, srcRowIndex, srcColumnIndex), evalArg(arg1, srcRowIndex, srcColumnIndex), evalArg(arg2, srcRowIndex, srcColumnIndex));
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(result);
+ }
+ private static int evalArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
+ if (arg == MissingArgEval.instance) {
+ return 0;
+ }
+ ValueEval ev = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
+ // Excel silently truncates double values to integers
+ return OperandResolver.coerceValueToInt(ev);
+ }
+ /**
+ * Converts the supplied hours, minutes and seconds to an Excel time value.
+ *
+ *
+ * @param ds array of 3 doubles containing hours, minutes and seconds.
+ * Non-integer inputs are truncated to an integer before further calculation
+ * of the time value.
+ * @return An Excel representation of a time of day.
+ * If the time value represents more than a day, the days are removed from
+ * the result, leaving only the time of day component.
+ * @throws org.apache.poi.hssf.record.formula.eval.EvaluationException
+ * If any of the arguments are greater than 32767 or the hours
+ * minutes and seconds when combined form a time value less than 0, the function
+ * evaluates to an error.
+ */
+ private static double evaluate(int hours, int minutes, int seconds) throws EvaluationException {
+
+ if (hours > 32767 || minutes > 32767 || seconds > 32767) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ int totalSeconds = hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
+
+ if (totalSeconds < 0) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ return (totalSeconds % SECONDS_PER_DAY) / (double)SECONDS_PER_DAY;
+ }
+}
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.Choose;
import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.hssf.record.formula.functions.If;
+import org.apache.poi.hssf.record.formula.functions.IfFunc;
import org.apache.poi.hssf.record.formula.udf.UDFFinder;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
ValueEval arg0 = stack.pop();
boolean evaluatedPredicate;
try {
- evaluatedPredicate = If.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
+ evaluatedPredicate = IfFunc.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
} catch (EvaluationException e) {
stack.push(e.getErrorEval());
int dist = attrPtg.getData();
}
public void testRow() {
- Function target = new Row();
+ Function target = new RowFunc();
{
ValueEval[] args = { EvalFactory.createRefEval("C5"), };
double actual = NumericFunctionInvoker.invoke(target, args);
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
- * Tests for {@link Time}
- *
+ * Tests for {@link TimeFunc}
+ *
* @author @author Steven Butler (sebutler @ gmail dot com)
*/
public final class TestTime extends TestCase {
int expH = Integer.parseInt(parts[0]);
int expM = Integer.parseInt(parts[1]);
int expS = Integer.parseInt(parts[2]);
-
+
double expectedValue = (expH*SECONDS_PER_HOUR + expM*SECONDS_PER_MINUTE + expS)/SECONDS_PER_DAY;
cell11.setCellFormula(formulaText);
cell11.setCellStyle(style);
evaluator.clearAllCachedResultValues();
-
+
double actualValue = evaluator.evaluate(cell11).getNumberValue();
assertEquals(expectedValue, actualValue, 0.0);