]> source.dussan.org Git - poi.git/commitdiff
More progress towards #55906 - Have the ExternSheet references set up for multi-sheet...
authorNick Burch <nick@apache.org>
Fri, 25 Jul 2014 10:05:57 +0000 (10:05 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Jul 2014 10:05:57 +0000 (10:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613373 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/model/InternalWorkbook.java
src/java/org/apache/poi/hssf/model/LinkTable.java
src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java

index 45c16124618f1c5b5cae392a8d260f8ef16f48e3..1e88e94b078aedd39ab16554858a1d0ed5e58d72 100644 (file)
@@ -1871,17 +1871,31 @@ public final class InternalWorkbook {
         return linkTable.getLastInternalSheetIndexForExtIndex(externSheetNumber);
     }
 
-    /** returns the extern sheet number for specific sheet number ,
-     *  if this sheet doesn't exist in extern sheet , add it
-     * @param sheetNumber sheet number
+    /** 
+     * Returns the extern sheet number for specific sheet number.
+     * If this sheet doesn't exist in extern sheet, add it
+     * @param sheetNumber local sheet number
      * @return index to extern sheet
      */
     public short checkExternSheet(int sheetNumber){
         return (short)getOrCreateLinkTable().checkExternSheet(sheetNumber);
     }
+    /** 
+     * Returns the extern sheet number for specific range of sheets.
+     * If this sheet range doesn't exist in extern sheet, add it
+     * @param firstSheetNumber first local sheet number
+     * @param lastSheetNumber last local sheet number
+     * @return index to extern sheet
+     */
+    public short checkExternSheet(int firstSheetNumber, int lastSheetNumber){
+        return (short)getOrCreateLinkTable().checkExternSheet(firstSheetNumber, lastSheetNumber);
+    }
 
     public int getExternalSheetIndex(String workbookName, String sheetName) {
-        return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName);
+        return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName, sheetName);
+    }
+    public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
+        return getOrCreateLinkTable().getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
     }
 
 
index a01b287161c8b99923bd07252a7b1da10a9114f7..7277da2e6c240518bfb71d308342af3fa55ba77b 100644 (file)
@@ -383,7 +383,7 @@ final class LinkTable {
                }
        }
 
-       public int getExternalSheetIndex(String workbookName, String sheetName) {
+       public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
                SupBookRecord ebrTarget = null;
                int externalBookIndex = -1;
                for (int i=0; i<_externalBookBlocks.length; i++) {
@@ -400,12 +400,13 @@ final class LinkTable {
                if (ebrTarget == null) {
                        throw new RuntimeException("No external workbook with name '" + workbookName + "'");
                }
-               int sheetIndex = getSheetIndex(ebrTarget.getSheetNames(), sheetName);
+               int firstSheetIndex = getSheetIndex(ebrTarget.getSheetNames(), firstSheetName);
+        int lastSheetIndex = getSheetIndex(ebrTarget.getSheetNames(), lastSheetName);
 
-               int result = _externSheetRecord.getRefIxForSheet(externalBookIndex, sheetIndex);
+               int result = _externSheetRecord.getRefIxForSheet(externalBookIndex, firstSheetIndex, lastSheetIndex);
                if (result < 0) {
                        throw new RuntimeException("ExternSheetRecord does not contain combination ("
-                                       + externalBookIndex + ", " + sheetIndex + ")");
+                                       + externalBookIndex + ", " + firstSheetIndex + ", " + lastSheetIndex + ")");
                }
                return result;
        }
@@ -454,6 +455,9 @@ final class LinkTable {
        }
 
        public int checkExternSheet(int sheetIndex) {
+           return checkExternSheet(sheetIndex, sheetIndex);
+       }
+    public int checkExternSheet(int firstSheetIndex, int lastSheetIndex) {
                int thisWbIndex = -1; // this is probably always zero
                for (int i=0; i<_externalBookBlocks.length; i++) {
                        SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord();
@@ -467,12 +471,12 @@ final class LinkTable {
                }
 
                //Trying to find reference to this sheet
-               int i = _externSheetRecord.getRefIxForSheet(thisWbIndex, sheetIndex);
+               int i = _externSheetRecord.getRefIxForSheet(thisWbIndex, firstSheetIndex, lastSheetIndex);
                if (i>=0) {
                        return i;
                }
                //We haven't found reference to this sheet
-               return _externSheetRecord.addRef(thisWbIndex, sheetIndex, sheetIndex);
+               return _externSheetRecord.addRef(thisWbIndex, firstSheetIndex, lastSheetIndex);
        }
 
        /**
@@ -612,7 +616,8 @@ final class LinkTable {
         int numberOfNames = extBlock.getNumberOfNames();
         // a new name is inserted in the end of the SupBookRecord, after the last name
         _workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord);
-        int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, -2 /* the scope is workbook*/);
+        int fakeSheetIdx = -2; /* the scope is workbook*/
+        int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, fakeSheetIdx, fakeSheetIdx);
         return new NameXPtg(ix, nameIndex);
     }
 
