r(m, "IMSUB", null);
r(m, "IMSUM", null);
r(m, "INTRATE", null);
- r(m, "ISEVEN", null);
- r(m, "ISODD", null);
+ r(m, "ISEVEN", ParityFunction.IS_EVEN);
+ r(m, "ISODD", ParityFunction.IS_ODD);
r(m, "LCM", null);
r(m, "MDURATION", null);
r(m, "MROUND", null);
--- /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.atp;
+
+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.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+/**
+ * Implementation of Excel 'Analysis ToolPak' function ISEVEN() ISODD()<br/>
+ *
+ * @author Josh Micich
+ */
+final class ParityFunction implements FreeRefFunction {
+
+ public static final FreeRefFunction IS_EVEN = new ParityFunction(0);
+ public static final FreeRefFunction IS_ODD = new ParityFunction(1);
+ private final int _desiredParity;
+
+ private ParityFunction(int desiredParity) {
+ _desiredParity = desiredParity;
+ }
+
+ public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook,
+ HSSFSheet sheet) {
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ int val;
+ try {
+ val = evaluateArgParity(args[0], srcCellRow, srcCellCol);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+
+ return BoolEval.valueOf(val == _desiredParity);
+ }
+
+ private static int evaluateArgParity(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+
+ if (ve == BlankEval.INSTANCE) {
+ return 0;
+ }
+ double d = OperandResolver.coerceValueToDouble(ve);
+ if (d < 0) {
+ d = -d;
+ }
+ long v = (long) Math.floor(d);
+ return (int) (v & 0x0001);
+ }
+}
import java.util.GregorianCalendar;
import java.util.regex.Pattern;
+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.Eval;
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
Calendar date = parseDate(strVal);
return HSSFDateUtil.getExcelDate(date, false);
}
+ if (ve instanceof BlankEval) {
+ return 0.0;
+ }
return OperandResolver.coerceValueToDouble(ve);
}
} catch (NumberFormatException e) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
- if (f0<0 || f1<0 || f2<0 || f0>12 || f1>12 || f2>12) {
+ if (f0<0 || f1<0 || f2<0 || (f0>12 && f1>12 && f2>12)) {
// easy to see this cannot be a valid date
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
if (day <1 || day>cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
+ cal.set(Calendar.DAY_OF_MONTH, day);
return cal;
}
public void testEvaluate() {
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFCell cell = sheet.getRow(0).getCell(0);
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
- CellValue evalResult = fe.evaluate(cell);
- evalResult.toString();
+ confirmCellEval(sheet, 0, 0, fe, "YEARFRAC(B1,C1)", 29.0/90.0);
+ confirmCellEval(sheet, 1, 0, fe, "YEARFRAC(B2,C2)", 0.0);
+ confirmCellEval(sheet, 2, 0, fe, "IF(ISEVEN(3),1.2,1.6)", 1.6);
+ confirmCellEval(sheet, 3, 0, fe, "IF(ISODD(3),1.2,1.6)", 1.2);
+ }
+
+ private static void confirmCellEval(HSSFSheet sheet, int rowIx, int colIx,
+ HSSFFormulaEvaluator fe, String expectedFormula, double expectedResult) {
+ HSSFCell cell = sheet.getRow(rowIx).getCell(colIx);
+ assertEquals(expectedFormula, cell.getCellFormula());
+ CellValue cv = fe.evaluate(cell);
+ assertEquals(expectedResult, cv.getNumberValue(), 0.0);
}
}
confirm(md(1999, 3, 31), md(1999, 4, 3), 1, 0.008219178);
confirm(md(1999, 4, 5), md(1999, 4, 8), 1, 0.008219178);
confirm(md(1999, 4, 4), md(1999, 4, 7), 1, 0.008219178);
+ confirm(md(2000, 2, 5), md(2000, 6, 1), 0, 0.322222222);
}
private void confirm(double startDate, double endDate, int basis, double expectedValue) {