FileDocCategorySizeDatePackage
FormulaRecord.javaAPI DocApache Poi 3.0.115443Mon Jan 01 12:39:40 GMT 2007org.apache.poi.hssf.record

FormulaRecord

public class FormulaRecord extends Record implements Comparable, CellValueRecordInterface
Formula Record. REFERENCE: PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

author
Andrew C. Oliver (acoliver at apache dot org)
author
Jason Height (jheight at chariot dot net dot au)
version
2.0-pre

Fields Summary
public static final short
sid
private int
field_1_row
private short
field_2_column
private short
field_3_xf
private double
field_4_value
private short
field_5_options
private BitField
alwaysCalc
private BitField
calcOnLoad
private BitField
sharedFormula
private int
field_6_zero
private short
field_7_expression_len
private Stack
field_8_parsed_expr
private byte[]
value_data
Since the NaN support seems sketchy (different constants) we'll store and spit it out directly
private byte[]
all_data
Constructors Summary
public FormulaRecord()
Creates new FormulaRecord

 //if formula support is not enabled then
                                        //we'll just store/reserialize

        

     
    
        field_8_parsed_expr = new Stack();
    
public FormulaRecord(RecordInputStream in)
Constructs a Formula record and sets its fields appropriately.

param
id id must be 0x06 (NOT 0x406 see MSKB #Q184647 for an "explanation of this bug in the documentation) or an exception will be throw upon validation
param
size the size of the data area of the record
param
data data of the record (should not contain sid/len)

        super(in);
    
Methods Summary
public java.lang.Objectclone()

      FormulaRecord rec = new FormulaRecord();
      rec.field_1_row = field_1_row;
      rec.field_2_column = field_2_column;
      rec.field_3_xf = field_3_xf;
      rec.field_4_value = field_4_value;
      rec.field_5_options = field_5_options;
      rec.field_6_zero = field_6_zero;
      rec.field_7_expression_len = field_7_expression_len;
      rec.field_8_parsed_expr = new Stack();
      int size = 0;
      if (field_8_parsed_expr != null)
        size = field_8_parsed_expr.size();
      for (int i=0; i< size; i++) {
        Ptg ptg = (Ptg)((Ptg)field_8_parsed_expr.get(i)).clone();        
        rec.field_8_parsed_expr.add(i, ptg);
      }
      rec.value_data = value_data;
      rec.all_data = all_data;
      return rec;
    
public intcompareTo(java.lang.Object obj)

        CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;

        if ((this.getRow() == loc.getRow())
                && (this.getColumn() == loc.getColumn()))
        {
            return 0;
        }
        if (this.getRow() < loc.getRow())
        {
            return -1;
        }
        if (this.getRow() > loc.getRow())
        {
            return 1;
        }
        if (this.getColumn() < loc.getColumn())
        {
            return -1;
        }
        if (this.getColumn() > loc.getColumn())
        {
            return 1;
        }
        return -1;
    
public booleanequals(java.lang.Object obj)

        if (!(obj instanceof CellValueRecordInterface))
        {
            return false;
        }
        CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;

        if ((this.getRow() == loc.getRow())
                && (this.getColumn() == loc.getColumn()))
        {
            return true;
        }
        return false;
    
protected voidfillFields(org.apache.poi.hssf.record.RecordInputStream in)

        try {
          field_1_row            = in.readUShort();
          field_2_column         = in.readShort();
          field_3_xf             = in.readShort();
          field_4_value          = in.readDouble();
          field_5_options        = in.readShort();
		        
        if (Double.isNaN(field_4_value)) {
            value_data = in.getNANData();
        }
        
          field_6_zero           = in.readInt();
          field_7_expression_len = in.readShort();
          field_8_parsed_expr    = Ptg.createParsedExpressionTokens(field_7_expression_len, in);
        } catch (java.lang.UnsupportedOperationException uoe)  {
          throw new RecordFormatException(uoe);
        }
    
public shortgetColumn()

        return field_2_column;
    
public shortgetExpressionLength()
get the length (in number of tokens) of the expression

return
expression length

        return field_7_expression_len;
    
public intgetNumberOfExpressionTokens()
get the size of the stack

return
size of the stack

        if (this.field_8_parsed_expr == null) {
            return 0;
        } else {
            return field_8_parsed_expr.size();
        }
    
public shortgetOptions()
get the option flags

return
bitmask

        return field_5_options;
    
public java.util.ListgetParsedExpression()
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!

        return field_8_parsed_expr;
    
public intgetRecordSize()

        int retval =0;
        
        if (this.field_8_parsed_expr != null) {
            retval = getTotalPtgSize() + 26;
        } else {
            retval =all_data.length;
        }
        return retval;

        // return getTotalPtgSize() + 28;
    
public intgetRow()

        return field_1_row;
    
public shortgetSid()

        return sid;
    
private intgetTotalPtgSize()

        List list   = getParsedExpression();
        int  retval = 0;

        for (int k = 0; k < list.size(); k++)
        {
            Ptg ptg = ( Ptg ) list.get(k);

            retval += ptg.getSize();
        }
        return retval;
    
public doublegetValue()
get the calculated value of the formula

return
calculated value

        return field_4_value;
    
public shortgetXFIndex()

        return field_3_xf;
    
public booleanisAfter(org.apache.poi.hssf.record.CellValueRecordInterface i)

        if (this.getRow() < i.getRow())
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() < i.getColumn()))
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()))
        {
            return false;
        }
        return true;
    
public booleanisBefore(org.apache.poi.hssf.record.CellValueRecordInterface i)

        if (this.getRow() > i.getRow())
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() > i.getColumn()))
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()))
        {
            return false;
        }
        return true;
    