index 846c9c2a6baeddf9b9516d4fc34bf7ecc78054b0..636b6b0da063bda62bd8b4c309263e25b3845f11 100644 (file)
@@ -276,14 +276,15 @@ public class ExternSheetRecord extends StandardRecord {
                return _list.size() - 1;
        }
 
-       public int getRefIxForSheet(int externalBookIndex, int sheetIndex) {
+       public int getRefIxForSheet(int externalBookIndex, int firstSheetIndex, int lastSheetIndex) {
                int nItems = _list.size();
                for (int i = 0; i < nItems; i++) {
                        RefSubRecord ref = getRef(i);
                        if (ref.getExtBookIndex() != externalBookIndex) {
                                continue;
                        }
-                       if (ref.getFirstSheetIndex() == sheetIndex && ref.getLastSheetIndex() == sheetIndex) {
+                       if (ref.getFirstSheetIndex() == firstSheetIndex && 
+                               ref.getLastSheetIndex() == lastSheetIndex) {
                                return i;
                        }
                }
index 84eb528d5591e30a8eb92864f62550c1ab09dd36..5136babe2d1419cb7e8d63b469436689bb6428ac 100644 (file)
@@ -30,7 +30,9 @@ import org.apache.poi.ss.formula.FormulaParseException;
 import org.apache.poi.ss.formula.FormulaParsingWorkbook;
 import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.NameIdentifier;
 import org.apache.poi.ss.formula.SheetIdentifier;
+import org.apache.poi.ss.formula.SheetRangeIdentifier;
 import org.apache.poi.ss.formula.ptg.Area3DPtg;
 import org.apache.poi.ss.formula.ptg.NamePtg;
 import org.apache.poi.ss.formula.ptg.NameXPtg;
@@ -69,7 +71,25 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
     public int getExternalSheetIndex(String workbookName, String sheetName) {
         return _iBook.getExternalSheetIndex(workbookName, sheetName);
     }
-
+    public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
+        return _iBook.getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
+    }
+    
+    public int getExternalSheetIndex(String workbookName, NameIdentifier sheetName) {
+        return getExternalSheetIndex(workbookName, sheetName.getName());
+    }
+    public int getExternalSheetIndex(String workbookName, NameIdentifier firstSheetName, NameIdentifier lastSheetName) {
+        return getExternalSheetIndex(workbookName, firstSheetName.getName(), lastSheetName.getName());
+    }
+    public int getExternalSheetIndex(NameIdentifier sheetName) {
+        return getExternalSheetIndex(sheetName.getName());
+    }
+    public int getExternalSheetIndex(NameIdentifier firstSheetName, NameIdentifier lastSheetName) {
+        int firstSheetIndex = _uBook.getSheetIndex(firstSheetName.getName());
+        int lastSheetIndex = _uBook.getSheetIndex(lastSheetName.getName());
+        return _iBook.checkExternSheet(firstSheetIndex, lastSheetIndex);
+    }
+    
     public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
         int extIx = getSheetExtIx(sheet);
         return new Ref3DPtg(cr, extIx);
@@ -235,11 +255,25 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
         if (sheetIden == null) {
             extIx = -1;
         } else {
-            String sName = sheetIden.getSheetIdentifier().getName();
+            NameIdentifier sheetName = sheetIden.getSheetIdentifier();
+            NameIdentifier lastSheetName = null;
+            
+            if (sheetIden instanceof SheetRangeIdentifier) {
+                lastSheetName = ((SheetRangeIdentifier)sheetIden).getLastSheetIdentifier();
+            }
+            
             if (sheetIden.getBookName() == null) {
-                extIx = getExternalSheetIndex(sName);
+                if (lastSheetName == null) {
+                    extIx = getExternalSheetIndex(sheetName);
+                } else {
+                    extIx = getExternalSheetIndex(sheetName, lastSheetName);
+                }
             } else {
-                extIx = getExternalSheetIndex(sheetIden.getBookName(), sName);
+                if (lastSheetName == null) {
+                    extIx = getExternalSheetIndex(sheetIden.getBookName(), sheetName);
+                } else {
+                    extIx = getExternalSheetIndex(sheetIden.getBookName(), sheetName, lastSheetName);
+                }
             }
         }
         return extIx;
index 222da5cd6275a5ed76372d0abcac0905de60141f..bf86a004cbea62089c47803b60ee58e897e455ab 100644 (file)
@@ -283,16 +283,15 @@ public final class TestXSSFFormulaParser {
             
             
             // Check things parse as expected:
-            // Note - Ptgs will only show one sheet, the formula
-            //  parser stuff looks up the second later
+            // TODO Fix it so that the Pxgs get the second sheet too!
             
             
             // SUM to one cell over 3 workbooks, relative reference
             ptgs = parse(fpb, "SUM(Sheet1:Sheet3!A1)");
             assertEquals(2, ptgs.length);
             if (wb instanceof HSSFWorkbook) {
-                assertEquals(Ref3DPtg.class, ptgs[0].getClass());
-                assertEquals("Sheet1!A1",    toFormulaString(ptgs[0], fpb));
+                assertEquals(Ref3DPtg.class,     ptgs[0].getClass());
+                assertEquals("Sheet1:Sheet3!A1", toFormulaString(ptgs[0], fpb));
             } else {
                 assertEquals(Ref3DPxg.class, ptgs[0].getClass());
                 assertEquals("Sheet1!A1",    toFormulaString(ptgs[0], fpb));
@@ -305,8 +304,8 @@ public final class TestXSSFFormulaParser {
             ptgs = parse(fpb, "MAX(Sheet1:Sheet3!A$1)");
             assertEquals(2, ptgs.length);
             if (wb instanceof HSSFWorkbook) {
-                assertEquals(Ref3DPtg.class, ptgs[0].getClass());
-                assertEquals("Sheet1!A$1",   toFormulaString(ptgs[0], fpb));
+                assertEquals(Ref3DPtg.class,      ptgs[0].getClass());
+                assertEquals("Sheet1:Sheet3!A$1", toFormulaString(ptgs[0], fpb));
             } else {
                 assertEquals(Ref3DPxg.class, ptgs[0].getClass());
                 assertEquals("Sheet1!A$1",   toFormulaString(ptgs[0], fpb));
@@ -319,14 +318,20 @@ public final class TestXSSFFormulaParser {
             ptgs = parse(fpb, "MIN(Sheet1:Sheet3!$A$1)");
             assertEquals(2, ptgs.length);
             if (wb instanceof HSSFWorkbook) {
-                assertEquals(Ref3DPtg.class, ptgs[0].getClass());
-                assertEquals("Sheet1!$A$1",  toFormulaString(ptgs[0], fpb));
+                assertEquals(Ref3DPtg.class,       ptgs[0].getClass());
+                assertEquals("Sheet1:Sheet3!$A$1", toFormulaString(ptgs[0], fpb));
             } else {
                 assertEquals(Ref3DPxg.class, ptgs[0].getClass());
                 assertEquals("Sheet1!$A$1",  toFormulaString(ptgs[0], fpb));
             }
             assertEquals(FuncVarPtg.class, ptgs[1].getClass());
             assertEquals("MIN",            toFormulaString(ptgs[1], fpb));
+            
+            
+            // Check we can round-trip - try to set a new one to a new cell
+            Cell newF = s1.getRow(0).createCell(10, Cell.CELL_TYPE_FORMULA);
+            newF.setCellFormula("SUM(Sheet2:Sheet3!A1)");
+            assertEquals("SUM(Sheet2:Sheet3!A1)", newF.getCellFormula());
         }
     }
     private static String toFormulaString(Ptg ptg, FormulaParsingWorkbook wb) {
index f780bde0e6314892ad75abe372e1d69eae39a528..4546de31ad76af499c13c3ec240b29fbf85c689a 100644 (file)
@@ -476,10 +476,9 @@ public final class TestFormulaParser extends TestCase {
         assertEquals("\'Test Sheet\'!A1", formula);
         
         // Now both
-        // TODO Implement remaining logic for #55906
         cell.setCellFormula("Cash_Flow:\'Test Sheet\'!A1");
         formula = cell.getCellFormula();
-//        assertEquals("Cash_Flow:\'Test Sheet\'!A1", formula);
+        assertEquals("Cash_Flow:\'Test Sheet\'!A1", formula);
        }
        
        /**