]> source.dussan.org Git - poi.git/commitdiff
Absolute vs relative references now work .. refactored ReferenceUtils in the bargain
authorAvik Sengupta <avik@apache.org>
Sat, 4 May 2002 15:45:05 +0000 (15:45 +0000)
committerAvik Sengupta <avik@apache.org>
Sat, 4 May 2002 15:45:05 +0000 (15:45 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352598 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/FormulaParser.java
src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java
src/java/org/apache/poi/hssf/util/AreaReference.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/util/CellReference.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java
src/testcases/org/apache/poi/hssf/util/TestCellReference.java [new file with mode: 0644]

index 50f7e8dfdbf8341679326a0eade0557b7488a315..6fd242cafc001cb5e84c73c5e7281695520bf489 100644 (file)
@@ -138,7 +138,7 @@ public class FormulaParser {
  
     /** Recognize an Alpha Character */
     private boolean IsAlpha(char c) {
-        return Character.isLetter(c);
+        return Character.isLetter(c) || c == '$';
     }
     
     
index 4a154bae727a9627f674b9f8f7baa72204a79365..eef722a6abbaf0ec51568ae05cc869d5f2b0019d 100644 (file)
@@ -63,7 +63,7 @@ package org.apache.poi.hssf.record.formula;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.BitField;
 
-import org.apache.poi.hssf.util.ReferenceUtil;
+import org.apache.poi.hssf.util.CellReference;
 
 /**
  * ValueReferencePtg - handles references (such as A1, A2, IA4) - Should also
@@ -89,11 +89,11 @@ public class ReferencePtg extends Ptg
      * numeric fields.
      */
     protected ReferencePtg(String cellref) {
-        int[] xy = ReferenceUtil.getXYFromReference(cellref);
-        setRow((short)xy[0]);
-        setColumn((short)xy[1]);
-        setColRelative(true);
-        setRowRelative(true);
+        CellReference c= new CellReference(cellref);
+        setRow((short) c.getRow());
+        setColumn((short) c.getCol());
+        setColRelative(!c.isColAbsolute());
+        setRowRelative(!c.isRowAbsolute());
     }
 
     /** Creates new ValueReferencePtg */
@@ -179,6 +179,7 @@ public class ReferencePtg extends Ptg
 
     public String toFormulaString()
     {
-        return ReferenceUtil.getReferenceFromXY(getRow(),getColumn());
+        //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
+        return (new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).toString();
     }
 }
diff --git a/src/java/org/apache/poi/hssf/util/AreaReference.java b/src/java/org/apache/poi/hssf/util/AreaReference.java
new file mode 100644 (file)
index 0000000..5c1a815
--- /dev/null
@@ -0,0 +1,104 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.util;
+
+public class AreaReference {
+    
+    
+private CellReference [] cells;
+private int dim;
+
+    /** Create an area ref from a string representation
+     */
+    public AreaReference(String reference) {
+        String[] refs = seperateAreaRefs(reference);
+        dim = refs.length;
+        cells = new CellReference[dim];
+        for (int i=0;i<dim;i++) {
+            cells[i]=new CellReference(refs[i]);
+        }
+    }
+    //not sure if we need to be flexible here!
+    /** return the dimensions of this area
+     **/
+    public int getDim() {
+        return dim;
+    }
+    
+    public String toString() {
+        StringBuffer retval = new StringBuffer();
+        for (int i=0;i<dim;i++){
+            retval.append(':');
+            retval.append(cells[i].toString());
+        }
+        retval.deleteCharAt(0);
+        return retval.toString();
+    }
+    
+    /**
+     * seperates Area refs in two parts and returns them as seperate elements in a 
+     * String array
+     */
+    private String[] seperateAreaRefs(String reference) {
+        String retval[] = new String[2];
+        int length = reference.length();
+        
+        int loc = reference.indexOf(':',0);
+        
+        retval[0] = reference.substring(0,loc);
+        retval[1] = reference.substring(loc+1);        
+        return retval;
+    }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/util/CellReference.java b/src/java/org/apache/poi/hssf/util/CellReference.java
new file mode 100644 (file)
index 0000000..55eb272
--- /dev/null
@@ -0,0 +1,176 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.util;
+
+/**
+ *
+ * @author  Avik Sengupta
+ */
+public class CellReference {
+    
+    /** Creates new CellReference */
+    private int row;
+    private int col;
+    private boolean rowAbs;
+    private boolean colAbs;
+    
+    public CellReference(String cellRef) {
+        String[] parts = seperateRowColumns(cellRef);
+        String ref = parts[0];
+        if (ref.charAt(0) == '$') {
+            colAbs=true; 
+            ref=ref.substring(1);
+        }
+        col = convertColStringToNum(ref);
+        ref=parts[1];
+        if (ref.charAt(0) == '$') {
+            rowAbs=true; 
+            ref=ref.substring(1);
+        }
+        row = Integer.parseInt(ref)-1;
+    }
+    
+    public CellReference(int pRow, int pCol) {
+        this(pRow,pCol,false,false);
+    }
+    
+    public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
+        row=pRow;col=pCol;
+        rowAbs = pAbsRow;
+        colAbs=pAbsCol;
+        
+    }
+    
+    public int getRow(){return row;}
+    public int getCol(){return col;}
+    public boolean isRowAbsolute(){return rowAbs;}
+    public boolean isColAbsolute(){return colAbs;}
+    
+    /**
+     * takes in a column reference portion of a CellRef and converts it from
+     * ALPHA-26 number format to 0-based base 10.
+     */
+    private int convertColStringToNum(String ref) {
+        int len = ref.length();
+        int retval=0;
+        int pos = 0;
+        
+        for (int k = ref.length()-1; k > -1; k--) {
+            char thechar = ref.charAt(k);
+            if ( pos == 0) {
+                retval += (Character.getNumericValue(thechar)-9);
+            } else {
+                retval += (Character.getNumericValue(thechar)-9) * (pos * 26);
+            }
+            pos++;
+        }
+        return retval-1;
+    }
+    
+    
+    /**
+     * Seperates the row from the columns and returns an array.  Element in
+     * position one is the substring containing the columns still in ALPHA-26
+     * number format.
+     */
+    private String[] seperateRowColumns(String reference) {
+        int loc = 0; // location of first number
+        String retval[] = new String[2];
+        int length = reference.length();
+        
+        char[] chars = reference.toCharArray();
+        if (chars[loc]=='$') loc++;
+        for (; loc < chars.length; loc++) {
+            if (Character.isDigit(chars[loc]) || chars[loc] == '$') {
+                break;
+            }
+        }
+        
+        
+        retval[0] = reference.substring(0,loc);
+        retval[1] = reference.substring(loc);
+        return retval;
+    }
+    
+    /**
+     * takes in a 0-based base-10 column and returns a ALPHA-26 representation
+     */
+    private static String convertNumToColString(int col) {
+        String retval = null;
+        int mod = col % 26;
+        int div = col / 26;
+        char small=(char)(mod + 65);
+        char big = (char)(div + 64);
+        
+        if (div == 0) {
+            retval = ""+small;
+        } else {
+            retval = ""+big+""+small;
+        }
+        
+        return retval;
+    }
+    
+    
+    public String toString() {
+        StringBuffer retval = new StringBuffer();
+        retval.append( (colAbs)?"$":"");
+        retval.append( convertNumToColString(col));
+        retval.append((rowAbs)?"$":"");
+        retval.append(row+1);
+    
+    return retval.toString();
+    }
+}
index ca25c305fe3b58a73cca45e0edf76fd78b86cf5d..05ba984a28a3315e822e32ff63fe3a29ab6afc63 100644 (file)
@@ -698,7 +698,48 @@ extends TestCase {
     
     
     
-    
+    public void testAbsRefs() throws Exception {
+            File file = File.createTempFile("testFormulaAbsRef",".xls");
+            FileOutputStream out    = new FileOutputStream(file);
+            HSSFWorkbook     wb     = new HSSFWorkbook();
+            HSSFSheet        s      = wb.createSheet();
+            HSSFRow          r      = null;
+            HSSFCell         c      = null;
+
+
+            r = s.createRow((short) 0);
+
+            c = r.createCell((short) 0);
+            c.setCellFormula("A3+A2");
+            c=r.createCell( (short) 1);
+            c.setCellFormula("$A3+$A2");
+            c=r.createCell( (short) 2);
+            c.setCellFormula("A$3+A$2");
+            c=r.createCell( (short) 3);
+            c.setCellFormula("$A$3+$A$2");
+             c=r.createCell( (short) 4);
+            c.setCellFormula("SUM($A$3,$A$2)");
+
+            wb.write(out);
+            out.close();
+            assertTrue("file exists",file.exists());
+            
+            FileInputStream in = new FileInputStream(file);
+            wb = new HSSFWorkbook(in);
+            s = wb.getSheetAt(0);
+            r = s.getRow(0);
+            c = r.getCell((short)0);
+            assertTrue("A3+A2", ("A3+A2").equals(c.getCellFormula()));
+             c = r.getCell((short)1);
+            assertTrue("$A3+$A2", ("$A3+$A2").equals(c.getCellFormula()));
+             c = r.getCell((short)2);
+            assertTrue("A$3+A$2", ("A$3+A$2").equals(c.getCellFormula()));
+             c = r.getCell((short)3);
+            assertTrue("$A$3+$A$2", ("$A$3+$A$2").equals(c.getCellFormula()));
+            c = r.getCell((short)4);
+            assertTrue("SUM($A$3,$A$2)", ("SUM($A$3,$A$2)").equals(c.getCellFormula()));
+            in.close();
+    }
     public static void main(String [] args) {
         System.out
         .println("Testing org.apache.poi.hssf.usermodel.TestFormulas");
diff --git a/src/testcases/org/apache/poi/hssf/util/TestCellReference.java b/src/testcases/org/apache/poi/hssf/util/TestCellReference.java
new file mode 100644 (file)
index 0000000..5482ccd
--- /dev/null
@@ -0,0 +1,107 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.poi.hssf.util;
+
+
+import junit.framework.TestCase;
+
+
+public class TestCellReference extends TestCase {
+    public TestCellReference(String s) {
+        super(s);
+    }
+    
+    public void testAbsRef1(){
+        CellReference cf = new CellReference("$B$5");
+        assertTrue("row is 4",cf.getRow()==4);
+        assertTrue("col is 1",cf.getCol()==1);
+        assertTrue("row is abs",cf.isRowAbsolute());
+        assertTrue("col is abs",cf.isColAbsolute());
+        assertTrue("string is $B$5",cf.toString().equals("$B$5"));
+    }
+    
+    public void  testAbsRef2(){
+        CellReference cf = new CellReference(4,1,true,true);
+        assertTrue("row is 4",cf.getRow()==4);
+        assertTrue("col is 1",cf.getCol()==1);
+        assertTrue("row is abs",cf.isRowAbsolute());
+        assertTrue("col is abs",cf.isColAbsolute());
+        assertTrue("string is $B$5",cf.toString().equals("$B$5"));
+    }
+
+    public void  testAbsRef3(){
+        CellReference cf = new CellReference("B$5");
+        assertTrue("row is 4",cf.getRow()==4);
+        assertTrue("col is 1",cf.getCol()==1);
+        assertTrue("row is abs",cf.isRowAbsolute());
+        assertTrue("col is rel",!cf.isColAbsolute());
+        assertTrue("string is B$5",cf.toString().equals("B$5"));
+    }
+    
+    public void  testAbsRef4(){
+        CellReference cf = new CellReference(4,1,true,false);
+        assertTrue("row is 4",cf.getRow()==4);
+        assertTrue("col is 1",cf.getCol()==1);
+        assertTrue("row is abs",cf.isRowAbsolute());
+        assertTrue("col is rel",!cf.isColAbsolute());
+        assertTrue("string is B$5",cf.toString().equals("B$5"));
+    }
+
+    
+    public static void main(String [] args) {
+        System.out.println("Testing org.apache.poi.hssf.util.TestCellReference");
+        junit.textui.TestRunner.run(TestCellReference.class);
+    }
+    
+}
\ No newline at end of file