]> source.dussan.org Git - poi.git/commitdiff
#63302 Formula evaluation of names with offset or row function is incorrect
authorGreg Woolsey <gwoolsey@apache.org>
Sat, 30 Mar 2019 18:14:14 +0000 (18:14 +0000)
committerGreg Woolsey <gwoolsey@apache.org>
Sat, 30 Mar 2019 18:14:14 +0000 (18:14 +0000)
thanks to John Lincoln White for the patch, including new unit tests.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1856644 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java
test-data/spreadsheet/external_name.xls [new file with mode: 0644]

index 2116456f3496f1b42e96991d48132d727ed24b85..060f274ef088c5db631bc2cb98b165b4c0d11258 100644 (file)
@@ -773,10 +773,12 @@ public final class WorkbookEvaluator {
      * YK: Used by OperationEvaluationContext to resolve indirect names.
      */
     /*package*/ ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) {
-    if (ptgs.length == 1) {
-      return getEvalForPtg(ptgs[0], ec);
-    }
-      return evaluateFormula(ec, ptgs);
+      if (ptgs.length == 1 && !(ptgs[0] instanceof FuncVarPtg)) {
+        return getEvalForPtg(ptgs[0], ec);
+      }
+        
+      OperationEvaluationContext anyValueContext = new OperationEvaluationContext(this, ec.getWorkbook(), ec.getSheetIndex(), ec.getRowIndex(), ec.getColumnIndex(), new EvaluationTracker(_cache), false);
+      return evaluateFormula(anyValueContext, ptgs);
     }
 
     /**
index 4441a4fb535d7fe1ac57e0d0466e147c0f2bf6ff..be2cc54cde07d493bebb2fe5b392aec9ad15c257 100644 (file)
@@ -274,12 +274,22 @@ public class TestWorkbookEvaluator {
         Name name3 = wb.createName();
         name3.setNameName("aSet");
         name3.setRefersToFormula("Sheet1!$A$2:$A$4");
-
+        
+        Name name4 = wb.createName();
+        name4.setNameName("offsetFormula");
+        name4.setRefersToFormula("OFFSET(Sheet1!$A$1:$A$4,2,0,2,1)");
+        
+        Name name5 = wb.createName();
+        name5.setNameName("rowFormula");
+        name5.setRefersToFormula("ROW()");
         
         Row row0 = sheet.createRow(0);
         Row row1 = sheet.createRow(1);
         Row row2 = sheet.createRow(2);
         Row row3 = sheet.createRow(3);
+        Row row4 = sheet.createRow(4);
+        Row row5 = sheet.createRow(5);
+        
         row0.createCell(0).setCellValue(2);
         row1.createCell(0).setCellValue(5);
         row2.createCell(0).setCellValue(3);
@@ -289,16 +299,20 @@ public class TestWorkbookEvaluator {
         row1.createCell(2).setCellFormula("aFormula");
         row2.createCell(2).setCellFormula("SUM(aSet)");
         row3.createCell(2).setCellFormula("aConstant+aFormula+SUM(aSet)");
+        row4.createCell(2).setCellFormula("SUM(offsetFormula)");
+        row5.createCell(2).setCellFormula("rowFormula");
 
         FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
         assertEquals(3.14, fe.evaluate(row0.getCell(2)).getNumberValue(), EPSILON);
         assertEquals(10.0, fe.evaluate(row1.getCell(2)).getNumberValue(), EPSILON);
         assertEquals(15.0, fe.evaluate(row2.getCell(2)).getNumberValue(), EPSILON);
         assertEquals(28.14, fe.evaluate(row3.getCell(2)).getNumberValue(), EPSILON);
+        assertEquals(10.0, fe.evaluate(row4.getCell(2)).getNumberValue(), EPSILON);
+        assertEquals(6.0, fe.evaluate(row5.getCell(2)).getNumberValue(), EPSILON);
         
         wb.close();
     }
-
+    
     @Test
     public void testIgnoreMissingWorkbooks() {
         // TODO: update this test for meaningful functional behavior
diff --git a/test-data/spreadsheet/external_name.xls b/test-data/spreadsheet/external_name.xls
new file mode 100644 (file)
index 0000000..b87e6a9
Binary files /dev/null and b/test-data/spreadsheet/external_name.xls differ