Browse Source

Minor fixes to YEARFRAC(). Added ISEVEN() and ISODD(). Added test cases.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692614 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_2_FINAL
Josh Micich 16 years ago
parent
commit
ba665e8b75

+ 2
- 2
src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java View File

@@ -109,8 +109,8 @@ public final class AnalysisToolPak {
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);

+ 74
- 0
src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java View File

@@ -0,0 +1,74 @@
/* ====================================================================
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);
}
}

+ 6
- 1
src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java View File

@@ -21,6 +21,7 @@ import java.util.Calendar;
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;
@@ -96,6 +97,9 @@ final class YearFrac implements FreeRefFunction {
Calendar date = parseDate(strVal);
return HSSFDateUtil.getExcelDate(date, false);
}
if (ve instanceof BlankEval) {
return 0.0;
}
return OperandResolver.coerceValueToDouble(ve);
}

@@ -120,7 +124,7 @@ final class YearFrac implements FreeRefFunction {
} 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);
}
@@ -150,6 +154,7 @@ final class YearFrac implements FreeRefFunction {
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;
}


BIN
src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls View File


+ 12
- 3
src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java View File

@@ -74,9 +74,18 @@ public final class TestExternalFunctionFormulas extends TestCase {
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);
}
}

+ 1
- 0
src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculator.java View File

@@ -38,6 +38,7 @@ public final class TestYearFracCalculator extends TestCase {
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) {

Loading…
Cancel
Save