evalFunc){
+ ValueEval arg0 = args[0];
+
+ int w1, w2, h1, h2;
+ int a1FirstCol = 0, a1FirstRow = 0;
+ if (arg0 instanceof AreaEval) {
+ AreaEval ae = (AreaEval)arg0;
+ w1 = ae.getWidth();
+ h1 = ae.getHeight();
+ a1FirstCol = ae.getFirstColumn();
+ a1FirstRow = ae.getFirstRow();
+ } else if (arg0 instanceof RefEval){
+ RefEval ref = (RefEval)arg0;
+ w1 = 1;
+ h1 = 1;
+ a1FirstCol = ref.getColumn();
+ a1FirstRow = ref.getRow();
+ } else {
+ w1 = 1;
+ h1 = 1;
+ }
+ w2 = 1;
+ h2 = 1;
+
+ int width = Math.max(w1, w2);
+ int height = Math.max(h1, h2);
+
+ ValueEval[] vals = new ValueEval[height * width];
+
+ int idx = 0;
+ for(int i = 0; i < height; i++){
+ for(int j = 0; j < width; j++){
+ ValueEval vA;
+ try {
+ vA = OperandResolver.getSingleValue(arg0, a1FirstRow + i, a1FirstCol + j);
+ } catch (FormulaParseException e) {
+ vA = ErrorEval.NAME_INVALID;
+ } catch (EvaluationException e) {
+ vA = e.getErrorEval();
+ }
+ vals[idx++] = evalFunc.apply(vA);
+ }
+ }
+
+ if (vals.length == 1) {
+ return vals[0];
+ }
+
+ return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
+
+ }
+
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/IfFunc.java b/src/java/org/apache/poi/ss/formula/functions/IfFunc.java
index d410350b7c..effff27815 100644
--- a/src/java/org/apache/poi/ss/formula/functions/IfFunc.java
+++ b/src/java/org/apache/poi/ss/formula/functions/IfFunc.java
@@ -17,12 +17,7 @@
package org.apache.poi.ss.formula.functions;
-import org.apache.poi.ss.formula.eval.BlankEval;
-import org.apache.poi.ss.formula.eval.BoolEval;
-import org.apache.poi.ss.formula.eval.EvaluationException;
-import org.apache.poi.ss.formula.eval.MissingArgEval;
-import org.apache.poi.ss.formula.eval.OperandResolver;
-import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.RefPtg;
@@ -36,8 +31,9 @@ import org.apache.poi.ss.formula.ptg.RefPtg;
* See bug numbers #55324 and #55747 for the full details on this.
* TODO Fix this...
*/
-public final class IfFunc extends Var2or3ArgFunction {
+public final class IfFunc extends Var2or3ArgFunction implements ArrayFunction {
+ @Override
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
boolean b;
try {
@@ -54,6 +50,7 @@ public final class IfFunc extends Var2or3ArgFunction {
return BoolEval.FALSE;
}
+ @Override
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
ValueEval arg2) {
boolean b;
@@ -83,4 +80,29 @@ public final class IfFunc extends Var2or3ArgFunction {
}
return b.booleanValue();
}
+
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ ValueEval arg0 = args[0];
+ ValueEval arg1 = args[1];
+ return evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, srcColumnIndex,
+ (vA, vB) -> {
+ Boolean b;
+ try {
+ b = OperandResolver.coerceValueToBoolean(vA, false);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (b != null && b) {
+ if (vB == MissingArgEval.instance) {
+ return BlankEval.instance;
+ }
+ return vB;
+ }
+ return BoolEval.FALSE;
+ }
+ );
+ }
+
}
diff --git a/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java b/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
index a3fe304746..5cb7d25505 100644
--- a/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
@@ -23,7 +23,7 @@ import org.apache.poi.ss.formula.eval.*;
* Implementation of the various ISxxx Logical Functions, which
* take a single expression argument, and return True or False.
*/
-public abstract class LogicalFunction extends Fixed1ArgFunction {
+public abstract class LogicalFunction extends Fixed1ArgFunction implements ArrayFunction{
@SuppressWarnings("unused")
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
@@ -41,6 +41,14 @@ public abstract class LogicalFunction extends Fixed1ArgFunction {
return BoolEval.valueOf(evaluate(ve));
}
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex){
+ return evaluateOneArrayArg(args, srcRowIndex, srcColumnIndex, (valA) ->
+ BoolEval.valueOf(evaluate(valA))
+ );
+ }
+
/**
* @param arg any {@link ValueEval}, potentially {@link BlankEval} or {@link ErrorEval}.
*/
diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
new file mode 100644
index 0000000000..cbdbfa5043
--- /dev/null
+++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
@@ -0,0 +1,32 @@
+/* ====================================================================
+ 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.junit.runners.Parameterized.Parameters;
+
+import java.util.Collection;
+
+/**
+ * Tests IF() as loaded from a test data spreadsheet.
+ */
+public class TestIFFunctionFromSpreadsheet extends BaseTestFunctionsFromSpreadsheet {
+ @Parameters(name="{0}")
+ public static Collection