mirror of https://github.com/apache/poi.git
[github-185] Fix if function in array formulas with 2nd argument evaluating to error. Thanks to Miłosz Rembisz. This closes #185
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1879481 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
be1d2aebf2
commit
be09639638
|
@ -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 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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
@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 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;
|
||||
}
|
||||
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 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);
|
||||
int width = Math.max(w1, w2);
|
||||
int height = Math.max(h1, h2);
|
||||
|
||||
ValueEval[] vals = new ValueEval[height * width];
|
||||
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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
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(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];
|
||||
}
|
||||
if (vals.length == 1) {
|
||||
return vals[0];
|
||||
}
|
||||
|
||||
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
||||
}
|
||||
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue