Facility to use Macro functions in formulas.

Major functionality upgrade, thanks to Paul Krause
Some of the Named Range and Area3d functionality can now be enhanced using the features of this patch.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/REL_2_BRANCH@353315 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Avik Sengupta 2003-08-23 19:40:05 +00:00
parent 2ad62ccff7
commit a1b3efa614
42 changed files with 301 additions and 168 deletions

View File

@ -77,7 +77,6 @@ import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.model.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.SheetReferences;
/**
* FormulaViewer - finds formulas in a BIFF8 file and attempts to read them/display
@ -144,7 +143,7 @@ public class FormulaViewer
StringBuffer buf = new StringBuffer();
if (token instanceof ExpPtg) return;
buf.append(name=((OperationPtg) token).toFormulaString((SheetReferences)null));
buf.append(name=((OperationPtg) token).toFormulaString((Workbook)null));
buf.append(sep);
switch (token.getPtgClass()) {
case Ptg.CLASS_REF :
@ -213,7 +212,7 @@ public class FormulaViewer
StringBuffer buf = new StringBuffer();
for (int i=0;i<numptgs;i++) {
token = (Ptg) tokens.get(i);
buf.append( token.toFormulaString((SheetReferences)null));
buf.append( token.toFormulaString((Workbook)null));
switch (token.getPtgClass()) {
case Ptg.CLASS_REF :
buf.append("(R)");
@ -233,7 +232,7 @@ public class FormulaViewer
private String composeFormula(FormulaRecord record)
{
return org.apache.poi.hssf.model.FormulaParser.toFormulaString((SheetReferences)null,record.getParsedExpression());
return org.apache.poi.hssf.model.FormulaParser.toFormulaString((Workbook)null,record.getParsedExpression());
}
/**

View File

@ -64,7 +64,6 @@ import java.util.List;
//import PTG's .. since we need everything, import *
import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.util.SheetReferences;
/**
@ -335,10 +334,14 @@ public class FormulaParser {
int numArgs = Arguments();
Match(')');
Ptg functionPtg = getFunction(name,(byte)numArgs);
AbstractFunctionPtg functionPtg = getFunction(name,(byte)numArgs);
tokens.add(functionPtg);
if (functionPtg.getName().equals("externalflag")) {
tokens.add(new NamePtg(name, this.book));
}
//remove what we just put in
this.functionTokens.remove(0);
}
@ -382,8 +385,8 @@ public class FormulaParser {
* @param numArgs
* @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this function
*/
private Ptg getFunction(String name,byte numArgs) {
Ptg retval = null;
private AbstractFunctionPtg getFunction(String name, byte numArgs) {
AbstractFunctionPtg retval = null;
if (name.equals("IF")) {
retval = new FuncVarPtg(AbstractFunctionPtg.ATTR_NAME, numArgs);
@ -795,69 +798,85 @@ end;
/**
* Convience method which takes in a list then passes it to the other toFormulaString
* signature.
* @param lptgs - list of ptgs, can be null
* @param book workbook for 3D and named references
* @param lptgs list of Ptg, can be null or empty
* @return a human readable String
*/
public static String toFormulaString(SheetReferences refs, List lptgs) {
public static String toFormulaString(Workbook book, List lptgs) {
String retval = null;
if (lptgs == null || lptgs.size() == 0) return "#NAME";
Ptg[] ptgs = new Ptg[lptgs.size()];
ptgs = (Ptg[])lptgs.toArray(ptgs);
retval = toFormulaString(refs, ptgs);
retval = toFormulaString(book, ptgs);
return retval;
}
/** Static method to convert an array of Ptgs in RPN order
* to a human readable string format in infix mode
* @param ptgs - array of ptgs, can be null or empty
/**
* Static method to convert an array of Ptgs in RPN order
* to a human readable string format in infix mode.
* @param book workbook for named and 3D references
* @param ptgs array of Ptg, can be null or empty
* @return a human readable String
*/
public static String toFormulaString(SheetReferences refs, Ptg[] ptgs) {
public static String toFormulaString(Workbook book, Ptg[] ptgs) {
if (ptgs == null || ptgs.length == 0) return "#NAME";
java.util.Stack stack = new java.util.Stack();
int numPtgs = ptgs.length;
OperationPtg o;
int numOperands;
String result=null;
String[] operands;
AttrPtg ifptg = null;
for (int i=0;i<numPtgs;i++) {
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
// do not have any operands. Skip them.
if (ptgs[i] instanceof OperationPtg && i>0) {
o = (OperationPtg) ptgs[i];
stack.push(ptgs[0].toFormulaString(book));
if (o instanceof AttrPtg && ((AttrPtg)o).isOptimizedIf()) {
ifptg=(AttrPtg)o;
} else {
for (int i = 1; i < ptgs.length; i++) {
if (! (ptgs[i] instanceof OperationPtg)) {
stack.push(ptgs[i].toFormulaString(book));
continue;
}
numOperands = o.getNumberOfOperands();
operands = new String[numOperands];
if (ptgs[i] instanceof AttrPtg && ((AttrPtg) ptgs[i]).isOptimizedIf()) {
ifptg = (AttrPtg) ptgs[i];
continue;
}
for (int j=0;j<numOperands;j++) {
operands[numOperands-j-1] = (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
final OperationPtg o = (OperationPtg) ptgs[i];
final String[] operands = new String[o.getNumberOfOperands()];
for (int j = operands.length; j > 0; j--) {
//TODO: catch stack underflow and throw parse exception.
operands[j - 1] = (String) stack.pop();
}
if ( (o instanceof AbstractFunctionPtg) &&
((AbstractFunctionPtg)o).getName().equals("specialflag") &&
ifptg != null
) {
stack.push(o.toFormulaString(operands));
if (!(o instanceof AbstractFunctionPtg)) continue;
final AbstractFunctionPtg f = (AbstractFunctionPtg) o;
final String fname = f.getName();
if (fname == null) continue;
if ((ifptg != null) && (fname.equals("specialflag"))) {
// this special case will be way different.
result = ifptg.toFormulaString(
new String[] {(o.toFormulaString(operands))}
);
ifptg = null;
} else {
result = o.toFormulaString(operands);
stack.push(ifptg.toFormulaString(new String[]{(String) stack.pop()}));
continue;
}
stack.push(result);
if (fname.equals("externalflag")) {
final String top = (String) stack.pop();
final int paren = top.indexOf('(');
final int comma = top.indexOf(',');
if (comma == -1) {
final int rparen = top.indexOf(')');
stack.push(top.substring(paren + 1, rparen) + "()");
}
} else {
stack.push(ptgs[i].toFormulaString(refs));
else {
stack.push(top.substring(paren + 1, comma) + '(' +
top.substring(comma + 1));
}
}
return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
}
// TODO: catch stack underflow and throw parse exception.
return (String) stack.pop();
}
/** Create a tree representation of the RPN token array
*used to run the class(RVA) change algo
*/
@ -890,11 +909,9 @@ end;
* Useful for testing
*/
public String toString() {
SheetReferences refs = null;
if (book!=null) book.getSheetReferences();
StringBuffer buf = new StringBuffer();
for (int i=0;i<tokens.size();i++) {
buf.append( ( (Ptg)tokens.get(i)).toFormulaString(refs));
buf.append( ( (Ptg)tokens.get(i)).toFormulaString(book));
buf.append(' ');
}
return buf.toString();

View File

@ -58,11 +58,11 @@ package org.apache.poi.hssf.record;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.util.RangeAddress;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
@ -127,6 +127,14 @@ public class NameRecord extends Record {
*/
public final static byte BUILTIN_SHEET_TITLE = (byte)12;
public static final short OPT_HIDDEN_NAME = (short) 0x0001;
public static final short OPT_FUNCTION_NAME = (short) 0x0002;
public static final short OPT_COMMAND_NAME = (short) 0x0004;
public static final short OPT_MACRO = (short) 0x0008;
public static final short OPT_COMPLEX = (short) 0x0010;
public static final short OPT_BUILTIN = (short) 0x0020;
public static final short OPT_BINDATA = (short) 0x1000;
private short field_1_option_flag;
private byte field_2_keyboard_shortcut;
@ -192,7 +200,7 @@ public class NameRecord extends Record {
{
this();
this.field_12_builtIn_name = builtin;
this.setOptionFlag((short)(this.getOptionFlag() | (short)0x20));
this.setOptionFlag((short)(this.getOptionFlag() | OPT_BUILTIN));
this.setNameTextLength((byte)1);
this.setEqualsToIndexToSheet(index); //the extern sheets are set through references
@ -252,13 +260,22 @@ public class NameRecord extends Record {
/**
* Convenience method to retrieve the index the name refers to.
* @see getEqualsToIndexToSheet()
* @see #getEqualsToIndexToSheet()
* @return short
*/
public short getIndexToSheet() {
return getEqualsToIndexToSheet();
}
/**
* @return function group
* @see FnGroupCountRecord
*/
public byte getFnGroup() {
int masked = field_1_option_flag & 0x0fc0;
return (byte) (masked >> 4);
}
public void setEqualsToIndexToSheet(short value)
{
field_6_equals_to_index_to_sheet = value;
@ -409,11 +426,47 @@ public class NameRecord extends Record {
return field_11_compressed_unicode_flag;
}
/**
* @return true if name is hidden
*/
public boolean isHiddenName() {
return (field_1_option_flag & OPT_HIDDEN_NAME) != 0;
}
/**
* @return true if name is a function
*/
public boolean isFunctionName() {
return (field_1_option_flag & OPT_FUNCTION_NAME) != 0;
}
/**
* @return true if name is a command
*/
public boolean isCommandName() {
return (field_1_option_flag & OPT_COMMAND_NAME) != 0;
}
/**
* @return true if function macro or command macro
*/
public boolean isMacro() {
return (field_1_option_flag & OPT_MACRO) != 0;
}
/**
* @return true if array formula or user defined
*/
public boolean isComplexFunction() {
return (field_1_option_flag & OPT_COMPLEX) != 0;
}
/**Convenience Function to determine if the name is a built-in name
*/
public boolean isBuiltInName()
{
return ((this.getOptionFlag() & (short)0x20) != 0);
return ((this.getOptionFlag() & OPT_BUILTIN) != 0);
}
@ -511,7 +564,7 @@ public class NameRecord extends Record {
data[18 + offset] = getCompressedUnicodeFlag();
/* temp: gjs
if ( ( field_1_option_flag & (short) 0x20 ) != 0 )
if (isBuiltInName())
{
LittleEndian.putShort( data, 2 + offset, (short) ( 16 + field_13_raw_name_definition.length ) );
@ -647,16 +700,16 @@ public class NameRecord extends Record {
/** gets the reference , the area only (range)
* @return area reference
*/
public String getAreaReference(SheetReferences refs){
public String getAreaReference(Workbook book){
if (field_13_name_definition == null) return "#REF!";
Ptg ptg = (Ptg) field_13_name_definition.peek();
String result = "";
if (ptg.getClass() == Area3DPtg.class){
result = ptg.toFormulaString(refs);
result = ptg.toFormulaString(book);
} else if (ptg.getClass() == Ref3DPtg.class){
result = ptg.toFormulaString(refs);
result = ptg.toFormulaString(book);
}
return result;
@ -727,7 +780,7 @@ public class NameRecord extends Record {
/*
temp: gjs
if ( ( field_1_option_flag & (short)0x20 ) != 0 ) {
if (isBuiltInName()) {
// DEBUG
// System.out.println( "Built-in name" );

View File

@ -54,9 +54,8 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.BinaryTree;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
import java.util.Stack;
/**
* This class provides the base functionality for Excel sheet functions
@ -69,7 +68,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
//constant used allow a ptgAttr to be mapped properly for its functionPtg
public static final String ATTR_NAME = "specialflag";
public static final short INDEX_EXTERNAL = 255;
private static BinaryTree map = produceHash();
protected static Object[][] functionData = produceFunctionData();
@ -104,7 +103,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
return lookupName(field_2_fnc_index);
}
public String toFormulaString(SheetReferences refs) {
public String toFormulaString(Workbook book) {
return getName();
}
@ -140,7 +139,9 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
}
protected short lookupIndex(String name) {
return (short)((Integer)map.getKeyForValue(name)).intValue();
Integer index = (Integer) map.getKeyForValue(name);
if (index != null) return index.shortValue();
return INDEX_EXTERNAL;
}
/**
@ -389,6 +390,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
dmap.put(new Integer(252),"FREQUENCY");
dmap.put(new Integer(253),"ADDTOOLBAR");
dmap.put(new Integer(254),"DELETETOOLBAR");
dmap.put(new Integer(255),"externalflag");
dmap.put(new Integer(256),"RESETTOOLBAR");
dmap.put(new Integer(257),"EVALUATE");
dmap.put(new Integer(258),"GETTOOLBAR");

View File

@ -62,7 +62,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Addition operator PTG the "+" binomial operator. If you need more
@ -113,7 +113,7 @@ public class AddPtg
}
/** Implementation of method from Ptg */
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "+";
}

View File

@ -291,8 +291,9 @@ public class Area3DPtg extends Ptg
}
public String toFormulaString( SheetReferences refs )
public String toFormulaString(Workbook book)
{
SheetReferences refs = book == null ? null : book.getSheetReferences();
StringBuffer retval = new StringBuffer();
if ( refs != null )
{
@ -352,4 +353,3 @@ public class Area3DPtg extends Ptg
}

View File

@ -65,7 +65,7 @@ import org.apache.poi.util.BitField;
import org.apache.poi.hssf.util.AreaReference;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Specifies a rectangular area of cells A1:A4 for instance.
@ -305,7 +305,7 @@ public class AreaPtg
field_4_last_column = column;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return (new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative())).toString() + ":" +
(new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();

View File

@ -60,7 +60,7 @@
*/
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.BitField;
@ -207,11 +207,11 @@ public class AttrPtg
if(space.isSet(field_1_options)) {
return operands[ 0 ];
} else if (optiIf.isSet(field_1_options)) {
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] +")";
return toFormulaString((Workbook)null) + "(" + operands[ 0 ] +")";
} else if (optGoto.isSet(field_1_options)) {
return toFormulaString((SheetReferences)null) + operands[0]; //goto isn't a real formula element should not show up
return toFormulaString((Workbook)null) + operands[0]; //goto isn't a real formula element should not show up
} else {
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] + ")";
return toFormulaString((Workbook)null) + "(" + operands[ 0 ] + ")";
}
}
@ -226,7 +226,7 @@ public class AttrPtg
return -1;
}
public String toFormulaString(SheetReferences refs) {
public String toFormulaString(Workbook book) {
if(semiVolatile.isSet(field_1_options)) {
return "ATTR(semiVolatile)";
}

View File

@ -60,7 +60,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Boolean (boolean)
@ -114,7 +114,7 @@ public class BoolPtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return field_1_value ? "TRUE" : "FALSE";
}

View File

@ -62,7 +62,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -108,7 +108,7 @@ public class ConcatPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return CONCAT;
}

View File

@ -62,7 +62,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* This PTG implements the standard binomial divide "/"
@ -108,7 +108,7 @@ public class DividePtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "/";
}
@ -117,7 +117,7 @@ public class DividePtg
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -62,7 +62,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -107,7 +107,7 @@ public class EqualPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "=";
}
@ -117,7 +117,7 @@ public class EqualPtg
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -60,7 +60,7 @@
*/
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -102,7 +102,7 @@ public class ExpPtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "NO IDEA SHARED FORMULA EXP PTG";
}

View File

@ -54,7 +54,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* PTG class to implement greater or equal to
@ -98,7 +98,7 @@ public class GreaterEqualPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return ">=";
}
@ -108,7 +108,7 @@ public class GreaterEqualPtg
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -61,7 +61,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Greater than operator PTG ">"
@ -133,7 +133,7 @@ public class GreaterThanPtg
* Implementation of method from Ptg
* @param refs the Sheet References
*/
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return this.GREATERTHAN;
}
@ -171,5 +171,3 @@ public class GreaterThanPtg
return new GreaterThanPtg();
}
}

View File

@ -61,7 +61,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Integer (short intger)
@ -116,7 +116,7 @@ public class IntPtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "" + getValue();
}

View File

@ -53,7 +53,7 @@
*/
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
@ -99,7 +99,7 @@ public class LessEqualPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "<=";
}
@ -109,7 +109,7 @@ public class LessEqualPtg
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -63,7 +63,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
//POI
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Less than operator PTG "<". The SID is taken from the
@ -142,7 +142,7 @@ public class LessThanPtg
* Implementation of method from Ptg
* @param refs the Sheet References
*/
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return this.LESSTHAN;
}
@ -180,6 +180,3 @@ public class LessThanPtg
}
}

View File

@ -61,7 +61,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -118,7 +118,7 @@ public class MemErrPtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "ERR#";
}

View File

@ -60,7 +60,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* @author Glen Stampoultzis (glens at apache.org)
@ -96,7 +96,7 @@ public class MemFuncPtg extends ControlPtg
LittleEndian.putShort( array, offset + 1, (short)field_1_len_ref_subexpression );
}
public String toFormulaString( SheetReferences refs )
public String toFormulaString(Workbook book)
{
return "";
}

View File

@ -54,7 +54,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Missing Function Arguments
@ -91,7 +91,7 @@ public class MissingArgPtg
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return " ";
}
@ -103,5 +103,3 @@ public class MissingArgPtg
}
}

