// 358: GETPIVOTDATA
retval[359] = new Hyperlink();
// 360: PHONETIC
- // 361: AVERAGEA
+ retval[361] = AggregateFunction.AVERAGEA;
retval[362] = MinaMaxa.MAXA;
retval[363] = MinaMaxa.MINA;
// 364: STDEVPA
// 365: VARPA
- // 366: STDEVA
- // 367: VARA
+ retval[366] = AggregateFunction.STDEVA;
+ retval[367] = AggregateFunction.VARA;
for (int i = 0; i < retval.length; i++) {
Function f = retval[i];
}
};
public static final Function AVERAGE = new AggregateFunction() {
+ @Override
+ protected double evaluate(double[] values) throws EvaluationException {
+ if (values.length < 1) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return MathX.average(values);
+ }
+ };
+ public static final Function AVERAGEA = new AggregateFunction() {
+ @Override
+ protected boolean handleLogicalValues() {
+ return true;
+ }
+
+ @Override
protected double evaluate(double[] values) throws EvaluationException {
if (values.length < 1) {
throw new EvaluationException(ErrorEval.DIV_ZERO);
return StatsLib.stdevp(values);
}
};
+ public static final Function STDEVA = new AggregateFunction() {
+ @Override
+ protected boolean handleLogicalValues() {
+ return true;
+ }
+
+ @Override
+ protected double evaluate(double[] values) throws EvaluationException {
+ if (values.length < 1) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return StatsLib.stdev(values);
+ }
+ };
public static final Function SUM = new AggregateFunction() {
protected double evaluate(double[] values) {
return MathX.sum(values);
return StatsLib.varp(values);
}
};
+ public static final Function VARA = new AggregateFunction() {
+ @Override
+ protected boolean handleLogicalValues() {
+ return true;
+ }
+
+ @Override
+ protected double evaluate(double[] values) throws EvaluationException {
+ if (values.length < 1) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return StatsLib.var(values);
+ }
+ };
public static final Function GEOMEAN = new Geomean();
private static class Product extends AggregateFunction {
blankConsumer = ConsumerFactory.createForBlank(policy);
}
+ /**
+ * Functions like AVERAGEA() differ from AVERAGE() in the way they handle non-numeric cells.
+ * AVERAGEA treats booleans as 1.0 (true) and 0.0 (false). For strings, they should be parsed as numbers.
+ * When the string is not a number, treat it as 0.0.
+ *
+ * @return whether to parse non-numeric cells
+ */
+ protected boolean handleLogicalValues() {
+ return false;
+ }
+
public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
try {
double[] values = getNumberArray(args);
ValueEval ve = ae.getValue(sIx, rrIx, rcIx);
if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
if (!isHiddenRowCounted() && ae.isRowHidden(rrIx)) continue;
- collectValue(ve, true, temp);
+ collectValue(ve, !handleLogicalValues(), temp);
}
}
}
for (int rcIx = 0; rcIx < width; rcIx++) {
ValueEval ve = ae.getValue(rrIx, rcIx);
if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
- collectValue(ve, true, temp);
+ collectValue(ve, !handleLogicalValues(), temp);
}
}
return;
if (operand instanceof RefEval) {
RefEval re = (RefEval) operand;
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
- collectValue(re.getInnerValueEval(sIx), true, temp);
+ collectValue(re.getInnerValueEval(sIx), !handleLogicalValues(), temp);
}
return;
}
// ignore all ref strings
return;
}
- String s = ((StringValueEval) ve).getStringValue();
+ String s = ((StringValueEval) ve).getStringValue().trim();
Double d = OperandResolver.parseDouble(s);
if (d == null) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ if (handleLogicalValues()) {
+ temp.add(0.0);
+ } else {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ } else {
+ temp.add(d.doubleValue());
}
- temp.add(d.doubleValue());
return;
}
if (ve instanceof ErrorEval) {
--- /dev/null
+
+/* ====================================================================
+ 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.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.apache.poi.ss.util.Utils.addRow;
+import static org.apache.poi.ss.util.Utils.assertDouble;
+
+/**
+ * Testcase for AVERAGEA() functions
+ */
+public class TestAverageA {
+
+ //https://support.microsoft.com/en-us/office/averagea-function-f5f84098-d453-4f4c-bbba-3d2c66356091
+ @Test
+ void testMicrosoftExample1() throws IOException {
+ try (HSSFWorkbook wb = initWorkbook1()) {
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+ HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(12);
+ assertDouble(fe, cell, "AVERAGEA(A2:A6)", 5.6, 0.00000000001);
+ assertDouble(fe, cell, "AVERAGEA(A2:A5,A7)", 5.6, 0.00000000001);
+ assertDouble(fe, cell, "AVERAGE(A2:A6)", 7, 0.00000000001);
+ }
+ }
+
+ private HSSFWorkbook initWorkbook1() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet();
+ addRow(sheet, 0, "Data");
+ addRow(sheet, 1, 10);
+ addRow(sheet, 2, 7);
+ addRow(sheet, 3, 9);
+ addRow(sheet, 4, 2);
+ addRow(sheet, 5, "Not available");
+ addRow(sheet, 6, "Formula");
+ return wb;
+ }
+}