]> source.dussan.org Git - poi.git/commitdiff
Support evaluation of indirect defined names in INDIRECT
authorYegor Kozlov <yegor@apache.org>
Sun, 14 Feb 2010 17:11:08 +0000 (17:11 +0000)
committerYegor Kozlov <yegor@apache.org>
Sun, 14 Feb 2010 17:11:08 +0000 (17:11 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@910043 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndirect.java

index 28c8f53b0f5464b30292db163924fa77942d47e7..10ae36634936d833d345388f0f526de0def6888f 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="add">Support evaluation of indirect defined names in INDIRECT</action>
            <action dev="POI-DEVELOPERS" type="fix">43670 - Improve HDGF ChunkV11 separator detection, and short string detection, to solve the "Negative length of ChunkHeader" problem</action>
            <action dev="POI-DEVELOPERS" type="add">48617 - Optionally allow the overriding of the Locale used by DataFormatter to control how the default number and date formats should look</action>
            <action dev="POI-DEVELOPERS" type="add">New event based xssf text extractor (XSSFEventBasedExcelExtractor)</action>
index 32bc460d0eac32fa7855bc9f08db437a7594e584..147e07d7a543cb38360db01684212b508020cca3 100644 (file)
 
 package org.apache.poi.ss.formula;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.*;
 import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
@@ -159,8 +156,11 @@ public final class OperationEvaluationContext {
                        case BAD_CELL_OR_NAMED_RANGE:
                                return ErrorEval.REF_INVALID;
                        case NAMED_RANGE:
-                               throw new RuntimeException("Cannot evaluate '" + refStrPart1
-                                               + "'. Indirect evaluation of defined names not supported yet");
+                EvaluationName nm = ((FormulaParsingWorkbook)_workbook).getName(refStrPart1, _sheetIndex);
+                if(!nm.isRange()){
+                    throw new RuntimeException("Specified name '" + refStrPart1 + "' is not a range as expected.");
+                }
+                return _bookEvaluator.evaluateNameFormula(nm.getNameDefinition(), this);
                }
                if (refStrPart2 == null) {
                        // no ':'
index 199217eb8834518cc482b2c70e0bfcdf8c84577e..ad15b84e9c7b148f14fca999500020e1df7a20db 100644 (file)
@@ -580,7 +580,10 @@ public final class WorkbookEvaluator {
 
                throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
        }
-       private ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) {
+    /**
+     * YK: Used by OperationEvaluationContext to resolve indirect names.
+     */
+       /*package*/ ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) {
                if (ptgs.length > 1) {
                        throw new RuntimeException("Complex name formulas not supported yet");
                }
index 50c2067798c416cf963ada0e5ae4f90db63a76f5..6be7b03309f03ac7483f2526718ed7b28aaf610c 100644 (file)
@@ -21,14 +21,11 @@ import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.usermodel.HSSFCell;
-import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
-import org.apache.poi.hssf.usermodel.HSSFRow;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.util.CellReference;
 
 /**
  * Tests for the INDIRECT() function.</p>
@@ -62,6 +59,19 @@ public final class TestIndirect extends TestCase {
 
                createDataRow(sheet3, 0, 30, 31, 32);
                createDataRow(sheet3, 1, 33, 34, 35);
+
+        HSSFName name1 = wb.createName();
+        name1.setNameName("sales1");
+        name1.setRefersToFormula("Sheet1!A1:D1");
+
+        HSSFName name2 = wb.createName();
+        name2.setNameName("sales2");
+        name2.setRefersToFormula("Sheet2!B1:C3");
+
+        HSSFRow row = sheet1.createRow(3);
+        row.createCell(0).setCellValue("sales1");  //A4
+        row.createCell(1).setCellValue("sales2");  //B4
+
                return wb;
        }
 
@@ -103,6 +113,8 @@ public final class TestIndirect extends TestCase {
 
                confirm(feA, c, "INDIRECT(\"A1:G1\")", 13); // de-reference area ref (note formula is in C4)
 
+        confirm(feA, c, "SUM(INDIRECT(A4))", 50); // indirect defined name
+        confirm(feA, c, "SUM(INDIRECT(B4))", 351); // indirect defined name pointinh to other sheet
 
                // simple error propagation: