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
This commit is contained in:
parent
9dea9eba13
commit
74624c0cdd
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.6-beta1" date="2009-??-??">
|
<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">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="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>
|
<action dev="POI-DEVELOPERS" type="add">47922 - added example HSMF application that converts a .msg file to text and extracts attachments</action>
|
||||||
|
@ -203,6 +203,7 @@ public final class FunctionEval implements OperationEval {
|
|||||||
|
|
||||||
retval[345] = new Sumif();
|
retval[345] = new Sumif();
|
||||||
retval[346] = new Countif();
|
retval[346] = new Countif();
|
||||||
|
retval[347] = new Countblank();
|
||||||
|
|
||||||
retval[359] = new Hyperlink();
|
retval[359] = new Hyperlink();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -46,6 +46,34 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
|
|
||||||
private static final String NULL = null;
|
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() {
|
public void testCountA() {
|
||||||
|
|
||||||
ValueEval[] args;
|
ValueEval[] args;
|
||||||
@ -196,6 +224,12 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
double result = NumericFunctionInvoker.invoke(new Countif(), args);
|
double result = NumericFunctionInvoker.invoke(new Countif(), args);
|
||||||
assertEquals(expected, result, 0);
|
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) {
|
private static I_MatchPredicate createCriteriaPredicate(ValueEval ev) {
|
||||||
return Countif.createCriteriaPredicate(ev, 0, 0);
|
return Countif.createCriteriaPredicate(ev, 0, 0);
|
||||||
@ -388,10 +422,14 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testCountifFromSpreadsheet() {
|
public void testCountifFromSpreadsheet() {
|
||||||
final String FILE_NAME = "countifExamples.xls";
|
testCountFunctionFromSpreadsheet("countifExamples.xls", 1, 2, 3, "countif");
|
||||||
final int START_ROW_IX = 1;
|
}
|
||||||
final int COL_IX_ACTUAL = 2;
|
|
||||||
final int COL_IX_EXPECTED = 3;
|
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;
|
int failureCount = 0;
|
||||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(FILE_NAME);
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(FILE_NAME);
|
||||||
@ -415,7 +453,8 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (failureCount > 0) {
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
test-data/spreadsheet/countblankExamples.xls
Normal file
BIN
test-data/spreadsheet/countblankExamples.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user