public booleanisEqual(org.apache.poi.hssf.record.CellValueRecordInterface i)

        return ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()));
    
public booleanisInValueSection()

        return true;
    
public booleanisSharedFormula()

        return sharedFormula.isSet(field_5_options);
    
public booleanisValue()

        return true;
    
public org.apache.poi.hssf.record.formula.PtgpeekExpressionToken()
peek at the token on the top of stack

return
Ptg - the token

        return ( Ptg ) field_8_parsed_expr.peek();
    
public org.apache.poi.hssf.record.formula.PtgpopExpressionToken()
pop a token off of the stack

return
Ptg - the token

        return ( Ptg ) field_8_parsed_expr.pop();
    
public voidpushExpressionToken(org.apache.poi.hssf.record.formula.Ptg ptg)
push a token onto the stack

param
ptg the token

        field_8_parsed_expr.push(ptg);
    
public intserialize(int offset, byte[] data)
called by the class that is responsible for writing this sucker. Subclasses should implement this so that their data is passed back in a byte array.

return
byte array containing instance data

        if (this.field_8_parsed_expr != null) {
        int ptgSize = getTotalPtgSize();

        LittleEndian.putShort(data, 0 + offset, sid);
        LittleEndian.putShort(data, 2 + offset, ( short ) (22 + ptgSize));
        //LittleEndian.putShort(data, 4 + offset, getRow());
        LittleEndian.putShort(data, 4 + offset, ( short ) getRow());
        LittleEndian.putShort(data, 6 + offset, getColumn());
        LittleEndian.putShort(data, 8 + offset, getXFIndex());
        
        //only reserialize if the value is still NaN and we have old nan data
        if (Double.isNaN(this.getValue()) && value_data != null) {        	
			System.arraycopy(value_data,0,data,10 + offset,value_data.length);
        } else {
			LittleEndian.putDouble(data, 10 + offset, field_4_value);
        }
        	
        LittleEndian.putShort(data, 18 + offset, getOptions());
        
        //when writing the chn field (offset 20), it's supposed to be 0 but ignored on read
        //Microsoft Excel Developer's Kit Page 318
        LittleEndian.putInt(data, 20 + offset, 0);
        LittleEndian.putShort(data, 24 + offset, getExpressionLength());
        Ptg.serializePtgStack(field_8_parsed_expr, data, 26+offset);
        } else {
            System.arraycopy(all_data,0,data,offset,all_data.length);
        }
        return getRecordSize();
    
public voidsetColumn(short column)

        field_2_column = column;
    
public voidsetExpressionLength(short len)
set the length (in number of tokens) of the expression

param
len length

        field_7_expression_len = len;
    
public voidsetOptions(short options)
set the option flags

param
options bitmask

        field_5_options = options;
    
public voidsetParsedExpression(java.util.Stack ptgs)

      field_8_parsed_expr = ptgs;
    
public voidsetRow(int row)

        field_1_row = row;
    
public voidsetSharedFormula(boolean flag)

    	sharedFormula.setBoolean(field_5_options, flag);
    
public voidsetValue(double value)
set the calculated value of the formula

param
value calculated value

        field_4_value = value;
    
public voidsetXFIndex(short xf)

        field_3_xf = xf;
    
public java.lang.StringtoString()

        StringBuffer buffer = new StringBuffer();
            buffer.append("[FORMULA]\n");
            buffer.append("    .row       = ")
                .append(Integer.toHexString(getRow())).append("\n");
            buffer.append("    .column    = ")
                .append(Integer.toHexString(getColumn()))
                .append("\n");
            buffer.append("    .xf              = ")
                .append(Integer.toHexString(getXFIndex())).append("\n");
            if (Double.isNaN(this.getValue()) && value_data != null)
              buffer.append("    .value (NaN)     = ")
                  .append(org.apache.poi.util.HexDump.dump(value_data,0,0))
                  .append("\n");
            else
              buffer.append("    .value           = ").append(getValue())
                  .append("\n");
            buffer.append("    .options         = ").append(getOptions())
                .append("\n");
            buffer.append("      .alwaysCalc         = ").append(alwaysCalc.isSet(getOptions()))
                .append("\n");
            buffer.append("      .calcOnLoad         = ").append(calcOnLoad.isSet(getOptions()))
                .append("\n");
            buffer.append("      .sharedFormula         = ").append(sharedFormula.isSet(getOptions()))
                .append("\n");
            buffer.append("    .zero            = ").append(field_6_zero)
                .append("\n");
            buffer.append("    .expressionlength= ").append(getExpressionLength())
                .append("\n");

            if (field_8_parsed_expr != null) {
                buffer.append("    .numptgsinarray  = ").append(field_8_parsed_expr.size())
                    .append("\n");
            

                for (int k = 0; k < field_8_parsed_expr.size(); k++ ) {
                   buffer.append("     Ptg(")
                        .append(k)
                        .append(")=")
                        .append(field_8_parsed_expr.get(k).toString())
                        .append("\n")
                        .append(((Ptg)field_8_parsed_expr.get(k)).toDebugString())
                        .append("\n");
                }
            }else {
                buffer.append("Formula full data \n")
                    .append(org.apache.poi.util.HexDump.dump(this.all_data,0,0));
            }
            
            
            buffer.append("[/FORMULA]\n");
        return buffer.toString();
    
protected voidvalidateSid(short id)
called by constructor, should throw runtime exception in the event of a record passed with a differing ID.

param
id alleged id for this record

        if (id != sid)
        {
            throw new RecordFormatException("NOT A FORMULA RECORD");
        }