More formula enhancements, particularly for fixed args tFunc 0x21/41/61. Also try not to bomb on unknown Ptg
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352668 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3899a5ee12
commit
e346cb4473
@ -88,6 +88,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
public class FormulaViewer
|
||||
{
|
||||
private String file;
|
||||
private boolean list=false;
|
||||
|
||||
/** Creates new FormulaViewer */
|
||||
|
||||
@ -118,10 +119,67 @@ public class FormulaViewer
|
||||
|
||||
if (record.getSid() == FormulaRecord.sid)
|
||||
{
|
||||
parseFormulaRecord(( FormulaRecord ) record);
|
||||
if (list) {
|
||||
listFormula((FormulaRecord) record);
|
||||
}else {
|
||||
parseFormulaRecord(( FormulaRecord ) record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void listFormula(FormulaRecord record) {
|
||||
String sep="~";
|
||||
List tokens= record.getParsedExpression();
|
||||
int numptgs = record.getNumberOfExpressionTokens();
|
||||
Ptg token = null;
|
||||
String name,numArg;
|
||||
if (tokens != null) {
|
||||
token = (Ptg) tokens.get(numptgs-1);
|
||||
if (token instanceof FuncPtg) {
|
||||
numArg = String.valueOf(numptgs-1);
|
||||
} else { numArg = String.valueOf(-1);}
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
buf.append(name=((OperationPtg) token).toFormulaString());
|
||||
buf.append(sep);
|
||||
switch (token.getPtgClass()) {
|
||||
case Ptg.CLASS_REF :
|
||||
buf.append("REF");
|
||||
break;
|
||||
case Ptg.CLASS_VALUE :
|
||||
buf.append("VALUE");
|
||||
break;
|
||||
case Ptg.CLASS_ARRAY :
|
||||
buf.append("ARRAY");
|
||||
break;
|
||||
}
|
||||
|
||||
buf.append(sep);
|
||||
if (numptgs>1) {
|
||||
token = (Ptg) tokens.get(numptgs-2);
|
||||
switch (token.getPtgClass()) {
|
||||
case Ptg.CLASS_REF :
|
||||
buf.append("REF");
|
||||
break;
|
||||
case Ptg.CLASS_VALUE :
|
||||
buf.append("VALUE");
|
||||
break;
|
||||
case Ptg.CLASS_ARRAY :
|
||||
buf.append("ARRAY");
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
buf.append("VALUE");
|
||||
}
|
||||
buf.append(sep);
|
||||
buf.append(numArg);
|
||||
System.out.println(buf.toString());
|
||||
} else {
|
||||
System.out.println("#NAME");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method parseFormulaRecord
|
||||
@ -142,23 +200,36 @@ public class FormulaViewer
|
||||
+ record.getNumberOfExpressionTokens());
|
||||
System.out.println(", options = " + record.getOptions());
|
||||
System.out.println("RPN List = "+formulaString(record));
|
||||
System.out.println("Formula text = "+ composeForumla(record));
|
||||
System.out.println("Formula text = "+ composeFormula(record));
|
||||
}
|
||||
|
||||
private String formulaString(FormulaRecord record) {
|
||||
StringBuffer formula = new StringBuffer("=");
|
||||
int numptgs = record.getNumberOfExpressionTokens();
|
||||
List tokens = record.getParsedExpression();
|
||||
Ptg token;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i=0;i<numptgs;i++) {
|
||||
buf.append( ( (Ptg)tokens.get(i)).toFormulaString());
|
||||
token = (Ptg) tokens.get(i);
|
||||
buf.append( token.toFormulaString());
|
||||
switch (token.getPtgClass()) {
|
||||
case Ptg.CLASS_REF :
|
||||
buf.append("(R)");
|
||||
break;
|
||||
case Ptg.CLASS_VALUE :
|
||||
buf.append("(V)");
|
||||
break;
|
||||
case Ptg.CLASS_ARRAY :
|
||||
buf.append("(A)");
|
||||
break;
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
private String composeForumla(FormulaRecord record)
|
||||
private String composeFormula(FormulaRecord record)
|
||||
{
|
||||
return FormulaParser.toFormulaString(record.getParsedExpression());
|
||||
}
|
||||
@ -175,6 +246,10 @@ public class FormulaViewer
|
||||
{
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public void setList(boolean list) {
|
||||
this.list=list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method main
|
||||
@ -187,12 +262,23 @@ public class FormulaViewer
|
||||
|
||||
public static void main(String args[])
|
||||
{
|
||||
if ((args == null) || (args.length != 1)
|
||||
if ((args == null) || (args.length >2 )
|
||||
|| args[ 0 ].equals("--help"))
|
||||
{
|
||||
System.out.println(
|
||||
"FormulaViewer .8 proof that the devil lies in the details (or just in BIFF8 files in general)");
|
||||
System.out.println("usage: Give me a big fat file name");
|
||||
} else if (args[0].equals("--listFunctions")) { // undocumented attribute to research functions!~
|
||||
try {
|
||||
FormulaViewer viewer = new FormulaViewer();
|
||||
viewer.setFile(args[1]);
|
||||
viewer.setList(true);
|
||||
viewer.run();
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Whoops!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.record.formula.*;
|
||||
|
||||
/**
|
||||
* Formula Record - This is not really supported in this release. Its here for future use.<P>
|
||||
* Formula Record.
|
||||
* REFERENCE: PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @version 2.0-pre
|
||||
@ -134,7 +134,7 @@ public class FormulaRecord
|
||||
|
||||
protected void fillFields(byte [] data, short size, int offset)
|
||||
{
|
||||
if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
|
||||
try {
|
||||
//field_1_row = LittleEndian.getShort(data, 0 + offset);
|
||||
field_1_row = LittleEndian.getUShort(data, 0 + offset);
|
||||
field_2_column = LittleEndian.getShort(data, 2 + offset);
|
||||
@ -146,11 +146,15 @@ public class FormulaRecord
|
||||
field_8_parsed_expr = getParsedExpressionTokens(data, size,
|
||||
offset);
|
||||
|
||||
} else {
|
||||
} catch (java.lang.UnsupportedOperationException uoe) {
|
||||
field_8_parsed_expr = null;
|
||||
all_data = new byte[size+4];
|
||||
LittleEndian.putShort(all_data,0,sid);
|
||||
LittleEndian.putShort(all_data,2,size);
|
||||
System.arraycopy(data,offset,all_data,4,size);
|
||||
System.err.println("[WARNING] Unknown Ptg "
|
||||
+ uoe.getMessage()
|
||||
+ " at cell ("+field_1_row+","+field_2_column+")");
|
||||
}
|
||||
|
||||
}
|
||||
@ -164,7 +168,6 @@ public class FormulaRecord
|
||||
while (pos < size)
|
||||
{
|
||||
Ptg ptg = Ptg.createPtg(data, pos);
|
||||
|
||||
pos += ptg.getSize();
|
||||
stack.push(ptg);
|
||||
}
|
||||
@ -307,13 +310,20 @@ public class FormulaRecord
|
||||
|
||||
public int getNumberOfExpressionTokens()
|
||||
{
|
||||
return field_8_parsed_expr.size();
|
||||
if (this.field_8_parsed_expr == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return field_8_parsed_expr.size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the stack as a list
|
||||
*
|
||||
* @return list of tokens (casts stack to a list and returns it!)
|
||||
* this method can return null is we are unable to create Ptgs from
|
||||
* existing excel file
|
||||
* callers should check for null!
|
||||
*/
|
||||
|
||||
public List getParsedExpression()
|
||||
@ -351,7 +361,7 @@ public class FormulaRecord
|
||||
|
||||
public int serialize(int offset, byte [] data)
|
||||
{
|
||||
if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
|
||||
if (this.field_8_parsed_expr != null) {
|
||||
int ptgSize = getTotalPtgSize();
|
||||
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
@ -378,7 +388,7 @@ public class FormulaRecord
|
||||
{
|
||||
int retval =0;
|
||||
|
||||
if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
|
||||
if (this.field_8_parsed_expr != null) {
|
||||
retval = getTotalPtgSize() + 26;
|
||||
} else {
|
||||
retval =all_data.length;
|
||||
|
@ -0,0 +1,538 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.BinaryTree;
|
||||
/**
|
||||
* This class provides the base functionality for Excel sheet functions
|
||||
* There are two kinds of function Ptgs - tFunc and tFuncVar
|
||||
* Therefore, this class will have ONLY two subclasses
|
||||
* @author Avik Sengupta
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
*/
|
||||
public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
|
||||
private final static int SIZE = 4;
|
||||
|
||||
private static BinaryTree map = produceHash();
|
||||
protected static Object[][] functionData = produceFunctionData();
|
||||
protected byte returnClass;
|
||||
protected byte[] paramClass;
|
||||
|
||||
protected byte field_1_num_args;
|
||||
protected short field_2_fnc_index;
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer
|
||||
.append("<FunctionPtg>").append("\n")
|
||||
.append(" field_1_num_args=").append(field_1_num_args).append("\n")
|
||||
.append(" name =").append(lookupName(field_2_fnc_index)).append("\n")
|
||||
.append(" field_2_fnc_index=").append(field_2_fnc_index).append("\n")
|
||||
.append("</FunctionPtg>");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public short getFunctionIndex() {
|
||||
return field_2_fnc_index;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return lookupName(field_2_fnc_index);
|
||||
}
|
||||
|
||||
public String toFormulaString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public String toFormulaString(String[] operands) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(getName()+"(");
|
||||
if (operands.length >0) {
|
||||
for (int i=0;i<operands.length;i++) {
|
||||
buf.append(operands[i]);
|
||||
buf.append(',');
|
||||
}
|
||||
buf.deleteCharAt(buf.length()-1);
|
||||
}
|
||||
buf.append(")");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public abstract void writeBytes(byte[] array, int offset);
|
||||
|
||||
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
private String lookupName(short index) {
|
||||
return ((String)map.get(new Integer(index)));
|
||||
}
|
||||
|
||||
protected short lookupIndex(String name) {
|
||||
return (short)((Integer)map.getKeyForValue(name)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the function table hashmap
|
||||
*/
|
||||
private static BinaryTree produceHash() {
|
||||
BinaryTree dmap = new BinaryTree();
|
||||
|
||||
dmap.put(new Integer(0),"COUNT");
|
||||
dmap.put(new Integer(2),"ISNA");
|
||||
dmap.put(new Integer(3),"ISERROR");
|
||||
dmap.put(new Integer(4),"SUM");
|
||||
dmap.put(new Integer(5),"AVERAGE");
|
||||
dmap.put(new Integer(6),"MIN");
|
||||
dmap.put(new Integer(7),"MAX");
|
||||
dmap.put(new Integer(8),"ROW");
|
||||
dmap.put(new Integer(9),"COLUMN");
|
||||
dmap.put(new Integer(10),"NA");
|
||||
dmap.put(new Integer(11),"NPV");
|
||||
dmap.put(new Integer(12),"STDEV");
|
||||
dmap.put(new Integer(13),"DOLLAR");
|
||||
dmap.put(new Integer(14),"FIXED");
|
||||
dmap.put(new Integer(15),"SIN");
|
||||
dmap.put(new Integer(16),"COS");
|
||||
dmap.put(new Integer(17),"TAN");
|
||||
dmap.put(new Integer(18),"ATAN");
|
||||
dmap.put(new Integer(19),"PI");
|
||||
dmap.put(new Integer(20),"SQRT");
|
||||
dmap.put(new Integer(21),"EXP");
|
||||
dmap.put(new Integer(22),"LN");
|
||||
dmap.put(new Integer(23),"LOG10");
|
||||
dmap.put(new Integer(24),"ABS");
|
||||
dmap.put(new Integer(25),"INT");
|
||||
dmap.put(new Integer(26),"SIGN");
|
||||
dmap.put(new Integer(27),"ROUND");
|
||||
dmap.put(new Integer(28),"LOOKUP");
|
||||
dmap.put(new Integer(29),"INDEX");
|
||||
dmap.put(new Integer(30),"REPT");
|
||||
dmap.put(new Integer(31),"MID");
|
||||
dmap.put(new Integer(32),"LEN");
|
||||
dmap.put(new Integer(33),"VALUE");
|
||||
dmap.put(new Integer(34),"TRUE");
|
||||
dmap.put(new Integer(35),"FALSE");
|
||||
dmap.put(new Integer(36),"AND");
|
||||
dmap.put(new Integer(37),"OR");
|
||||
dmap.put(new Integer(38),"NOT");
|
||||
dmap.put(new Integer(39),"MOD");
|
||||
dmap.put(new Integer(40),"DCOUNT");
|
||||
dmap.put(new Integer(41),"DSUM");
|
||||
dmap.put(new Integer(42),"DAVERAGE");
|
||||
dmap.put(new Integer(43),"DMIN");
|
||||
dmap.put(new Integer(44),"DMAX");
|
||||
dmap.put(new Integer(45),"DSTDEV");
|
||||
dmap.put(new Integer(46),"VAR");
|
||||
dmap.put(new Integer(47),"DVAR");
|
||||
dmap.put(new Integer(48),"TEXT");
|
||||
dmap.put(new Integer(49),"LINEST");
|
||||
dmap.put(new Integer(50),"TREND");
|
||||
dmap.put(new Integer(51),"LOGEST");
|
||||
dmap.put(new Integer(52),"GROWTH");
|
||||
dmap.put(new Integer(53),"GOTO");
|
||||
dmap.put(new Integer(54),"HALT");
|
||||
dmap.put(new Integer(56),"PV");
|
||||
dmap.put(new Integer(57),"FV");
|
||||
dmap.put(new Integer(58),"NPER");
|
||||
dmap.put(new Integer(59),"PMT");
|
||||
dmap.put(new Integer(60),"RATE");
|
||||
dmap.put(new Integer(61),"MIRR");
|
||||
dmap.put(new Integer(62),"IRR");
|
||||
dmap.put(new Integer(63),"RAND");
|
||||
dmap.put(new Integer(64),"MATCH");
|
||||
dmap.put(new Integer(65),"DATE");
|
||||
dmap.put(new Integer(66),"TIME");
|
||||
dmap.put(new Integer(67),"DAY");
|
||||
dmap.put(new Integer(68),"MONTH");
|
||||
dmap.put(new Integer(69),"YEAR");
|
||||
dmap.put(new Integer(70),"WEEKDAY");
|
||||
dmap.put(new Integer(71),"HOUR");
|
||||
dmap.put(new Integer(72),"MINUTE");
|
||||
dmap.put(new Integer(73),"SECOND");
|
||||
dmap.put(new Integer(74),"NOW");
|
||||
dmap.put(new Integer(75),"AREAS");
|
||||
dmap.put(new Integer(76),"ROWS");
|
||||
dmap.put(new Integer(77),"COLUMNS");
|
||||
dmap.put(new Integer(78),"OFFSET");
|
||||
dmap.put(new Integer(79),"ABSREF");
|
||||
dmap.put(new Integer(80),"RELREF");
|
||||
dmap.put(new Integer(81),"ARGUMENT");
|
||||
dmap.put(new Integer(82),"SEARCH");
|
||||
dmap.put(new Integer(83),"TRANSPOSE");
|
||||
dmap.put(new Integer(84),"ERROR");
|
||||
dmap.put(new Integer(85),"STEP");
|
||||
dmap.put(new Integer(86),"TYPE");
|
||||
dmap.put(new Integer(87),"ECHO");
|
||||
dmap.put(new Integer(88),"SETNAME");
|
||||
dmap.put(new Integer(89),"CALLER");
|
||||
dmap.put(new Integer(90),"DEREF");
|
||||
dmap.put(new Integer(91),"WINDOWS");
|
||||
dmap.put(new Integer(92),"SERIES");
|
||||
dmap.put(new Integer(93),"DOCUMENTS");
|
||||
dmap.put(new Integer(94),"ACTIVECELL");
|
||||
dmap.put(new Integer(95),"SELECTION");
|
||||
dmap.put(new Integer(96),"RESULT");
|
||||
dmap.put(new Integer(97),"ATAN2");
|
||||
dmap.put(new Integer(98),"ASIN");
|
||||
dmap.put(new Integer(99),"ACOS");
|
||||
dmap.put(new Integer(100),"CHOOSE");
|
||||
dmap.put(new Integer(101),"HLOOKUP");
|
||||
dmap.put(new Integer(102),"VLOOKUP");
|
||||
dmap.put(new Integer(103),"LINKS");
|
||||
dmap.put(new Integer(104),"INPUT");
|
||||
dmap.put(new Integer(105),"ISREF");
|
||||
dmap.put(new Integer(106),"GETFORMULA");
|
||||
dmap.put(new Integer(107),"GETNAME");
|
||||
dmap.put(new Integer(108),"SETVALUE");
|
||||
dmap.put(new Integer(109),"LOG");
|
||||
dmap.put(new Integer(110),"EXEC");
|
||||
dmap.put(new Integer(111),"CHAR");
|
||||
dmap.put(new Integer(112),"LOWER");
|
||||
dmap.put(new Integer(113),"UPPER");
|
||||
dmap.put(new Integer(114),"PROPER");
|
||||
dmap.put(new Integer(115),"LEFT");
|
||||
dmap.put(new Integer(116),"RIGHT");
|
||||
dmap.put(new Integer(117),"EXACT");
|
||||
dmap.put(new Integer(118),"TRIM");
|
||||
dmap.put(new Integer(119),"REPLACE");
|
||||
dmap.put(new Integer(120),"SUBSTITUTE");
|
||||
dmap.put(new Integer(121),"CODE");
|
||||
dmap.put(new Integer(122),"NAMES");
|
||||
dmap.put(new Integer(123),"DIRECTORY");
|
||||
dmap.put(new Integer(124),"FIND");
|
||||
dmap.put(new Integer(125),"CELL");
|
||||
dmap.put(new Integer(126),"ISERR");
|
||||
dmap.put(new Integer(127),"ISTEXT");
|
||||
dmap.put(new Integer(128),"ISNUMBER");
|
||||
dmap.put(new Integer(129),"ISBLANK");
|
||||
dmap.put(new Integer(130),"T");
|
||||
dmap.put(new Integer(131),"N");
|
||||
dmap.put(new Integer(132),"FOPEN");
|
||||
dmap.put(new Integer(133),"FCLOSE");
|
||||
dmap.put(new Integer(134),"FSIZE");
|
||||
dmap.put(new Integer(135),"FREADLN");
|
||||
dmap.put(new Integer(136),"FREAD");
|
||||
dmap.put(new Integer(137),"FWRITELN");
|
||||
dmap.put(new Integer(138),"FWRITE");
|
||||
dmap.put(new Integer(139),"FPOS");
|
||||
dmap.put(new Integer(140),"DATEVALUE");
|
||||
dmap.put(new Integer(141),"TIMEVALUE");
|
||||
dmap.put(new Integer(142),"SLN");
|
||||
dmap.put(new Integer(143),"SYD");
|
||||
dmap.put(new Integer(144),"DDB");
|
||||
dmap.put(new Integer(145),"GETDEF");
|
||||
dmap.put(new Integer(146),"REFTEXT");
|
||||
dmap.put(new Integer(147),"TEXTREF");
|
||||
dmap.put(new Integer(148),"INDIRECT");
|
||||
dmap.put(new Integer(149),"REGISTER");
|
||||
dmap.put(new Integer(150),"CALL");
|
||||
dmap.put(new Integer(151),"ADDBAR");
|
||||
dmap.put(new Integer(152),"ADDMENU");
|
||||
dmap.put(new Integer(153),"ADDCOMMAND");
|
||||
dmap.put(new Integer(154),"ENABLECOMMAND");
|
||||
dmap.put(new Integer(155),"CHECKCOMMAND");
|
||||
dmap.put(new Integer(156),"RENAMECOMMAND");
|
||||
dmap.put(new Integer(157),"SHOWBAR");
|
||||
dmap.put(new Integer(158),"DELETEMENU");
|
||||
dmap.put(new Integer(159),"DELETECOMMAND");
|
||||
dmap.put(new Integer(160),"GETCHARTITEM");
|
||||
dmap.put(new Integer(161),"DIALOGBOX");
|
||||
dmap.put(new Integer(162),"CLEAN");
|
||||
dmap.put(new Integer(163),"MDETERM");
|
||||
dmap.put(new Integer(164),"MINVERSE");
|
||||
dmap.put(new Integer(165),"MMULT");
|
||||
dmap.put(new Integer(166),"FILES");
|
||||
dmap.put(new Integer(167),"IPMT");
|
||||
dmap.put(new Integer(168),"PPMT");
|
||||
dmap.put(new Integer(169),"COUNTA");
|
||||
dmap.put(new Integer(170),"CANCELKEY");
|
||||
dmap.put(new Integer(175),"INITIATE");
|
||||
dmap.put(new Integer(176),"REQUEST");
|
||||
dmap.put(new Integer(177),"POKE");
|
||||
dmap.put(new Integer(178),"EXECUTE");
|
||||
dmap.put(new Integer(179),"TERMINATE");
|
||||
dmap.put(new Integer(180),"RESTART");
|
||||
dmap.put(new Integer(181),"HELP");
|
||||
dmap.put(new Integer(182),"GETBAR");
|
||||
dmap.put(new Integer(183),"PRODUCT");
|
||||
dmap.put(new Integer(184),"FACT");
|
||||
dmap.put(new Integer(185),"GETCELL");
|
||||
dmap.put(new Integer(186),"GETWORKSPACE");
|
||||
dmap.put(new Integer(187),"GETWINDOW");
|
||||
dmap.put(new Integer(188),"GETDOCUMENT");
|
||||
dmap.put(new Integer(189),"DPRODUCT");
|
||||
dmap.put(new Integer(190),"ISNONTEXT");
|
||||
dmap.put(new Integer(191),"GETNOTE");
|
||||
dmap.put(new Integer(192),"NOTE");
|
||||
dmap.put(new Integer(193),"STDEVP");
|
||||
dmap.put(new Integer(194),"VARP");
|
||||
dmap.put(new Integer(195),"DSTDEVP");
|
||||
dmap.put(new Integer(196),"DVARP");
|
||||
dmap.put(new Integer(197),"TRUNC");
|
||||
dmap.put(new Integer(198),"ISLOGICAL");
|
||||
dmap.put(new Integer(199),"DCOUNTA");
|
||||
dmap.put(new Integer(200),"DELETEBAR");
|
||||
dmap.put(new Integer(201),"UNREGISTER");
|
||||
dmap.put(new Integer(204),"USDOLLAR");
|
||||
dmap.put(new Integer(205),"FINDB");
|
||||
dmap.put(new Integer(206),"SEARCHB");
|
||||
dmap.put(new Integer(207),"REPLACEB");
|
||||
dmap.put(new Integer(208),"LEFTB");
|
||||
dmap.put(new Integer(209),"RIGHTB");
|
||||
dmap.put(new Integer(210),"MIDB");
|
||||
dmap.put(new Integer(211),"LENB");
|
||||
dmap.put(new Integer(212),"ROUNDUP");
|
||||
dmap.put(new Integer(213),"ROUNDDOWN");
|
||||
dmap.put(new Integer(214),"ASC");
|
||||
dmap.put(new Integer(215),"DBCS");
|
||||
dmap.put(new Integer(216),"RANK");
|
||||
dmap.put(new Integer(219),"ADDRESS");
|
||||
dmap.put(new Integer(220),"DAYS360");
|
||||
dmap.put(new Integer(221),"TODAY");
|
||||
dmap.put(new Integer(222),"VDB");
|
||||
dmap.put(new Integer(227),"MEDIAN");
|
||||
dmap.put(new Integer(228),"SUMPRODUCT");
|
||||
dmap.put(new Integer(229),"SINH");
|
||||
dmap.put(new Integer(230),"COSH");
|
||||
dmap.put(new Integer(231),"TANH");
|
||||
dmap.put(new Integer(232),"ASINH");
|
||||
dmap.put(new Integer(233),"ACOSH");
|
||||
dmap.put(new Integer(234),"ATANH");
|
||||
dmap.put(new Integer(235),"DGET");
|
||||
dmap.put(new Integer(236),"CREATEOBJECT");
|
||||
dmap.put(new Integer(237),"VOLATILE");
|
||||
dmap.put(new Integer(238),"LASTERROR");
|
||||
dmap.put(new Integer(239),"CUSTOMUNDO");
|
||||
dmap.put(new Integer(240),"CUSTOMREPEAT");
|
||||
dmap.put(new Integer(241),"FORMULACONVERT");
|
||||
dmap.put(new Integer(242),"GETLINKINFO");
|
||||
dmap.put(new Integer(243),"TEXTBOX");
|
||||
dmap.put(new Integer(244),"INFO");
|
||||
dmap.put(new Integer(245),"GROUP");
|
||||
dmap.put(new Integer(246),"GETOBJECT");
|
||||
dmap.put(new Integer(247),"DB");
|
||||
dmap.put(new Integer(248),"PAUSE");
|
||||
dmap.put(new Integer(250),"RESUME");
|
||||
dmap.put(new Integer(252),"FREQUENCY");
|
||||
dmap.put(new Integer(253),"ADDTOOLBAR");
|
||||
dmap.put(new Integer(254),"DELETETOOLBAR");
|
||||
dmap.put(new Integer(256),"RESETTOOLBAR");
|
||||
dmap.put(new Integer(257),"EVALUATE");
|
||||
dmap.put(new Integer(258),"GETTOOLBAR");
|
||||
dmap.put(new Integer(259),"GETTOOL");
|
||||
dmap.put(new Integer(260),"SPELLINGCHECK");
|
||||
dmap.put(new Integer(261),"ERRORTYPE");
|
||||
dmap.put(new Integer(262),"APPTITLE");
|
||||
dmap.put(new Integer(263),"WINDOWTITLE");
|
||||
dmap.put(new Integer(264),"SAVETOOLBAR");
|
||||
dmap.put(new Integer(265),"ENABLETOOL");
|
||||
dmap.put(new Integer(266),"PRESSTOOL");
|
||||
dmap.put(new Integer(267),"REGISTERID");
|
||||
dmap.put(new Integer(268),"GETWORKBOOK");
|
||||
dmap.put(new Integer(269),"AVEDEV");
|
||||
dmap.put(new Integer(270),"BETADIST");
|
||||
dmap.put(new Integer(271),"GAMMALN");
|
||||
dmap.put(new Integer(272),"BETAINV");
|
||||
dmap.put(new Integer(273),"BINOMDIST");
|
||||
dmap.put(new Integer(274),"CHIDIST");
|
||||
dmap.put(new Integer(275),"CHIINV");
|
||||
dmap.put(new Integer(276),"COMBIN");
|
||||
dmap.put(new Integer(277),"CONFIDENCE");
|
||||
dmap.put(new Integer(278),"CRITBINOM");
|
||||
dmap.put(new Integer(279),"EVEN");
|
||||
dmap.put(new Integer(280),"EXPONDIST");
|
||||
dmap.put(new Integer(281),"FDIST");
|
||||
dmap.put(new Integer(282),"FINV");
|
||||
dmap.put(new Integer(283),"FISHER");
|
||||
dmap.put(new Integer(284),"FISHERINV");
|
||||
dmap.put(new Integer(285),"FLOOR");
|
||||
dmap.put(new Integer(286),"GAMMADIST");
|
||||
dmap.put(new Integer(287),"GAMMAINV");
|
||||
dmap.put(new Integer(288),"CEILING");
|
||||
dmap.put(new Integer(289),"HYPGEOMDIST");
|
||||
dmap.put(new Integer(290),"LOGNORMDIST");
|
||||
dmap.put(new Integer(291),"LOGINV");
|
||||
dmap.put(new Integer(292),"NEGBINOMDIST");
|
||||
dmap.put(new Integer(293),"NORMDIST");
|
||||
dmap.put(new Integer(294),"NORMSDIST");
|
||||
dmap.put(new Integer(295),"NORMINV");
|
||||
dmap.put(new Integer(296),"NORMSINV");
|
||||
dmap.put(new Integer(297),"STANDARDIZE");
|
||||
dmap.put(new Integer(298),"ODD");
|
||||
dmap.put(new Integer(299),"PERMUT");
|
||||
dmap.put(new Integer(300),"POISSON");
|
||||
dmap.put(new Integer(301),"TDIST");
|
||||
dmap.put(new Integer(302),"WEIBULL");
|
||||
dmap.put(new Integer(303),"SUMXMY2");
|
||||
dmap.put(new Integer(304),"SUMX2MY2");
|
||||
dmap.put(new Integer(305),"SUMX2PY2");
|
||||
dmap.put(new Integer(306),"CHITEST");
|
||||
dmap.put(new Integer(307),"CORREL");
|
||||
dmap.put(new Integer(308),"COVAR");
|
||||
dmap.put(new Integer(309),"FORECAST");
|
||||
dmap.put(new Integer(310),"FTEST");
|
||||
dmap.put(new Integer(311),"INTERCEPT");
|
||||
dmap.put(new Integer(312),"PEARSON");
|
||||
dmap.put(new Integer(313),"RSQ");
|
||||
dmap.put(new Integer(314),"STEYX");
|
||||
dmap.put(new Integer(315),"SLOPE");
|
||||
dmap.put(new Integer(316),"TTEST");
|
||||
dmap.put(new Integer(317),"PROB");
|
||||
dmap.put(new Integer(318),"DEVSQ");
|
||||
dmap.put(new Integer(319),"GEOMEAN");
|
||||
dmap.put(new Integer(320),"HARMEAN");
|
||||
dmap.put(new Integer(321),"SUMSQ");
|
||||
dmap.put(new Integer(322),"KURT");
|
||||
dmap.put(new Integer(323),"SKEW");
|
||||
dmap.put(new Integer(324),"ZTEST");
|
||||
dmap.put(new Integer(325),"LARGE");
|
||||
dmap.put(new Integer(326),"SMALL");
|
||||
dmap.put(new Integer(327),"QUARTILE");
|
||||
dmap.put(new Integer(328),"PERCENTILE");
|
||||
dmap.put(new Integer(329),"PERCENTRANK");
|
||||
dmap.put(new Integer(330),"MODE");
|
||||
dmap.put(new Integer(331),"TRIMMEAN");
|
||||
dmap.put(new Integer(332),"TINV");
|
||||
dmap.put(new Integer(334),"MOVIECOMMAND");
|
||||
dmap.put(new Integer(335),"GETMOVIE");
|
||||
dmap.put(new Integer(336),"CONCATENATE");
|
||||
dmap.put(new Integer(337),"POWER");
|
||||
dmap.put(new Integer(338),"PIVOTADDDATA");
|
||||
dmap.put(new Integer(339),"GETPIVOTTABLE");
|
||||
dmap.put(new Integer(340),"GETPIVOTFIELD");
|
||||
dmap.put(new Integer(341),"GETPIVOTITEM");
|
||||
dmap.put(new Integer(342),"RADIANS");
|
||||
dmap.put(new Integer(343),"DEGREES");
|
||||
dmap.put(new Integer(344),"SUBTOTAL");
|
||||
dmap.put(new Integer(345),"SUMIF");
|
||||
dmap.put(new Integer(346),"COUNTIF");
|
||||
dmap.put(new Integer(347),"COUNTBLANK");
|
||||
dmap.put(new Integer(348),"SCENARIOGET");
|
||||
dmap.put(new Integer(349),"OPTIONSLISTSGET");
|
||||
dmap.put(new Integer(350),"ISPMT");
|
||||
dmap.put(new Integer(351),"DATEDIF");
|
||||
dmap.put(new Integer(352),"DATESTRING");
|
||||
dmap.put(new Integer(353),"NUMBERSTRING");
|
||||
dmap.put(new Integer(354),"ROMAN");
|
||||
dmap.put(new Integer(355),"OPENDIALOG");
|
||||
dmap.put(new Integer(356),"SAVEDIALOG");
|
||||
dmap.put(new Integer(357),"VIEWGET");
|
||||
dmap.put(new Integer(358),"GETPIVOTDATA");
|
||||
dmap.put(new Integer(359),"HYPERLINK");
|
||||
dmap.put(new Integer(360),"PHONETIC");
|
||||
dmap.put(new Integer(361),"AVERAGEA");
|
||||
dmap.put(new Integer(362),"MAXA");
|
||||
dmap.put(new Integer(363),"MINA");
|
||||
dmap.put(new Integer(364),"STDEVPA");
|
||||
dmap.put(new Integer(365),"VARPA");
|
||||
dmap.put(new Integer(366),"STDEVA");
|
||||
dmap.put(new Integer(367),"VARA");
|
||||
|
||||
return dmap;
|
||||
}
|
||||
|
||||
private static Object[][] produceFunctionData() {
|
||||
Object [][] functionData = new Object[368][3];
|
||||
|
||||
functionData[0][0]=new Byte(Ptg.CLASS_VALUE);functionData[0][1]=new byte[] {Ptg.CLASS_REF};functionData[0][2]=new Integer(-1);
|
||||
functionData[2][0]=new Byte(Ptg.CLASS_VALUE);functionData[2][1]=new byte[] {Ptg.CLASS_VALUE};functionData[2][2]=new Integer(1);
|
||||
functionData[3][0]=new Byte(Ptg.CLASS_VALUE);functionData[3][1]=new byte[] {Ptg.CLASS_VALUE};functionData[3][2]=new Integer(1);
|
||||
functionData[4][0]=new Byte(Ptg.CLASS_REF);functionData[4][1]=new byte[] {Ptg.CLASS_REF};functionData[4][2]=new Integer(-1);
|
||||
functionData[5][0]=new Byte(Ptg.CLASS_VALUE);functionData[5][1]=new byte[] {Ptg.CLASS_REF};functionData[5][2]=new Integer(-1);
|
||||
functionData[6][0]=new Byte(Ptg.CLASS_VALUE);functionData[6][1]=new byte[] {Ptg.CLASS_REF};functionData[6][2]=new Integer(-1);
|
||||
functionData[7][0]=new Byte(Ptg.CLASS_VALUE);functionData[7][1]=new byte[] {Ptg.CLASS_REF};functionData[7][2]=new Integer(-1);
|
||||
functionData[8][0]=new Byte(Ptg.CLASS_VALUE);functionData[8][1]=new byte[] {Ptg.CLASS_REF};functionData[8][2]=new Integer(-1);
|
||||
functionData[9][0]=new Byte(Ptg.CLASS_VALUE);functionData[9][1]=new byte[] {Ptg.CLASS_REF};functionData[9][2]=new Integer(-1);
|
||||
functionData[10][0]=new Byte(Ptg.CLASS_VALUE);functionData[10][1]=new byte[] {Ptg.CLASS_VALUE};functionData[10][2]=new Integer(0);
|
||||
functionData[11][0]=new Byte(Ptg.CLASS_VALUE);functionData[11][1]=new byte[] {Ptg.CLASS_REF};functionData[11][2]=new Integer(-1);
|
||||
functionData[12][0]=new Byte(Ptg.CLASS_VALUE);functionData[12][1]=new byte[] {Ptg.CLASS_REF};functionData[12][2]=new Integer(-1);
|
||||
functionData[13][0]=new Byte(Ptg.CLASS_VALUE);functionData[13][1]=new byte[] {Ptg.CLASS_VALUE};functionData[13][2]=new Integer(-1);
|
||||
functionData[14][0]=new Byte(Ptg.CLASS_VALUE);functionData[14][1]=new byte[] {Ptg.CLASS_VALUE};functionData[14][2]=new Integer(-1);
|
||||
functionData[15][0]=new Byte(Ptg.CLASS_VALUE);functionData[15][1]=new byte[] {Ptg.CLASS_VALUE};functionData[15][2]=new Integer(1);
|
||||
functionData[16][0]=new Byte(Ptg.CLASS_VALUE);functionData[16][1]=new byte[] {Ptg.CLASS_VALUE};functionData[16][2]=new Integer(1);
|
||||
functionData[17][0]=new Byte(Ptg.CLASS_VALUE);functionData[17][1]=new byte[] {Ptg.CLASS_VALUE};functionData[17][2]=new Integer(1);
|
||||
functionData[18][0]=new Byte(Ptg.CLASS_VALUE);functionData[18][1]=new byte[] {Ptg.CLASS_VALUE};functionData[18][2]=new Integer(1);
|
||||
functionData[19][0]=new Byte(Ptg.CLASS_VALUE);functionData[19][1]=new byte[] {Ptg.CLASS_VALUE};functionData[19][2]=new Integer(0);
|
||||
functionData[20][0]=new Byte(Ptg.CLASS_VALUE);functionData[20][1]=new byte[] {Ptg.CLASS_VALUE};functionData[20][2]=new Integer(1);
|
||||
functionData[21][0]=new Byte(Ptg.CLASS_VALUE);functionData[21][1]=new byte[] {Ptg.CLASS_VALUE};functionData[21][2]=new Integer(1);
|
||||
functionData[22][0]=new Byte(Ptg.CLASS_VALUE);functionData[22][1]=new byte[] {Ptg.CLASS_VALUE};functionData[22][2]=new Integer(1);
|
||||
functionData[23][0]=new Byte(Ptg.CLASS_VALUE);functionData[23][1]=new byte[] {Ptg.CLASS_VALUE};functionData[23][2]=new Integer(1);
|
||||
functionData[24][0]=new Byte(Ptg.CLASS_VALUE);functionData[24][1]=new byte[] {Ptg.CLASS_VALUE};functionData[24][2]=new Integer(1);
|
||||
functionData[25][0]=new Byte(Ptg.CLASS_VALUE);functionData[25][1]=new byte[] {Ptg.CLASS_VALUE};functionData[25][2]=new Integer(1);
|
||||
functionData[26][0]=new Byte(Ptg.CLASS_VALUE);functionData[26][1]=new byte[] {Ptg.CLASS_VALUE};functionData[26][2]=new Integer(1);
|
||||
functionData[27][0]=new Byte(Ptg.CLASS_VALUE);functionData[27][1]=new byte[] {Ptg.CLASS_VALUE};functionData[27][2]=new Integer(2);
|
||||
functionData[28][0]=new Byte(Ptg.CLASS_VALUE);functionData[28][1]=new byte[] {Ptg.CLASS_REF};functionData[28][2]=new Integer(-1);
|
||||
functionData[29][0]=new Byte(Ptg.CLASS_VALUE);functionData[29][1]=new byte[] {Ptg.CLASS_REF};functionData[29][2]=new Integer(-1);
|
||||
functionData[30][0]=new Byte(Ptg.CLASS_VALUE);functionData[30][1]=new byte[] {Ptg.CLASS_VALUE};functionData[30][2]=new Integer(2);
|
||||
functionData[31][0]=new Byte(Ptg.CLASS_VALUE);functionData[31][1]=new byte[] {Ptg.CLASS_VALUE};functionData[31][2]=new Integer(3);
|
||||
functionData[32][0]=new Byte(Ptg.CLASS_VALUE);functionData[32][1]=new byte[] {Ptg.CLASS_VALUE};functionData[32][2]=new Integer(1);
|
||||
functionData[33][0]=new Byte(Ptg.CLASS_VALUE);functionData[33][1]=new byte[] {Ptg.CLASS_VALUE};functionData[33][2]=new Integer(1);
|
||||
functionData[34][0]=new Byte(Ptg.CLASS_VALUE);functionData[34][1]=new byte[] {Ptg.CLASS_VALUE};functionData[34][2]=new Integer(1);
|
||||
functionData[35][0]=new Byte(Ptg.CLASS_VALUE);functionData[35][1]=new byte[] {Ptg.CLASS_VALUE};functionData[35][2]=new Integer(1);
|
||||
functionData[36][0]=new Byte(Ptg.CLASS_VALUE);functionData[36][1]=new byte[] {Ptg.CLASS_REF};functionData[36][2]=new Integer(-1);
|
||||
functionData[37][0]=new Byte(Ptg.CLASS_VALUE);functionData[37][1]=new byte[] {Ptg.CLASS_REF};functionData[37][2]=new Integer(-1);
|
||||
functionData[38][0]=new Byte(Ptg.CLASS_VALUE);functionData[38][1]=new byte[] {Ptg.CLASS_VALUE};functionData[38][2]=new Integer(1);
|
||||
functionData[39][0]=new Byte(Ptg.CLASS_VALUE);functionData[39][1]=new byte[] {Ptg.CLASS_VALUE};functionData[39][2]=new Integer(2);
|
||||
functionData[40][0]=new Byte(Ptg.CLASS_VALUE);functionData[40][1]=new byte[] {Ptg.CLASS_REF};functionData[40][2]=new Integer(3);
|
||||
functionData[41][0]=new Byte(Ptg.CLASS_VALUE);functionData[41][1]=new byte[] {Ptg.CLASS_REF};functionData[41][2]=new Integer(3);
|
||||
functionData[42][0]=new Byte(Ptg.CLASS_VALUE);functionData[42][1]=new byte[] {Ptg.CLASS_REF};functionData[42][2]=new Integer(3);
|
||||
functionData[43][0]=new Byte(Ptg.CLASS_VALUE);functionData[43][1]=new byte[] {Ptg.CLASS_REF};functionData[43][2]=new Integer(3);
|
||||
functionData[44][0]=new Byte(Ptg.CLASS_VALUE);functionData[44][1]=new byte[] {Ptg.CLASS_REF};functionData[44][2]=new Integer(3);
|
||||
functionData[45][0]=new Byte(Ptg.CLASS_VALUE);functionData[45][1]=new byte[] {Ptg.CLASS_REF};functionData[45][2]=new Integer(3);
|
||||
functionData[46][0]=new Byte(Ptg.CLASS_VALUE);functionData[46][1]=new byte[] {Ptg.CLASS_REF};functionData[46][2]=new Integer(-1);
|
||||
functionData[47][0]=new Byte(Ptg.CLASS_VALUE);functionData[47][1]=new byte[] {Ptg.CLASS_REF};functionData[47][2]=new Integer(3);
|
||||
functionData[48][0]=new Byte(Ptg.CLASS_VALUE);functionData[48][1]=new byte[] {Ptg.CLASS_VALUE};functionData[48][2]=new Integer(2);
|
||||
functionData[49][0]=new Byte(Ptg.CLASS_VALUE);functionData[49][1]=new byte[] {Ptg.CLASS_REF};functionData[49][2]=new Integer(-1);
|
||||
functionData[50][0]=new Byte(Ptg.CLASS_VALUE);functionData[50][1]=new byte[] {Ptg.CLASS_REF};functionData[50][2]=new Integer(-1);
|
||||
functionData[51][0]=new Byte(Ptg.CLASS_VALUE);functionData[51][1]=new byte[] {Ptg.CLASS_REF};functionData[51][2]=new Integer(-1);
|
||||
functionData[52][0]=new Byte(Ptg.CLASS_VALUE);functionData[52][1]=new byte[] {Ptg.CLASS_REF};functionData[52][2]=new Integer(-1);
|
||||
functionData[53][0]=new Byte(Ptg.CLASS_VALUE);functionData[53][1]=new byte[] {Ptg.CLASS_VALUE};functionData[53][2]=new Integer(-1);
|
||||
functionData[54][0]=new Byte(Ptg.CLASS_VALUE);functionData[54][1]=new byte[] {Ptg.CLASS_VALUE};functionData[54][2]=new Integer(-1);
|
||||
functionData[56][0]=new Byte(Ptg.CLASS_VALUE);functionData[56][1]=new byte[] {Ptg.CLASS_VALUE};functionData[56][2]=new Integer(-1);
|
||||
functionData[57][0]=new Byte(Ptg.CLASS_VALUE);functionData[57][1]=new byte[] {Ptg.CLASS_VALUE};functionData[57][2]=new Integer(-1);
|
||||
functionData[58][0]=new Byte(Ptg.CLASS_VALUE);functionData[58][1]=new byte[] {Ptg.CLASS_VALUE};functionData[58][2]=new Integer(-1);
|
||||
functionData[59][0]=new Byte(Ptg.CLASS_VALUE);functionData[59][1]=new byte[] {Ptg.CLASS_VALUE};functionData[59][2]=new Integer(-1);
|
||||
functionData[60][0]=new Byte(Ptg.CLASS_VALUE);functionData[60][1]=new byte[] {Ptg.CLASS_VALUE};functionData[60][2]=new Integer(-1);
|
||||
functionData[61][0]=new Byte(Ptg.CLASS_VALUE);functionData[61][1]=new byte[] {Ptg.CLASS_VALUE};functionData[61][2]=new Integer(3);
|
||||
functionData[62][0]=new Byte(Ptg.CLASS_VALUE);functionData[62][1]=new byte[] {Ptg.CLASS_REF};functionData[62][2]=new Integer(-1);
|
||||
functionData[63][0]=new Byte(Ptg.CLASS_VALUE);functionData[63][1]=new byte[] {Ptg.CLASS_REF};functionData[63][2]=new Integer(1);
|
||||
functionData[64][0]=new Byte(Ptg.CLASS_VALUE);functionData[64][1]=new byte[] {Ptg.CLASS_REF};functionData[64][2]=new Integer(-1);
|
||||
functionData[65][0]=new Byte(Ptg.CLASS_VALUE);functionData[65][1]=new byte[] {Ptg.CLASS_VALUE};functionData[65][2]=new Integer(3);
|
||||
functionData[66][0]=new Byte(Ptg.CLASS_VALUE);functionData[66][1]=new byte[] {Ptg.CLASS_VALUE};functionData[66][2]=new Integer(3);
|
||||
functionData[67][0]=new Byte(Ptg.CLASS_VALUE);functionData[67][1]=new byte[] {Ptg.CLASS_VALUE};functionData[67][2]=new Integer(1);
|
||||
functionData[68][0]=new Byte(Ptg.CLASS_VALUE);functionData[68][1]=new byte[] {Ptg.CLASS_VALUE};functionData[68][2]=new Integer(1);
|
||||
functionData[69][0]=new Byte(Ptg.CLASS_VALUE);functionData[69][1]=new byte[] {Ptg.CLASS_VALUE};functionData[69][2]=new Integer(1);
|
||||
functionData[70][0]=new Byte(Ptg.CLASS_VALUE);functionData[70][1]=new byte[] {Ptg.CLASS_VALUE};functionData[70][2]=new Integer(-1);
|
||||
functionData[71][0]=new Byte(Ptg.CLASS_VALUE);functionData[71][1]=new byte[] {Ptg.CLASS_VALUE};functionData[71][2]=new Integer(1);
|
||||
functionData[72][0]=new Byte(Ptg.CLASS_VALUE);functionData[72][1]=new byte[] {Ptg.CLASS_VALUE};functionData[72][2]=new Integer(1);
|
||||
functionData[73][0]=new Byte(Ptg.CLASS_VALUE);functionData[73][1]=new byte[] {Ptg.CLASS_VALUE};functionData[73][2]=new Integer(1);
|
||||
functionData[74][0]=new Byte(Ptg.CLASS_VALUE);functionData[74][1]=new byte[] {Ptg.CLASS_REF};functionData[74][2]=new Integer(1);
|
||||
functionData[75][0]=new Byte(Ptg.CLASS_VALUE);functionData[75][1]=new byte[] {Ptg.CLASS_REF};functionData[75][2]=new Integer(1);
|
||||
functionData[76][0]=new Byte(Ptg.CLASS_VALUE);functionData[76][1]=new byte[] {Ptg.CLASS_REF};functionData[76][2]=new Integer(1);
|
||||
functionData[77][0]=new Byte(Ptg.CLASS_VALUE);functionData[77][1]=new byte[] {Ptg.CLASS_REF};functionData[77][2]=new Integer(1);
|
||||
functionData[78][0]=new Byte(Ptg.CLASS_VALUE);functionData[78][1]=new byte[] {Ptg.CLASS_VALUE};functionData[78][2]=new Integer(-1);
|
||||
|
||||
return functionData;
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return returnClass;
|
||||
}
|
||||
|
||||
protected byte getParameterClass(int index) {
|
||||
try {
|
||||
return paramClass[index];
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
return paramClass[paramClass.length - 1];
|
||||
}
|
||||
}
|
||||
}
|
@ -109,7 +109,7 @@ public class AreaPtg
|
||||
field_2_last_row = LittleEndian.getShort(data, 2 + offset);
|
||||
field_3_first_column = LittleEndian.getShort(data, 4 + offset);
|
||||
field_4_last_column = LittleEndian.getShort(data, 6 + offset);
|
||||
System.out.println(toString());
|
||||
//System.out.println(toString());
|
||||
}
|
||||
|
||||
public String toString()
|
||||
|
@ -97,7 +97,7 @@ public class AttrPtg
|
||||
field_2_data = LittleEndian.getShort(data, offset + 1);
|
||||
System.out.println("OPTIONS = " + Integer.toHexString(getOptions()));
|
||||
System.out.println("OPTIONS & 0x10 = " + (getOptions() & 0x10));
|
||||
System.out.println(toString());
|
||||
//System.out.println(toString());
|
||||
}
|
||||
|
||||
public void setOptions(byte options)
|
||||
@ -193,7 +193,7 @@ public class AttrPtg
|
||||
|
||||
public String toFormulaString()
|
||||
{
|
||||
return "SUM()";
|
||||
return "ATTR";
|
||||
}
|
||||
|
||||
public int getNumberOfOperands()
|
||||
|
@ -65,7 +65,7 @@ import java.io.File;
|
||||
|
||||
|
||||
/**
|
||||
* This class parses a formula string into a List of tokens in RPN order
|
||||
* This class parses a formula string into a List of tokens in RPN order.
|
||||
* Inspired by
|
||||
* Lets Build a Compiler, by Jack Crenshaw
|
||||
* BNF for the formula expression is :
|
||||
@ -271,8 +271,7 @@ public class FormulaParser {
|
||||
ptg.setSum(true);
|
||||
retval = ptg;
|
||||
} else {
|
||||
FunctionPtg ptg = new FunctionPtg(name,numArgs);
|
||||
retval = ptg;
|
||||
retval = new FuncVarPtg(name,numArgs);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -438,6 +437,12 @@ end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* PARSER IMPLEMENTATION ENDS HERE
|
||||
* EXCEL SPECIFIC METHODS BELOW
|
||||
*******************************/
|
||||
|
||||
/** API call to retrive the array of Ptgs created as
|
||||
* a result of the parsing
|
||||
*/
|
||||
@ -469,11 +474,11 @@ end;
|
||||
|
||||
private void setParameterRVA(Node n, int formulaType) {
|
||||
Ptg p = (Ptg) n.getValue();
|
||||
if (p instanceof FunctionPtg) {
|
||||
if (p instanceof AbstractFunctionPtg) {
|
||||
int numOperands = n.getNumChildren();
|
||||
for (int i =0;i<n.getNumChildren();i++) {
|
||||
setParameterRVA(n.getChild(i),((FunctionPtg)p).getParameterClass(i),formulaType);
|
||||
if (n.getChild(i).getValue() instanceof FunctionPtg) {
|
||||
setParameterRVA(n.getChild(i),((AbstractFunctionPtg)p).getParameterClass(i),formulaType);
|
||||
if (n.getChild(i).getValue() instanceof AbstractFunctionPtg) {
|
||||
setParameterRVA(n.getChild(i),formulaType);
|
||||
}
|
||||
}
|
||||
@ -517,7 +522,7 @@ end;
|
||||
|
||||
private void setClass(Node n, byte theClass) {
|
||||
Ptg p = (Ptg) n.getValue();
|
||||
if (p instanceof FunctionPtg || !(p instanceof OperationPtg)) {
|
||||
if (p instanceof AbstractFunctionPtg || !(p instanceof OperationPtg)) {
|
||||
p.setClass(theClass);
|
||||
} else {
|
||||
for (int i =0;i<n.getNumChildren();i++) {
|
||||
@ -527,10 +532,12 @@ end;
|
||||
}
|
||||
/**
|
||||
* Convience method which takes in a list then passes it to the other toFormulaString
|
||||
* signature
|
||||
* signature.
|
||||
* @param lptgs - list of ptgs, can be null
|
||||
*/
|
||||
public static String toFormulaString(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(ptgs);
|
||||
@ -539,19 +546,19 @@ end;
|
||||
|
||||
/** 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
|
||||
*/
|
||||
public static String toFormulaString(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[] operands;
|
||||
for (int i=0;i<numPtgs;i++) {
|
||||
if (ptgs[i] instanceof OperationPtg) {
|
||||
|
||||
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
||||
// do not have any operands. Skip them.
|
||||
if(i > 0) {
|
||||
// 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];
|
||||
numOperands = o.getNumberOfOperands();
|
||||
operands = new String[numOperands];
|
||||
@ -561,7 +568,6 @@ end;
|
||||
}
|
||||
String result = o.toFormulaString(operands);
|
||||
stack.push(result);
|
||||
}
|
||||
} else {
|
||||
stack.push(ptgs[i].toFormulaString());
|
||||
}
|
||||
|
31
src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
Normal file
31
src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
Normal file
@ -0,0 +1,31 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
public class FuncPtg extends AbstractFunctionPtg{
|
||||
|
||||
public final static short sid = 0x21;
|
||||
private int numParams=0;
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
*/
|
||||
public FuncPtg(byte[] data, int offset) {
|
||||
offset++;
|
||||
//field_1_num_args = data[ offset + 0 ];
|
||||
field_2_fnc_index = LittleEndian.getShort(data,offset + 0 );
|
||||
try {
|
||||
numParams = ( (Integer)functionData[field_2_fnc_index][2]).intValue();
|
||||
} catch (NullPointerException npe) {
|
||||
numParams=0;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
array[offset+0]=(byte) (sid + ptgClass);
|
||||
//array[offset+1]=field_1_num_args;
|
||||
LittleEndian.putShort(array,offset+1,field_2_fnc_index);
|
||||
}
|
||||
|
||||
public int getNumberOfOperands() {
|
||||
return numParams;
|
||||
}
|
||||
}
|
42
src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java
Normal file
42
src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java
Normal file
@ -0,0 +1,42 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
public class FuncVarPtg extends AbstractFunctionPtg{
|
||||
|
||||
public final static short sid = 0x22;
|
||||
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
*/
|
||||
public FuncVarPtg(byte[] data, int offset) {
|
||||
offset++;
|
||||
field_1_num_args = data[ offset + 0 ];
|
||||
field_2_fnc_index = LittleEndian.getShort(data,offset + 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a function ptg from a string tokenised by the parser
|
||||
*/
|
||||
protected FuncVarPtg(String pName, byte pNumOperands) {
|
||||
field_1_num_args = pNumOperands;
|
||||
field_2_fnc_index = lookupIndex(pName);
|
||||
try{
|
||||
returnClass = ( (Byte) functionData[field_2_fnc_index][0]).byteValue();
|
||||
paramClass = (byte[]) functionData[field_2_fnc_index][1];
|
||||
} catch (NullPointerException npe ) {
|
||||
returnClass = Ptg.CLASS_VALUE;
|
||||
paramClass = new byte[] {Ptg.CLASS_VALUE};
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
array[offset+0]=(byte) (sid + ptgClass);
|
||||
array[offset+1]=field_1_num_args;
|
||||
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
|
||||
}
|
||||
|
||||
public int getNumberOfOperands() {
|
||||
return field_1_num_args;
|
||||
}
|
||||
|
||||
|
||||
}
|
101
src/java/org/apache/poi/hssf/record/formula/MissingArgPtg.java
Normal file
101
src/java/org/apache/poi/hssf/record/formula/MissingArgPtg.java
Normal file
@ -0,0 +1,101 @@
|
||||
/* ====================================================================
|
||||
* 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.record.formula;
|
||||
|
||||
|
||||
/**
|
||||
* Missing Function Arguments
|
||||
*
|
||||
* Avik Sengupta <avik at apache.org>
|
||||
*/
|
||||
public class MissingArgPtg
|
||||
extends Ptg
|
||||
{
|
||||
|
||||
private final static int SIZE = 1;
|
||||
public final static byte sid = 0x16;
|
||||
|
||||
protected MissingArgPtg()
|
||||
{
|
||||
}
|
||||
|
||||
public MissingArgPtg(byte [] data, int offset)
|
||||
{
|
||||
// doesn't need anything
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void writeBytes(byte [] array, int offset)
|
||||
{
|
||||
array[ offset + 0 ] = sid;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
|
||||
public String toFormulaString()
|
||||
{
|
||||
return " ";
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
}
|
||||
|
||||
|
@ -133,14 +133,15 @@ public abstract class Ptg
|
||||
|
||||
final byte valueRef = ReferencePtg.sid + 0x20;
|
||||
final byte arrayRef = ReferencePtg.sid + 0x40;
|
||||
final byte valueFunc = FunctionPtg.sid + 0x20;
|
||||
final byte arrayFunc = FunctionPtg.sid + 0x40;
|
||||
final byte valueFunc = FuncPtg.sid + 0x20;
|
||||
final byte arrayFunc = FuncPtg.sid + 0x40;
|
||||
final byte valueFuncVar = FuncVarPtg.sid +0x20;
|
||||
final byte arrayFuncVar = FuncVarPtg.sid+0x40;
|
||||
final byte valueArea = AreaPtg.sid + 0x20;
|
||||
final byte arrayArea = AreaPtg.sid + 0x40;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
|
||||
case AddPtg.sid :
|
||||
retval = new AddPtg(data, offset);
|
||||
break;
|
||||
@ -200,15 +201,26 @@ public abstract class Ptg
|
||||
retval = new ParenthesisPtg(data, offset);
|
||||
break;
|
||||
|
||||
case FunctionPtg.sid :
|
||||
retval = new FunctionPtg(data, offset);
|
||||
case FuncPtg.sid :
|
||||
retval = new FuncPtg(data, offset);
|
||||
break;
|
||||
|
||||
case valueFunc :
|
||||
retval = new FunctionPtg(data, offset);
|
||||
retval = new FuncPtg(data, offset);
|
||||
break;
|
||||
case arrayFunc :
|
||||
retval = new FunctionPtg(data, offset);
|
||||
retval = new FuncPtg(data, offset);
|
||||
break;
|
||||
|
||||
case FuncVarPtg.sid :
|
||||
retval = new FuncVarPtg(data, offset);
|
||||
break;
|
||||
|
||||
case valueFuncVar :
|
||||
retval = new FuncVarPtg(data, offset);
|
||||
break;
|
||||
case arrayFuncVar :
|
||||
retval = new FuncVarPtg(data, offset);
|
||||
break;
|
||||
|
||||
case NumberPtg.sid :
|
||||
@ -234,13 +246,16 @@ public abstract class Ptg
|
||||
case Ref3DPtg.sid:
|
||||
retval = new Ref3DPtg(data, offset);
|
||||
break;
|
||||
|
||||
case MissingArgPtg.sid:
|
||||
retval = new MissingArgPtg(data,offset);
|
||||
break;
|
||||
|
||||
default :
|
||||
|
||||
// retval = new UnknownPtg();
|
||||
throw new RuntimeException("Unknown PTG = "
|
||||
+ Integer.toHexString(( int ) id)
|
||||
+ " (" + ( int ) id + ")");
|
||||
//retval = new UnknownPtg();
|
||||
throw new java.lang.UnsupportedOperationException(
|
||||
Integer.toHexString(( int ) id) + " (" + ( int ) id + ")");
|
||||
}
|
||||
|
||||
if (id > 0x60) {
|
||||
@ -295,6 +310,10 @@ public abstract class Ptg
|
||||
ptgClass = thePtgClass;
|
||||
}
|
||||
|
||||
/** returns the class (REF/VALUE/ARRAY) for this Ptg */
|
||||
public byte getPtgClass() {
|
||||
return ptgClass;
|
||||
}
|
||||
|
||||
public abstract byte getDefaultOperandClass();
|
||||
|
||||
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* ReferenceUtil.java
|
||||
*
|
||||
* Created on April 28, 2002, 1:09 PM
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.util;
|
||||
|
||||
/**
|
||||
* Handles conversion between A1= 0,0 (cell ref to numeric conversion)
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
*/
|
||||
public class ReferenceUtil {
|
||||
|
||||
/** You don't neeed to construct this */
|
||||
private ReferenceUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* takes in a cell range and returns an array of integers x1,y1,x2,y2
|
||||
*/
|
||||
public static int[] getXYXYFromAreaRef(String reference) {
|
||||
int retval[] = null;
|
||||
String[] refs = seperateAreaRefs(reference);
|
||||
int[] xy1 = getXYFromReference(refs[0]);
|
||||
int[] xy2 = getXYFromReference(refs[1]);
|
||||
retval = new int[] {xy1[0],xy1[1],xy2[0],xy2[1]};
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes in a cell reference string A1 for instance and returns an integer
|
||||
* array with the first element being the row number and the second being
|
||||
* the column number, all in 0-based base 10 format.
|
||||
* @param reference a cell reference such as A1 or AA1 or IV1
|
||||
* @return xyarray int array containing row and column number
|
||||
*/
|
||||
public static int[] getXYFromReference(String reference) {
|
||||
int[] retval = new int[2];
|
||||
String[] parts = seperateRowColumns(reference);
|
||||
retval[1] = convertColStringToNum(parts[0]);
|
||||
retval[0] = Integer.parseInt(parts[1])-1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes in a row and column and returns a string cellref
|
||||
* @param row the 0 based row such as 0
|
||||
* @param col the 0 based col number such as 1
|
||||
* @return cellreference string such as B1
|
||||
*/
|
||||
public static String getReferenceFromXY(int row, int col) {
|
||||
String retval = convertNumToColString(col) + ""+(row+1);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes in a column reference portion of a CellRef and converts it from
|
||||
* ALPHA-26 number format to 0-based base 10.
|
||||
*/
|
||||
private static 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 static String[] seperateRowColumns(String reference) {
|
||||
int loc = 0; // location of first number
|
||||
String retval[] = new String[2];
|
||||
int length = reference.length();
|
||||
|
||||
char[] chars = reference.toCharArray();
|
||||
|
||||
for (loc = 0; loc < chars.length; loc++) {
|
||||
if (Character.isDigit(chars[loc])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
retval[0] = reference.substring(0,loc);
|
||||
retval[1] = reference.substring(loc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* seperates Area refs in two parts and returns them as seperate elements in a
|
||||
* String array
|
||||
*/
|
||||
private static 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user