Author: fanningpj Date: Fri Jul 3 16:09:03 2020 New Revision: 1879481 URL: http://svn.apache.org/viewvc?rev=1879481&view=rev Log: [github-185] Fix if function in array formulas with 2nd argument evaluating to error. Thanks to MiĆosz Rembisz. This closes #185
Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java?rev=1879481&r1=1879480&r2=1879481&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java Fri Jul 3 16:09:03 2020 @@ -38,170 +38,168 @@ import java.util.function.BiFunction; public final class IfFunc extends Var2or3ArgFunction implements ArrayFunction { @Override - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { - boolean b; - try { - b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (b) { - if (arg1 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg1; - } - return BoolEval.FALSE; - } + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { + boolean b; + try { + b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + if (b) { + if (arg1 == MissingArgEval.instance) { + return BlankEval.instance; + } + return arg1; + } + return BoolEval.FALSE; + } @Override - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, - ValueEval arg2) { - boolean b; - try { - b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (b) { - if (arg1 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg1; - } - if (arg2 == MissingArgEval.instance) { - return BlankEval.instance; - } - return arg2; - } - - public static boolean evaluateFirstArg(ValueEval arg, int srcCellRow, int srcCellCol) - throws EvaluationException { - ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - Boolean b = OperandResolver.coerceValueToBoolean(ve, false); - if (b == null) { - return false; - } - return b.booleanValue(); - } - - - @Override - public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length < 2 || args.length > 3) { - return ErrorEval.VALUE_INVALID; - } - - ValueEval arg0 = args[0]; - ValueEval arg1 = args[1]; - ValueEval arg2 = args.length == 2 ? BoolEval.FALSE : args[2]; - return evaluateArrayArgs(arg0, arg1, arg2, srcRowIndex, srcColumnIndex); - } - - ValueEval evaluateArrayArgs(ValueEval arg0, ValueEval arg1, ValueEval arg2, int srcRowIndex, int srcColumnIndex) { - 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; - } - int a2FirstCol = 0, a2FirstRow = 0; - if (arg1 instanceof AreaEval) { - AreaEval ae = (AreaEval)arg1; - w2 = ae.getWidth(); - h2 = ae.getHeight(); - a2FirstCol = ae.getFirstColumn(); - a2FirstRow = ae.getFirstRow(); - } else if (arg1 instanceof RefEval){ - RefEval ref = (RefEval)arg1; - w2 = 1; - h2 = 1; - a2FirstCol = ref.getColumn(); - a2FirstRow = ref.getRow(); - } else { - w2 = 1; - h2 = 1; - } - - int a3FirstCol = 0, a3FirstRow = 0; - if (arg2 instanceof AreaEval) { - AreaEval ae = (AreaEval)arg2; - a3FirstCol = ae.getFirstColumn(); - a3FirstRow = ae.getFirstRow(); - } else if (arg2 instanceof RefEval){ - RefEval ref = (RefEval)arg2; - a3FirstCol = ref.getColumn(); - a3FirstRow = ref.getRow(); - } - - 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(); - } - ValueEval vB; - try { - vB = OperandResolver.getSingleValue(arg1, a2FirstRow + i, a2FirstCol + j); - } catch (FormulaParseException e) { - vB = ErrorEval.NAME_INVALID; - } catch (EvaluationException e) { - vB = e.getErrorEval(); - } - - ValueEval vC; - try { - vC = OperandResolver.getSingleValue(arg2, a3FirstRow + i, a3FirstCol + j); - } catch (FormulaParseException e) { - vC = ErrorEval.NAME_INVALID; - } catch (EvaluationException e) { - vC = e.getErrorEval(); - } - - if(vA instanceof ErrorEval){ - vals[idx++] = vA; - } else if (vB instanceof ErrorEval) { - vals[idx++] = vB; - } else { - Boolean b; - try { - b = OperandResolver.coerceValueToBoolean(vA, false); - vals[idx++] = b != null && b ? vB : vC; - } catch (EvaluationException e) { - vals[idx++] = e.getErrorEval(); - } - } - - } - } - - if (vals.length == 1) { - return vals[0]; - } + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, + ValueEval arg2) { + boolean b; + try { + b = evaluateFirstArg(arg0, srcRowIndex, srcColumnIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + if (b) { + if (arg1 == MissingArgEval.instance) { + return BlankEval.instance; + } + return arg1; + } + if (arg2 == MissingArgEval.instance) { + return BlankEval.instance; + } + return arg2; + } + + public static boolean evaluateFirstArg(ValueEval arg, int srcCellRow, int srcCellCol) + throws EvaluationException { + ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + Boolean b = OperandResolver.coerceValueToBoolean(ve, false); + if (b == null) { + return false; + } + return b.booleanValue(); + } - return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals); - } + + @Override + public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { + if (args.length < 2 || args.length > 3) { + return ErrorEval.VALUE_INVALID; + } + + ValueEval arg0 = args[0]; + ValueEval arg1 = args[1]; + ValueEval arg2 = args.length == 2 ? BoolEval.FALSE : args[2]; + return evaluateArrayArgs(arg0, arg1, arg2, srcRowIndex, srcColumnIndex); + } + + ValueEval evaluateArrayArgs(ValueEval arg0, ValueEval arg1, ValueEval arg2, int srcRowIndex, int srcColumnIndex) { + 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; + } + int a2FirstCol = 0, a2FirstRow = 0; + if (arg1 instanceof AreaEval) { + AreaEval ae = (AreaEval)arg1; + w2 = ae.getWidth(); + h2 = ae.getHeight(); + a2FirstCol = ae.getFirstColumn(); + a2FirstRow = ae.getFirstRow(); + } else if (arg1 instanceof RefEval){ + RefEval ref = (RefEval)arg1; + w2 = 1; + h2 = 1; + a2FirstCol = ref.getColumn(); + a2FirstRow = ref.getRow(); + } else { + w2 = 1; + h2 = 1; + } + + int a3FirstCol = 0, a3FirstRow = 0; + if (arg2 instanceof AreaEval) { + AreaEval ae = (AreaEval)arg2; + a3FirstCol = ae.getFirstColumn(); + a3FirstRow = ae.getFirstRow(); + } else if (arg2 instanceof RefEval){ + RefEval ref = (RefEval)arg2; + a3FirstCol = ref.getColumn(); + a3FirstRow = ref.getRow(); + } + + 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(); + } + ValueEval vB; + try { + vB = OperandResolver.getSingleValue(arg1, a2FirstRow + i, a2FirstCol + j); + } catch (FormulaParseException e) { + vB = ErrorEval.NAME_INVALID; + } catch (EvaluationException e) { + vB = e.getErrorEval(); + } + + ValueEval vC; + try { + vC = OperandResolver.getSingleValue(arg2, a3FirstRow + i, a3FirstCol + j); + } catch (FormulaParseException e) { + vC = ErrorEval.NAME_INVALID; + } catch (EvaluationException e) { + vC = e.getErrorEval(); + } + + if(vA instanceof ErrorEval){ + vals[idx++] = vA; + } else { + Boolean b; + try { + b = OperandResolver.coerceValueToBoolean(vA, false); + vals[idx++] = b != null && b ? vB : vC; + } catch (EvaluationException e) { + vals[idx++] = e.getErrorEval(); + } + } + + } + } + + if (vals.length == 1) { + return vals[0]; + } + + return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals); + } } Modified: poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls URL: http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls?rev=1879481&r1=1879480&r2=1879481&view=diff ============================================================================== Binary files - no diff available. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org