From b231366fb699414386fc14b59a8194b1ad1f20d3 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Wed, 30 Dec 2020 21:40:12 +0000 Subject: [PATCH] Bug 64986: Support missing or blank match_type for function Match 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-ffa450edef68 --- .../apache/poi/ss/formula/eval/ErrorEval.java | 6 ++--- .../poi/ss/formula/eval/NumericValueEval.java | 4 +-- .../poi/ss/formula/functions/Match.java | 9 ++++++- .../poi/xssf/usermodel/TestXSSFBugs.java | 25 +++++++++++++++++- .../spreadsheet/MatchFunctionTestCaseData.xls | Bin 40448 -> 14848 bytes 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java b/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java index faa8bed265..31d08d05e5 100644 --- a/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/ErrorEval.java @@ -27,7 +27,7 @@ import org.apache.poi.ss.usermodel.FormulaError; */ public final class ErrorEval implements ValueEval { private static final Map evals = new HashMap<>(); - + /** #NULL! - Intersection of two cell ranges is empty */ public static final ErrorEval NULL_INTERSECTION = new ErrorEval(FormulaError.NULL); /** #DIV/0! - Division by zero */ @@ -65,7 +65,7 @@ public final class ErrorEval implements ValueEval { } /** - * 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). * @return the String representation of the specified Excel error code. */ @@ -77,7 +77,7 @@ public final class ErrorEval implements ValueEval { return "~non~std~err(" + errorCode + ")~"; } - private FormulaError _error; + private final FormulaError _error; private ErrorEval(FormulaError error) { _error = error; evals.put(error, this); diff --git a/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java b/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java index 056f21cdf7..c6dcf1dc27 100644 --- a/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/NumericValueEval.java @@ -22,9 +22,9 @@ package org.apache.poi.ss.formula.eval; /** * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * */ public interface NumericValueEval extends ValueEval { - public abstract double getNumberValue(); + double getNumberValue(); } diff --git a/src/java/org/apache/poi/ss/formula/functions/Match.java b/src/java/org/apache/poi/ss/formula/functions/Match.java index 4b16b0c87f..4a61476657 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Match.java +++ b/src/java/org/apache/poi/ss/formula/functions/Match.java @@ -18,8 +18,10 @@ package org.apache.poi.ss.formula.functions; 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.EvaluationException; +import org.apache.poi.ss.formula.eval.MissingArgEval; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.NumericValueEval; import org.apache.poi.ss.formula.eval.OperandResolver; @@ -177,7 +179,12 @@ public final class Match extends Var2or3ArgFunction { throw new EvaluationException(ErrorEval.VALUE_INVALID); } // 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() + ")"); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index f19190e852..5476e28688 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -119,7 +119,6 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; 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.CTCols; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; @@ -3638,4 +3637,28 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } } } + + @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); + } } diff --git a/test-data/spreadsheet/MatchFunctionTestCaseData.xls b/test-data/spreadsheet/MatchFunctionTestCaseData.xls index 0b98a177136c381aae62af94f4dbed751c2f8359..a2a99b4c39b3cc39d0aa829bd23bc6410c47c170 100644 GIT binary patch literal 14848 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 ZN4xd08ev>pt%h&4JQ|zV)wD73{|y6LPE-H@ literal 40448 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