]> source.dussan.org Git - poi.git/commitdiff
Minor fixes to YEARFRAC(). Added ISEVEN() and ISODD(). Added test cases.
authorJosh Micich <josh@apache.org>
Sat, 6 Sep 2008 06:04:01 +0000 (06:04 +0000)
committerJosh Micich <josh@apache.org>
Sat, 6 Sep 2008 06:04:01 +0000 (06:04 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692614 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java
src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls
src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java
src/testcases/org/apache/poi/hssf/record/formula/atp/TestYearFracCalculator.java

index 60f06695d0eab83ae3b2fe684a30f6ade63530b9..f46b4aea71c7bffa63be8b7010723ec1063350f2 100644 (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);
diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java b/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java
new file mode 100644 (file)
index 0000000..dd9ecc2
--- /dev/null
@@ -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);
+       }
+}
index 586187192077d4260f25c0e43252006b6676f989..ac196723e20bec767335931d13307204069a5e38 100644 (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;
        }
 
index 07eafb414416e98875b4c0a9cd2a78b453a5413a..fc81e60a18397f0a47b49bb77c3e32309d15662d 100755 (executable)
Binary files a/src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls and b/src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls differ
index 2b60e23c3becbe605feba0f2cdd908c02293cd50..b3a82c6de76321aa9584589dd68c5880b48b5abf 100755 (executable)
@@ -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);
        }
 }
index aaf03a238ee6f413b936395ddfd702a31f921016..890a5c2cbd55d8cfdf81550761fc30de86f83cc9 100644 (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) {