aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosh Micich <josh@apache.org>2008-11-19 02:01:58 +0000
committerJosh Micich <josh@apache.org>2008-11-19 02:01:58 +0000
commitb8329a9693a876ecaf40f25847b3f61908a46444 (patch)
tree3a114231cba80af3e915c03c11373cde89429240 /src
parent5f6daad05709b9aa9c884d16dbbd44f8a2012c1e (diff)
downloadpoi-b8329a9693a876ecaf40f25847b3f61908a46444.tar.gz
poi-b8329a9693a876ecaf40f25847b3f61908a46444.zip
Initial support for union operator in FormulaParser (fix for broken junits)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@718838 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java4
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java43
-rw-r--r--src/java/org/apache/poi/ss/formula/FormulaParser.java62
-rw-r--r--src/java/org/apache/poi/ss/formula/OperandClassTransformer.java8
-rw-r--r--src/java/org/apache/poi/ss/formula/ParseNode.java21
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java60
-rw-r--r--src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java33
-rw-r--r--src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java6
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java16
10 files changed, 203 insertions, 52 deletions
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
index d6f2b44aaf..ded679ada4 100644
--- a/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
+++ b/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
@@ -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());
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index cb56fa2798..3b47ea31ba 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -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() {
diff --git a/src/java/org/apache/poi/ss/formula/FormulaParser.java b/src/java/org/apache/poi/ss/formula/FormulaParser.java
index 1398399ff4..e3e8749101 100644
--- a/src/java/org/apache/poi/ss/formula/FormulaParser.java
+++ b/src/java/org/apache/poi/ss/formula/FormulaParser.java
@@ -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)
diff --git a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
index 91226bd53b..2bf8cadca6 100644
--- a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
+++ b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
@@ -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
diff --git a/src/java/org/apache/poi/ss/formula/ParseNode.java b/src/java/org/apache/poi/ss/formula/ParseNode.java
index 75685dee64..83e2b08175 100644
--- a/src/java/org/apache/poi/ss/formula/ParseNode.java
+++ b/src/java/org/apache/poi/ss/formula/ParseNode.java
@@ -17,8 +17,10 @@
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) {
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java
index ebdfdd7238..2be7cffa59 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java
@@ -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;
}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index efa2d1289d..63f9152b89 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -17,30 +17,59 @@
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) {
diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
index 53061a228b..b9e9315945 100644
--- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
+++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
@@ -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());
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java b/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java
index e01bc2ff76..7b9989e47b 100644
--- a/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java
+++ b/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java
@@ -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());
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
index d02ddd05f3..e7c24e68b2 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java
@@ -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);
}
/**