View File

@ -61,7 +61,7 @@
package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Implements the standard mathmatical multiplication - *
@ -114,7 +114,7 @@ public class MultiplyPtg
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "*";
}
@ -123,9 +123,9 @@ public class MultiplyPtg
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString((SheetReferences)null));
buffer.append(operands[ 0 ].toFormulaString((Workbook)null));
buffer.append("*");
buffer.append(operands[ 1 ].toFormulaString((SheetReferences)null));
buffer.append(operands[ 1 ].toFormulaString((Workbook)null));
return buffer.toString();
}
@ -133,7 +133,7 @@ public class MultiplyPtg
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -61,7 +61,8 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord;
/**
*
@ -85,9 +86,22 @@ public class NamePtg
/** Creates new NamePtg */
public NamePtg(String name)
public NamePtg(String name, Workbook book)
{
//TODO
final short n = (short) (book.getNumNames() + 1);
NameRecord rec;
for (short i = 1; i < n; i++) {
rec = book.getNameRecord(i - 1);
if (name.equals(rec.getNameText())) {
field_1_label_index = i;
return;
}
}
rec = new NameRecord();
rec.setNameText(name);
rec.setNameTextLength((byte) name.length());
book.addName(rec);
field_1_label_index = n;
}
/** Creates new NamePtg */
@ -113,12 +127,13 @@ public class NamePtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "NAMED RANGE";
NameRecord rec = book.getNameRecord(field_1_label_index - 1);
return rec.getNameText();
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
public byte getDefaultOperandClass() {return Ptg.CLASS_REF;}
public Object clone() {
NamePtg ptg = new NamePtg();

View File

@ -61,7 +61,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -113,7 +113,7 @@ public class NameXPtg extends Ptg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "NO IDEA - NAME";
}

