]> source.dussan.org Git - poi.git/commitdiff
Initial support for union operator in FormulaParser (fix for broken junits)
authorJosh Micich <josh@apache.org>
Wed, 19 Nov 2008 02:01:58 +0000 (02:01 +0000)
committerJosh Micich <josh@apache.org>
Wed, 19 Nov 2008 02:01:58 +0000 (02:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@718838 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/ss/formula/FormulaParser.java
src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
src/java/org/apache/poi/ss/formula/ParseNode.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java
src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java

index d6f2b44aaf1fd25228d9a54cc866ef312be794f2..ded679ada42bed8d2a80e419862df427425cdc5f 100644 (file)
@@ -60,9 +60,9 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
                CellReference firstCell = ar.getFirstCell();
                CellReference lastCell = ar.getLastCell();
                setFirstRow(firstCell.getRow());
-               setFirstColumn(firstCell.getCol());
+               setFirstColumn(firstCell.getCol() == -1 ? 0 : firstCell.getCol());
                setLastRow(lastCell.getRow());
-               setLastColumn(lastCell.getCol());
+               setLastColumn(lastCell.getCol() == -1 ? 0xFF : lastCell.getCol());
                setFirstColRelative(!firstCell.isColAbsolute());
                setLastColRelative(!lastCell.isColAbsolute());
                setFirstRowRelative(!firstCell.isRowAbsolute());
index cb56fa27986ec3112f033c6dee5c75034149fb76..3b47ea31ba77bbcbe390a055ad018013899166e6 100644 (file)
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.apache.poi.POIDocument;
 import org.apache.poi.ddf.EscherBSERecord;
@@ -78,10 +79,10 @@ import org.apache.poi.util.POILogger;
  * @author  Andrew C. Oliver (acoliver at apache dot org)
  * @author  Glen Stampoultzis (glens at apache.org)
  * @author  Shawn Laubach (slaubach at apache dot org)
- * @version 2.0-pre
+ *
  */
-public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook
-{
+public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook {
+    private static final Pattern COMMA_PATTERN = Pattern.compile(",");
     private static final int MAX_ROW = 0xFFFF;
     private static final short MAX_COLUMN = (short)0x00FF;
 
@@ -802,8 +803,8 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
     }
 
     public int getSheetIndexFromExternSheetIndex(int externSheetNumber) {
-       return workbook.getSheetIndexFromExternSheetIndex(externSheetNumber);
-       }
+        return workbook.getSheetIndexFromExternSheetIndex(externSheetNumber);
+    }
 
     private HSSFSheet[] getSheets() {
         HSSFSheet[] result = new HSSFSheet[_sheets.size()];
@@ -811,7 +812,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
         return result;
     }
 
-       /**
+    /**
      * Get the HSSFSheet object at the given index.
      * @param index of the sheet number (0-based physical & logical)
      * @return HSSFSheet at the provided index
@@ -1340,9 +1341,9 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
 
         return result;
     }
-       public NameRecord getNameRecord(int nameIndex) {
-               return getWorkbook().getNameRecord(nameIndex);
-       }
+    public NameRecord getNameRecord(int nameIndex) {
+        return getWorkbook().getNameRecord(nameIndex);
+    }
 
     /** gets the named range name
      * @param index the named range index (0 based)
@@ -1367,13 +1368,19 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
 
 
         if (name == null) {
-                       name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
-                       // adding one here because 0 indicates a global named region; doesn't make sense for print areas
-               }
+            name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
+            // adding one here because 0 indicates a global named region; doesn't make sense for print areas
+        }
+        String[] parts = COMMA_PATTERN.split(reference);
         StringBuffer sb = new StringBuffer(32);
-        SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
-        sb.append("!");
-        sb.append(reference);
+        for (int i = 0; i < parts.length; i++) {
+            if(i>0) {
+                sb.append(",");
+            }
+            SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
+            sb.append("!");
+            sb.append(parts[i]);
+        }
         name.setNameDefinition(HSSFFormulaParser.parse(sb.toString(), this));
     }
 
@@ -1409,8 +1416,8 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
         NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
         //adding one here because 0 indicates a global named region; doesn't make sense for print areas
         if (name == null) {
-                       return null;
-               }
+            return null;
+        }
  
         return HSSFFormulaParser.toFormulaString(this, name.getNameDefinition());
     }
@@ -1721,7 +1728,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
     }
     
     public CreationHelper getCreationHelper() {
-       return new HSSFCreationHelper(this);
+        return new HSSFCreationHelper(this);
     }
 
     private static byte[] newUID() {
index 1398399ff4b9361ece7fdc910c88947c82a9994d..e3e8749101ca51222efadba2933de3b8747b97e0 100644 (file)
@@ -39,6 +39,7 @@ import org.apache.poi.hssf.record.formula.GreaterThanPtg;
 import org.apache.poi.hssf.record.formula.IntPtg;
 import org.apache.poi.hssf.record.formula.LessEqualPtg;
 import org.apache.poi.hssf.record.formula.LessThanPtg;
+import org.apache.poi.hssf.record.formula.MemFuncPtg;
 import org.apache.poi.hssf.record.formula.MissingArgPtg;
 import org.apache.poi.hssf.record.formula.MultiplyPtg;
 import org.apache.poi.hssf.record.formula.NamePtg;
@@ -56,6 +57,7 @@ import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.record.formula.SubtractPtg;
 import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
 import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
+import org.apache.poi.hssf.record.formula.UnionPtg;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
@@ -370,6 +372,11 @@ public final class FormulaParser {
             // TODO - handle <book name> ! <named range name>
             int externIdx = getExternalSheetIndex(iden.getName());
             String secondIden = parseUnquotedIdentifier();
+            if (isRowOrCol(secondIden) && look == ':') {
+                GetChar();
+                String thirdIden = parseUnquotedIdentifier();
+                return new Area3DPtg(secondIden + ":" + thirdIden, externIdx);
+            }
             AreaReference areaRef = parseArea(secondIden);
             if (areaRef == null) {
                 return new Ref3DPtg(secondIden, externIdx);
@@ -418,6 +425,33 @@ public final class FormulaParser {
                     + name + "' is not a range as expected");
     }
 
+    private static boolean isRowOrCol(String str) {
+        int i=0;
+        if (str.charAt(i) == '$') {
+            i++;
+        }
+        if (IsDigit(str.charAt(i))) {
+            while (i<str.length()) {
+                if (!IsDigit(str.charAt(i))) {
+                    return false;
+                }
+                i++;
+            }
+            return true;
+        }
+        if (IsAlpha(str.charAt(i))) {
+            while (i<str.length()) {
+                if (!IsAlpha(str.charAt(i))) {
+                    return false;
+                }
+                i++;
+            }
+            return true;
+        }
+        
+        return false;
+    }
+
     private int getExternalSheetIndex(String name) {
         if (name.charAt(0) == '[') {
             // we have a sheet name qualified with workbook name e.g. '[MyData.xls]Sheet1'
@@ -578,7 +612,7 @@ public final class FormulaParser {
     /** get arguments to a function */
     private ParseNode[] Arguments() {
         //average 2 args per function
-        List temp = new ArrayList(2);
+        List<ParseNode> temp = new ArrayList<ParseNode>(2);
         SkipWhite();
         if(look == ')') {
             return ParseNode.EMPTY_ARRAY;
@@ -676,7 +710,7 @@ public final class FormulaParser {
 
 
     private ParseNode parseArray() {
-        List rowsData = new ArrayList();
+        List<Object[]> rowsData = new ArrayList<Object[]>();
         while(true) {
             Object[] singleRowData = parseArrayRow();
             rowsData.add(singleRowData);
@@ -707,7 +741,7 @@ public final class FormulaParser {
     }
 
     private Object[] parseArrayRow() {
-        List temp = new ArrayList();
+        List<Object> temp = new ArrayList<Object>();
         while (true) {
             temp.add(parseArrayItem());
             SkipWhite();
@@ -937,6 +971,26 @@ public final class FormulaParser {
             result = new ParseNode(operator, result, other);
         }
     }
+    private ParseNode unionExpression() {
+        ParseNode result = comparisonExpression();
+        boolean hasUnions = false;
+        while (true) {
+            SkipWhite();
+            switch(look) {
+                case ',':
+                    GetChar();
+                    hasUnions = true;
+                    ParseNode other = comparisonExpression();
+                    result = new ParseNode(UnionPtg.instance, result, other);
+                    continue;
+            }
+            if (hasUnions) {
+                MemFuncPtg memFuncPtg = new MemFuncPtg(result.getEncodedSize());
+                result = new ParseNode(memFuncPtg, result);
+            }
+            return result;
+        }
+    }
 
     private ParseNode comparisonExpression() {
         ParseNode result = concatExpression();
@@ -1040,7 +1094,7 @@ end;
     private void parse() {
         pointer=0;
         GetChar();
-        _rootNode = comparisonExpression();
+        _rootNode = unionExpression();
 
         if(pointer <= formulaLength) {
             String msg = "Unused input [" + formulaString.substring(pointer-1)
index 91226bd53b936e2a902f09e50da846c5fde99a98..2bf8cadca630be311c7a760b5711eab772afb81d 100644 (file)
@@ -19,9 +19,11 @@ package org.apache.poi.ss.formula;
 
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
 import org.apache.poi.hssf.record.formula.ControlPtg;
+import org.apache.poi.hssf.record.formula.MemFuncPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RangePtg;
+import org.apache.poi.hssf.record.formula.UnionPtg;
 import org.apache.poi.hssf.record.formula.ValueOperatorPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
 
 /**
  * This class performs 'operand class' transformation. Non-base tokens are classified into three 
@@ -98,7 +100,9 @@ final class OperandClassTransformer {
                        return;
                }
                
-               if (token instanceof ValueOperatorPtg || token instanceof ControlPtg) {
+               if (token instanceof ValueOperatorPtg || token instanceof ControlPtg
+                               || token instanceof MemFuncPtg
+                               || token instanceof UnionPtg) {
                        // Value Operator Ptgs and Control are base tokens, so token will be unchanged
                        // but any child nodes are processed according to desiredOperandClass and callerForceArrayFlag
                        
index 75685dee642526d88d138ebfa3a8d2889eedc7f6..83e2b08175384a7577393098fce649eb864d43e8 100644 (file)
 
 package org.apache.poi.ss.formula;
 
+import org.apache.poi.hssf.record.formula.ArrayPtg;
 import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.FuncVarPtg;
+import org.apache.poi.hssf.record.formula.MemFuncPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 /**
@@ -62,6 +64,13 @@ final class ParseNode {
        private int getTokenCount() {
                return _tokenCount;
        }
+       public int getEncodedSize() {
+               int result = _token instanceof ArrayPtg ? ArrayPtg.PLAIN_TOKEN_SIZE : _token.getSize();
+               for (int i = 0; i < _children.length; i++) {
+                       result += _children[i].getEncodedSize();
+               }
+               return result;
+       }
 
        /**
         * Collects the array of <tt>Ptg</tt> tokens for the specified tree.
@@ -72,14 +81,20 @@ final class ParseNode {
                return temp.getResult();
        }
        private void collectPtgs(TokenCollector temp) {
-               if (isIf(getToken())) {
+               if (isIf(_token)) {
                        collectIfPtgs(temp);
                        return;
                }
+               boolean isPreFixOperator = _token instanceof MemFuncPtg;
+               if (isPreFixOperator) {
+                       temp.add(_token);
+               }
                for (int i=0; i< getChildren().length; i++) {
                        getChildren()[i].collectPtgs(temp);
                }
-               temp.add(getToken());
+               if (!isPreFixOperator) {
+                       temp.add(_token);
+               }
        }
        /**
         * The IF() function gets marked up with two or three tAttr tokens.
@@ -136,7 +151,7 @@ final class ParseNode {
                        temp.setPlaceholder(skipAfterTrueParamIndex, attrSkipAfterTrue);
                }
                
-               temp.add(getToken());
+               temp.add(_token);
        }
 
        private static boolean isIf(Ptg token) {
index ebdfdd7238ab3144532cd0a9d2c9ba81a9ebbbc1..2be7cffa590a99667401398fa514c4976c133f83 100644 (file)
@@ -188,7 +188,7 @@ public final class XSSFName implements Name {
             ptgs = FormulaParser.parse(formulaText, fpb, FormulaType.CELL); // TODO - use type NAMEDRANGE
         } catch (RuntimeException e) {
             if (e.getClass().getName().startsWith(FormulaParser.class.getName())) {
-                throw new IllegalArgumentException("Unparsable formula '" + formulaText + "'");
+                throw new IllegalArgumentException("Unparsable formula '" + formulaText + "'", e);
             }
             throw e;
         }
index efa2d1289d669195e20b96fbc0a26f3cca9dfcd8..63f9152b89c7da67c1aeebcdba145aeea742dd0c 100644 (file)
 
 package org.apache.poi.xssf.usermodel;
 
-import java.io.*;
-import java.util.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
 import javax.xml.namespace.QName;
+
 import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.hssf.record.formula.SheetNameFormatter;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
 import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.PackageHelper;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.xssf.model.*;
-import org.apache.poi.POIXMLException;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlException;
 import org.openxml4j.exceptions.OpenXML4JException;
-import org.openxml4j.opc.*;
 import org.openxml4j.opc.Package;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+import org.openxml4j.opc.PackagePart;
+import org.openxml4j.opc.PackagePartName;
+import org.openxml4j.opc.PackageRelationship;
+import org.openxml4j.opc.PackageRelationshipTypes;
+import org.openxml4j.opc.PackagingURIHelper;
+import org.openxml4j.opc.TargetMode;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookView;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookViews;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
 
 /**
  * High level representation of a SpreadsheetML workbook.  This is the first object most users
@@ -48,6 +77,7 @@ import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelations
  * top level object for creating new sheets/etc.
  */
 public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<XSSFSheet> {
+    private static final Pattern COMMA_PATTERN = Pattern.compile(",");
 
     /**
      * Width of one character of the default font in pixels. Same for Calibry and Arial.
@@ -831,7 +861,17 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         }
         //short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
         //name.setExternSheetNumber(externSheetIndex);
-        name.setReference(reference);
+        String[] parts = COMMA_PATTERN.split(reference);
+        StringBuffer sb = new StringBuffer(32);
+        for (int i = 0; i < parts.length; i++) {
+            if(i>0) {
+                sb.append(",");
+            }
+            SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
+            sb.append("!");
+            sb.append(parts[i]);
+        }
+        name.setFormula(sb.toString());
     }
 
     /**
@@ -922,7 +962,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         CellReference colRef = new CellReference(sheetName, startR, startC, true, true);
         CellReference colRef2 = new CellReference(sheetName, endR, endC, true, true);
 
-        return "'" + sheetName + "'!$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1];
+        return "$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1];
     }
 
     private XSSFName getBuiltInName(String builtInCode, int sheetNumber) {
index 53061a228b5db183cca96c9a02cc977f92c82404..b9e9315945b9902929f3134c224a91c601536310 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.record.constant.ErrorConstant;
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
 import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.hssf.record.formula.Area3DPtg;
 import org.apache.poi.hssf.record.formula.AreaI;
 import org.apache.poi.hssf.record.formula.AreaPtg;
 import org.apache.poi.hssf.record.formula.ArrayPtg;
@@ -36,6 +37,7 @@ import org.apache.poi.hssf.record.formula.ErrPtg;
 import org.apache.poi.hssf.record.formula.FuncPtg;
 import org.apache.poi.hssf.record.formula.FuncVarPtg;
 import org.apache.poi.hssf.record.formula.IntPtg;
+import org.apache.poi.hssf.record.formula.MemFuncPtg;
 import org.apache.poi.hssf.record.formula.MissingArgPtg;
 import org.apache.poi.hssf.record.formula.MultiplyPtg;
 import org.apache.poi.hssf.record.formula.NamePtg;
@@ -49,6 +51,7 @@ import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.record.formula.SubtractPtg;
 import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
 import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
+import org.apache.poi.hssf.record.formula.UnionPtg;
 import org.apache.poi.hssf.usermodel.FormulaExtractor;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
@@ -57,6 +60,7 @@ import org.apache.poi.hssf.usermodel.HSSFName;
 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.ss.formula.FormulaParser;
 import org.apache.poi.ss.formula.FormulaParserTestHelper;
 
 /**
@@ -509,6 +513,10 @@ public final class TestFormulaParser extends TestCase {
 
        /* package */ static Ptg[] confirmTokenClasses(String formula, Class[] expectedClasses) {
                Ptg[] ptgs = parseFormula(formula);
+               confirmTokenClasses(ptgs, expectedClasses);
+               return ptgs;
+       }
+       private static void confirmTokenClasses(Ptg[] ptgs, Class[] expectedClasses) {
                assertEquals(expectedClasses.length, ptgs.length);
                for (int i = 0; i < expectedClasses.length; i++) {
                        if(expectedClasses[i] != ptgs[i].getClass()) {
@@ -517,7 +525,6 @@ public final class TestFormulaParser extends TestCase {
                                        + ptgs[i].getClass().getName() + ")");
                        }
                }
-               return ptgs;
        }
 
        public void testPower() {
@@ -818,7 +825,7 @@ public final class TestFormulaParser extends TestCase {
                HSSFWorkbook wb = new HSSFWorkbook();
                HSSFSheet sheet = wb.createSheet("Sheet1");
                HSSFName name = wb.createName();
-               name.setReference("Sheet1!B1");
+               name.setFormula("Sheet1!B1");
                name.setNameName("pfy1");
 
                Ptg[] ptgs;
@@ -944,4 +951,26 @@ public final class TestFormulaParser extends TestCase {
                assertEquals(expectedExternSheetIndex, ((Ref3DPtg)ptg0).getExternSheetIndex());
        }
        
+       public void testUnion() {
+               String formula = "Sheet1!$B$2:$C$3,OFFSET(Sheet1!$E$2:$E$4,1,Sheet1!$A$1),Sheet1!$D$6";
+               HSSFWorkbook wb = new HSSFWorkbook();
+               wb.createSheet("Sheet1");
+               Ptg[] ptgs = FormulaParser.parse(formula, HSSFEvaluationWorkbook.create(wb));
+               
+               Class[] expectedClasses = {
+                               // TODO - AttrPtg.class, // Excel prepends this
+                               MemFuncPtg.class,
+                               Area3DPtg.class,
+                               Area3DPtg.class,
+                               IntPtg.class,
+                               Ref3DPtg.class,
+                               FuncVarPtg.class,
+                               UnionPtg.class,
+                               Ref3DPtg.class,
+                               UnionPtg.class,
+               };
+               confirmTokenClasses(ptgs, expectedClasses);
+               MemFuncPtg mf = (MemFuncPtg)ptgs[0];
+               assertEquals(45, mf.getLenRefSubexpression());
+       }
 }
index e01bc2ff768621b06173720f752ba216661f8ba0..7b9989e47bde4794b0dd48e90724e49f46b06d29 100644 (file)
@@ -178,4 +178,10 @@ public final class TestCellRange extends TestCase
                assertEquals("isFullRowRange", isFullRow, cr.isFullRowRange());
                assertEquals("isFullColumnRange", isFullColumn, cr.isFullColumnRange());
        }
+       
+       public void testNumberOfCells() {
+               assertEquals(1, oneCell.getNumberOfCells());
+               assertEquals(100, box9x9.getNumberOfCells());
+               assertEquals(121, box10to20c.getNumberOfCells());
+       }
 }
index d02ddd05f3c01387c77bed4b6ccb248a6268ce4a..e7c24e68b201a4246aa17c6df37839de7e798153 100644 (file)
@@ -355,16 +355,12 @@ public final class TestNamedRange extends TestCase {
        public void testPrintAreaUnion(){
                HSSFWorkbook workbook = new HSSFWorkbook();
                workbook.createSheet("Test Print Area");
-               String sheetName = workbook.getSheetName(0);
-
-
-               if (false) { // TODO - fix formula parser to support unions
-                       String reference = "'" + sheetName + "'!$A$1:$B$1,'" + sheetName + "'!$D$1:$F$2";
-                       workbook.setPrintArea(0, reference);
-                       String retrievedPrintArea = workbook.getPrintArea(0);
-                       assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
-                       assertEquals(reference, retrievedPrintArea);
-               }
+               
+               String reference = "$A$1:$B$1,$D$1:$F$2";
+               workbook.setPrintArea(0, reference);
+               String retrievedPrintArea = workbook.getPrintArea(0);
+               assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
+               assertEquals("'Test Print Area'!$A$1:$B$1,'Test Print Area'!$D$1:$F$2", retrievedPrintArea);
        }
 
        /**