Excel and LibreOffice use the default value in this case git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1884959 13f79535-47bb-0310-9956-ffa450edef68tags/REL_5_0_0
*/ | */ | ||||
public final class ErrorEval implements ValueEval { | public final class ErrorEval implements ValueEval { | ||||
private static final Map<FormulaError,ErrorEval> evals = new HashMap<>(); | private static final Map<FormulaError,ErrorEval> evals = new HashMap<>(); | ||||
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */ | /** <b>#NULL!</b> - Intersection of two cell ranges is empty */ | ||||
public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL); | public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL); | ||||
/** <b>#DIV/0!</b> - Division by zero */ | /** <b>#DIV/0!</b> - Division by zero */ | ||||
} | } | ||||
/** | /** | ||||
* Converts error codes to text. Handles non-standard error codes OK. | |||||
* Converts error codes to text. Handles non-standard error codes OK. | |||||
* For debug/test purposes (and for formatting error messages). | * For debug/test purposes (and for formatting error messages). | ||||
* @return the String representation of the specified Excel error code. | * @return the String representation of the specified Excel error code. | ||||
*/ | */ | ||||
return "~non~std~err(" + errorCode + ")~"; | return "~non~std~err(" + errorCode + ")~"; | ||||
} | } | ||||
private FormulaError _error; | |||||
private final FormulaError _error; | |||||
private ErrorEval(FormulaError error) { | private ErrorEval(FormulaError error) { | ||||
_error = error; | _error = error; | ||||
evals.put(error, this); | evals.put(error, this); |
/** | /** | ||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > | * @author Amol S. Deshmukh < amolweb at ya hoo dot com > | ||||
* | |||||
* | |||||
*/ | */ | ||||
public interface NumericValueEval extends ValueEval { | public interface NumericValueEval extends ValueEval { | ||||
public abstract double getNumberValue(); | |||||
double getNumberValue(); | |||||
} | } |
package org.apache.poi.ss.formula.functions; | package org.apache.poi.ss.formula.functions; | ||||
import org.apache.poi.ss.formula.TwoDEval; | import org.apache.poi.ss.formula.TwoDEval; | ||||
import org.apache.poi.ss.formula.eval.BlankEval; | |||||
import org.apache.poi.ss.formula.eval.ErrorEval; | import org.apache.poi.ss.formula.eval.ErrorEval; | ||||
import org.apache.poi.ss.formula.eval.EvaluationException; | import org.apache.poi.ss.formula.eval.EvaluationException; | ||||
import org.apache.poi.ss.formula.eval.MissingArgEval; | |||||
import org.apache.poi.ss.formula.eval.NumberEval; | import org.apache.poi.ss.formula.eval.NumberEval; | ||||
import org.apache.poi.ss.formula.eval.NumericValueEval; | import org.apache.poi.ss.formula.eval.NumericValueEval; | ||||
import org.apache.poi.ss.formula.eval.OperandResolver; | import org.apache.poi.ss.formula.eval.OperandResolver; | ||||
throw new EvaluationException(ErrorEval.VALUE_INVALID); | throw new EvaluationException(ErrorEval.VALUE_INVALID); | ||||
} | } | ||||
// if the string parses as a number, it is OK | // if the string parses as a number, it is OK | ||||
return d.doubleValue(); | |||||
return d; | |||||
} | |||||
if (match_type instanceof MissingArgEval || match_type instanceof BlankEval) { | |||||
// Excel-Online ignores a missing match-type and | |||||
// uses the default-value instead | |||||
return 1; | |||||
} | } | ||||
throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")"); | throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")"); | ||||
} | } |
import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||
import org.junit.jupiter.params.ParameterizedTest; | import org.junit.jupiter.params.ParameterizedTest; | ||||
import org.junit.jupiter.params.provider.EnumSource; | import org.junit.jupiter.params.provider.EnumSource; | ||||
import org.junit.jupiter.params.provider.ValueSource; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@Test | |||||
public void test64986() throws IOException { | |||||
XSSFWorkbook w = new XSSFWorkbook(); | |||||
XSSFSheet s = w.createSheet(); | |||||
XSSFRow r = s.createRow(0); | |||||
XSSFCell c = r.createCell(0); | |||||
c.setCellFormula("MATCH(\"VAL\",B1:B11,)"); | |||||
FormulaEvaluator evaluator = w.getCreationHelper().createFormulaEvaluator(); | |||||
CellValue value = evaluator.evaluate(c); | |||||
assertEquals(CellType.ERROR, value.getCellType()); | |||||
assertEquals(ErrorEval.NA.getErrorCode(), value.getErrorValue()); | |||||
// put a value in place so the match should find something | |||||
Cell val = r.createCell(1); | |||||
val.setCellValue("VAL"); | |||||
// clear and check that now we find a match | |||||
evaluator.clearAllCachedResultValues(); | |||||
value = evaluator.evaluate(c); | |||||
assertEquals(CellType.NUMERIC, value.getCellType()); | |||||
assertEquals(1, value.getNumberValue(), 0.01); | |||||
} | |||||
} | } |