View File

@ -56,7 +56,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Ptg class to implement not equal
@ -101,7 +101,7 @@ public class NotEqualPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "<>";
}
@ -111,7 +111,7 @@ public class NotEqualPtg
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -55,7 +55,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Number
* Stores a floating point value in a formula
@ -113,7 +113,7 @@ public class NumberPtg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "" + getValue();
}
@ -125,4 +125,3 @@ public class NumberPtg
return ptg;
}
}

View File

@ -57,7 +57,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* While formula tokens are stored in RPN order and thus do not need parenthesis for
@ -107,7 +107,7 @@ public class ParenthesisPtg
return 1;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "()";
}
@ -124,4 +124,3 @@ public class ParenthesisPtg
}
}

View File

@ -62,7 +62,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -108,7 +108,7 @@ public class PowerPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "^";
}
@ -118,7 +118,7 @@ public class PowerPtg
buffer.append(operands[ 0 ]);
buffer.append(toFormulaString((SheetReferences)null));
buffer.append(toFormulaString((Workbook)null));
buffer.append(operands[ 1 ]);
return buffer.toString();
}

View File

@ -63,7 +63,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import java.util.ArrayList;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -347,7 +347,7 @@ public abstract class Ptg
/**
* return a string representation of this token alone
*/
public abstract String toFormulaString(SheetReferences refs);
public abstract String toFormulaString(Workbook book);
/**
* dump a debug representation (hexdump) to a string
*/

