diff --git a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java index b327f2504..a3505d448 100644 --- a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java @@ -106,10 +106,10 @@ public final class FunctionEval { retval[38] = BooleanFunction.NOT; retval[39] = NumericFunction.MOD; // 40: DCOUNT - // 41: DSUM + retval[41] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DSUM); // 42: DAVERAGE retval[43] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMIN); - // 44: DMAX + retval[44] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMAX); // 45: DSTDEV retval[46] = AggregateFunction.VAR; // 47: DVAR @@ -144,7 +144,6 @@ public final class FunctionEval { retval[FunctionID.OFFSET] = new Offset(); //nominally 78 retval[82] = TextFunction.SEARCH; - // 83: TRANSPOSE retval[83] = MatrixFunction.TRANSPOSE; // 86: TYPE diff --git a/src/java/org/apache/poi/ss/formula/functions/DMax.java b/src/java/org/apache/poi/ss/formula/functions/DMax.java new file mode 100644 index 000000000..4d442f041 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/functions/DMax.java @@ -0,0 +1,60 @@ +/* ==================================================================== + 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.ss.formula.functions; + +import org.apache.poi.ss.formula.eval.NumberEval; +import org.apache.poi.ss.formula.eval.NumericValueEval; +import org.apache.poi.ss.formula.eval.ValueEval; + +/** + * Implementation of the DMax function: + * Finds the maximum value of a column in an area with given conditions. + * + * TODO: + * - wildcards ? and * in string conditions + * - functions as conditions + */ +public final class DMax implements IDStarAlgorithm { + private ValueEval maximumValue; + + @Override + public boolean processMatch(ValueEval eval) { + if(eval instanceof NumericValueEval) { + if(maximumValue == null) { // First match, just set the value. + maximumValue = eval; + } else { // There was a previous match, find the new minimum. + double currentValue = ((NumericValueEval)eval).getNumberValue(); + double oldValue = ((NumericValueEval)maximumValue).getNumberValue(); + if(currentValue > oldValue) { + maximumValue = eval; + } + } + } + + return true; + } + + @Override + public ValueEval getResult() { + if(maximumValue == null) { + return NumberEval.ZERO; + } else { + return maximumValue; + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java index 6a43a6204..a1f92e781 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java @@ -17,6 +17,8 @@ package org.apache.poi.ss.formula.functions; +import java.util.function.Supplier; + import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.ErrorEval; @@ -39,13 +41,38 @@ import org.apache.poi.ss.util.NumberComparer; * - functions as conditions */ public final class DStarRunner implements Function3Arg { + /** + * Enum for convenience to identify and source implementations of the D* functions + */ public enum DStarAlgorithmEnum { - DGET, - DMIN, - // DMAX, // DMAX is not yet implemented + /** @see DGet */ + DGET(DGet::new), + /** @see DMin */ + DMIN(DMin::new), + /** @see DMax */ + DMAX(DMax::new), + /** @see DSum */ + DSUM(DSum::new), + ; + + private final Supplier implSupplier; + + private DStarAlgorithmEnum(Supplier implSupplier) { + this.implSupplier = implSupplier; + } + + /** + * @return a new function implementation instance + */ + public IDStarAlgorithm newInstance() { + return implSupplier.get(); + } } private final DStarAlgorithmEnum algoType; + /** + * @param algorithm to implement + */ public DStarRunner(DStarAlgorithmEnum algorithm) { this.algoType = algorithm; } @@ -86,13 +113,7 @@ public final class DStarRunner implements Function3Arg { } // Create an algorithm runner. - IDStarAlgorithm algorithm; - switch(algoType) { - case DGET: algorithm = new DGet(); break; - case DMIN: algorithm = new DMin(); break; - default: - throw new IllegalStateException("Unexpected algorithm type " + algoType + " encountered."); - } + IDStarAlgorithm algorithm = algoType.newInstance(); // Iterate over all DB entries. final int height = db.getHeight(); diff --git a/src/java/org/apache/poi/ss/formula/functions/DSum.java b/src/java/org/apache/poi/ss/formula/functions/DSum.java new file mode 100644 index 000000000..26604677d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/functions/DSum.java @@ -0,0 +1,49 @@ +/* ==================================================================== + 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.ss.formula.functions; + +import org.apache.poi.ss.formula.eval.NumberEval; +import org.apache.poi.ss.formula.eval.NumericValueEval; +import org.apache.poi.ss.formula.eval.ValueEval; + +/** + * Implementation of the DSum function: + * Finds the total value of matching values in a column in an area with given conditions. + * + * TODO: + * - wildcards ? and * in string conditions + * - functions as conditions + */ +public final class DSum implements IDStarAlgorithm { + private double totalValue = 0; + + @Override + public boolean processMatch(ValueEval eval) { + if(eval instanceof NumericValueEval) { + double currentValue = ((NumericValueEval)eval).getNumberValue(); + totalValue += currentValue; + } + + return true; + } + + @Override + public ValueEval getResult() { + return new NumberEval(totalValue); + } +} diff --git a/test-data/spreadsheet/DStar.xls b/test-data/spreadsheet/DStar.xls index 0c8926142..8a5a45d7e 100644 Binary files a/test-data/spreadsheet/DStar.xls and b/test-data/spreadsheet/DStar.xls differ