diff options
author | Josh Micich <josh@apache.org> | 2009-10-24 00:41:30 +0000 |
---|---|---|
committer | Josh Micich <josh@apache.org> | 2009-10-24 00:41:30 +0000 |
commit | 46441487c7c454a68888c00053d6e3a86b75dfb1 (patch) | |
tree | 8fd137b3a8e97a6e229ea7c2ad4d187fea829bb9 | |
parent | db9e3cd754886e661273662282a9bafbdde1d91e (diff) | |
download | poi-46441487c7c454a68888c00053d6e3a86b75dfb1.tar.gz poi-46441487c7c454a68888c00053d6e3a86b75dfb1.zip |
Bugzilla 48044 - added implementation for CountBlank function (patch from Mads Mohr Christensen)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@829293 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | src/documentation/content/xdocs/status.xml | 1 | ||||
-rw-r--r-- | src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java | 1 | ||||
-rw-r--r-- | src/java/org/apache/poi/hssf/record/formula/functions/Countblank.java | 67 | ||||
-rw-r--r-- | src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java | 49 | ||||
-rw-r--r-- | test-data/spreadsheet/countblankExamples.xls | bin | 0 -> 6656 bytes |
5 files changed, 113 insertions, 5 deletions
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 6dac6eac44..99d07c91f4 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ <changes> <release version="3.6-beta1" date="2009-??-??"> + <action dev="POI-DEVELOPERS" type="add">48044 - added implementation for CountBlank function</action> <action dev="POI-DEVELOPERS" type="fix">48036 - added IntersectionEval to allow evaluation of the intersection formula operator</action> <action dev="POI-DEVELOPERS" type="fix">47999 - avoid un-needed call to the JVM Garbage Collector when working on OOXML OPC Packages</action> <action dev="POI-DEVELOPERS" type="add">47922 - added example HSMF application that converts a .msg file to text and extracts attachments</action> diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java index 583cf88b8e..dc5d6c5fe5 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java @@ -203,6 +203,7 @@ public final class FunctionEval implements OperationEval { retval[345] = new Sumif(); retval[346] = new Countif(); + retval[347] = new Countblank(); retval[359] = new Hyperlink(); diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Countblank.java b/src/java/org/apache/poi/hssf/record/formula/functions/Countblank.java new file mode 100644 index 0000000000..f7d7538a99 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Countblank.java @@ -0,0 +1,67 @@ +/* ==================================================================== + 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.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.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate; + +/** + * Implementation for the function COUNTBLANK + * <p> + * Syntax: COUNTBLANK ( range ) + * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions"> + * <tr><th>range </th><td>is the range of cells to count blanks</td></tr> + * </table> + * </p> + * + * @author Mads Mohr Christensen + */ +public final class Countblank implements Function { + + public ValueEval evaluate(ValueEval[] args, int srcRowIndex, short srcColumnIndex) { + 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; + ValueEval arg0 = args[0]; + if (arg0 instanceof RefEval) { + result = CountUtils.countMatchingCell((RefEval) arg0, predicate); + } else if (arg0 instanceof AreaEval) { + result = CountUtils.countMatchingCellsInArea((AreaEval) arg0, predicate); + } else { + throw new IllegalArgumentException("Bad range arg type (" + arg0.getClass().getName() + ")"); + } + return new NumberEval(result); + } + + private static final I_MatchPredicate predicate = new I_MatchPredicate() { + + public boolean matches(ValueEval valueEval) { + // Note - only BlankEval counts + return valueEval == BlankEval.INSTANCE; + } + }; +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java index e07f2c2454..e3ee50e0a4 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java @@ -46,6 +46,34 @@ public final class TestCountFuncs extends TestCase { private static final String NULL = null; + public void testCountBlank() { + + AreaEval range; + ValueEval[] values; + + values = new ValueEval[] { + new NumberEval(0), + new StringEval(""), // note - does not match blank + BoolEval.TRUE, + BoolEval.FALSE, + ErrorEval.DIV_ZERO, + BlankEval.INSTANCE, + }; + range = EvalFactory.createAreaEval("A1:B3", values); + confirmCountBlank(1, range); + + values = new ValueEval[] { + new NumberEval(0), + new StringEval(""), // note - does not match blank + BlankEval.INSTANCE, + BoolEval.FALSE, + BoolEval.TRUE, + BlankEval.INSTANCE, + }; + range = EvalFactory.createAreaEval("A1:B3", values); + confirmCountBlank(2, range); + } + public void testCountA() { ValueEval[] args; @@ -196,6 +224,12 @@ public final class TestCountFuncs extends TestCase { double result = NumericFunctionInvoker.invoke(new Countif(), args); assertEquals(expected, result, 0); } + private static void confirmCountBlank(int expected, AreaEval range) { + + ValueEval[] args = { range }; + double result = NumericFunctionInvoker.invoke(new Countblank(), args); + assertEquals(expected, result, 0); + } private static I_MatchPredicate createCriteriaPredicate(ValueEval ev) { return Countif.createCriteriaPredicate(ev, 0, 0); @@ -388,10 +422,14 @@ public final class TestCountFuncs extends TestCase { } public void testCountifFromSpreadsheet() { - final String FILE_NAME = "countifExamples.xls"; - final int START_ROW_IX = 1; - final int COL_IX_ACTUAL = 2; - final int COL_IX_EXPECTED = 3; + testCountFunctionFromSpreadsheet("countifExamples.xls", 1, 2, 3, "countif"); + } + + public void testCountBlankFromSpreadsheet() { + testCountFunctionFromSpreadsheet("countblankExamples.xls", 1, 3, 4, "countblank"); + } + + private static void testCountFunctionFromSpreadsheet(String FILE_NAME, int START_ROW_IX, int COL_IX_ACTUAL, int COL_IX_EXPECTED, String functionName) { int failureCount = 0; HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(FILE_NAME); @@ -415,7 +453,8 @@ public final class TestCountFuncs extends TestCase { } if (failureCount > 0) { - throw new AssertionFailedError(failureCount + " countif evaluations failed. See stderr for more details"); + throw new AssertionFailedError(failureCount + " " + functionName + + " evaluations failed. See stderr for more details"); } } } diff --git a/test-data/spreadsheet/countblankExamples.xls b/test-data/spreadsheet/countblankExamples.xls Binary files differnew file mode 100644 index 0000000000..19b4e17b4b --- /dev/null +++ b/test-data/spreadsheet/countblankExamples.xls |