View File

@ -61,6 +61,7 @@ import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.util.RangeAddress;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.util.BitField;
import org.apache.poi.hssf.model.Workbook;
@ -193,8 +194,9 @@ public class Ref3DPtg extends Ptg {
}
public String toFormulaString(SheetReferences refs) {
public String toFormulaString(Workbook book) {
StringBuffer retval = new StringBuffer();
SheetReferences refs = book == null ? null : book.getSheetReferences();
if (refs != null) {
retval.append(refs.getSheetName((int)this.field_1_index_extern_sheet));
retval.append('!');

View File

@ -64,7 +64,7 @@ import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.BitField;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* ReferencePtg - handles references (such as A1, A2, IA4)
@ -179,7 +179,7 @@ public class ReferencePtg extends Ptg
return SIZE;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
//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();

View File

@ -56,7 +56,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.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.util.StringUtil;
/**
@ -145,7 +145,7 @@ public class StringPtg
}
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "\""+getValue()+"\"";
}
@ -162,4 +162,3 @@ public class StringPtg
}
}

View File

@ -61,7 +61,7 @@
package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -105,7 +105,7 @@ public class SubtractPtg
return 2;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "-";
}

View File

@ -56,7 +56,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Unary Plus operator
@ -105,7 +105,7 @@ public class UnaryMinusPtg extends OperationPtg
}
/** Implementation of method from Ptg */
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "+";
}

View File

@ -56,7 +56,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* Unary Plus operator
@ -105,7 +105,7 @@ public class UnaryPlusPtg extends OperationPtg
}
/** Implementation of method from Ptg */
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "+";
}

View File

@ -54,7 +54,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
* @author Glen Stampoultzis (glens at apache.org)
@ -95,7 +95,7 @@ public class UnionPtg extends OperationPtg
}
/** Implementation of method from Ptg */
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return ",";
}

View File

@ -60,7 +60,7 @@
*/
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.model.Workbook;
/**
*
@ -94,7 +94,7 @@ public class UnknownPtg
return size;
}
public String toFormulaString(SheetReferences refs)
public String toFormulaString(Workbook book)
{
return "UNKNOWN";
}

View File

@ -726,8 +726,7 @@ public class HSSFCell
public String getCellFormula() {
//Workbook.currentBook=book;
SheetReferences refs = book.getSheetReferences();
String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
String retval = FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
//Workbook.currentBook=null;
return retval;
}

View File

@ -123,8 +123,7 @@ public class HSSFName {
public String getReference() {
String result;
SheetReferences refs = book.getSheetReferences();
result = name.getAreaReference(refs);
result = name.getAreaReference(book);
return result;
}
@ -167,4 +166,3 @@ public class HSSFName {
}
}

View File

@ -898,7 +898,7 @@ public class HSSFWorkbook
if (name == null) return null;
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
return name.getAreaReference(workbook.getSheetReferences());
return name.getAreaReference(workbook);
}
/**

View File

@ -56,7 +56,6 @@ package org.apache.poi.hssf.model;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.util.SheetReferences;
/**
* Test the low level formula parser functionality. High level tests are to
@ -145,7 +144,7 @@ public class TestFormulaParser extends TestCase {
assertEquals(true, flag.getValue());
assertEquals("Y", y.getValue());
assertEquals("N", n.getValue());
assertEquals("IF", funif.toFormulaString(new SheetReferences()));
assertEquals("IF", funif.toFormulaString((Workbook) null));
assertTrue("Goto ptg exists", goto1.isGoto());
}
@ -285,6 +284,19 @@ public class TestFormulaParser extends TestCase {
}
public void testMacroFunction() {
Workbook w = new Workbook();
FormulaParser fp = new FormulaParser("FOO()", w);
fp.parse();
Ptg[] ptg = fp.getRPNPtg();
AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[0];
assertEquals("externalflag", tfunc.getName());
NamePtg tname = (NamePtg) ptg[1];
assertEquals("FOO", tname.toFormulaString(w));
}
public static void main(String [] args) {
System.out.println("Testing org.apache.poi.hssf.record.formula.FormulaParser");
junit.textui.TestRunner.run(TestFormulaParser.class);

View File

@ -744,7 +744,7 @@ extends TestCase {
}
public void testSheetFunctions()
throws java.io.IOException
throws IOException
{
String filename = System.getProperty("HSSF.testdata.path");
@ -818,7 +818,7 @@ extends TestCase {
}
public void testStringFormulas()
throws java.io.IOException
throws IOException
{
String readFilename = System.getProperty("HSSF.testdata.path");
@ -852,7 +852,7 @@ extends TestCase {
public void testLogicalFormulas()
throws java.io.IOException
throws IOException
{
File file = File.createTempFile("testLogicalFormula",".xls");
@ -880,7 +880,7 @@ extends TestCase {
}
public void testDateFormulas()
throws java.io.IOException
throws IOException
{
String readFilename = System.getProperty("HSSF.testdata.path");
@ -918,7 +918,7 @@ extends TestCase {
public void testIfFormulas()
throws java.io.IOException
throws IOException
{
String readFilename = System.getProperty("HSSF.testdata.path");
@ -1008,7 +1008,7 @@ extends TestCase {
}
public void testSumIf()
throws java.io.IOException
throws IOException
{
String readFilename = System.getProperty("HSSF.testdata.path");
String function ="SUMIF(A1:A5,\">4000\",B1:B5)";
@ -1060,6 +1060,52 @@ extends TestCase {
assertTrue("sumif == 0 bytes", file.length() > 0);
}
public void testSquareMacro() throws IOException {
File dir = new File(System.getProperty("HSSF.testdata.path"));
File xls = new File(dir, "SquareMacro.xls");
FileInputStream in = new FileInputStream(xls);
HSSFWorkbook w;
try {
w = new HSSFWorkbook(in);
} finally {
in.close();
}
HSSFSheet s0 = w.getSheetAt(0);
HSSFRow[] r = {s0.getRow(0), s0.getRow(1)};
HSSFCell a1 = r[0].getCell((short) 0);
assertEquals("square(1)", a1.getCellFormula());
assertEquals(1d, a1.getNumericCellValue(), 1e-9);
HSSFCell a2 = r[1].getCell((short) 0);
assertEquals("square(2)", a2.getCellFormula());
assertEquals(4d, a2.getNumericCellValue(), 1e-9);
HSSFCell b1 = r[0].getCell((short) 1);
assertEquals("IF(TRUE,square(1))", b1.getCellFormula());
assertEquals(1d, b1.getNumericCellValue(), 1e-9);
HSSFCell b2 = r[1].getCell((short) 1);
assertEquals("IF(TRUE,square(2))", b2.getCellFormula());
assertEquals(4d, b2.getNumericCellValue(), 1e-9);
HSSFCell c1 = r[0].getCell((short) 2);
assertEquals("square(square(1))", c1.getCellFormula());
assertEquals(1d, c1.getNumericCellValue(), 1e-9);
HSSFCell c2 = r[1].getCell((short) 2);
assertEquals("square(square(2))", c2.getCellFormula());
assertEquals(16d, c2.getNumericCellValue(), 1e-9);
HSSFCell d1 = r[0].getCell((short) 3);
assertEquals("square(one())", d1.getCellFormula());
assertEquals(1d, d1.getNumericCellValue(), 1e-9);
HSSFCell d2 = r[1].getCell((short) 3);
assertEquals("square(two())", d2.getCellFormula());
assertEquals(4d, d2.getNumericCellValue(), 1e-9);
}
public static void main(String [] args) {
System.out
.println("Testing org.apache.poi.hssf.usermodel.TestFormulas");