diff --git a/components/fpspreadsheet/examples/other/test_write_formula.lpi b/components/fpspreadsheet/examples/other/test_write_formula.lpi
index a42f8266e..51a2befcb 100644
--- a/components/fpspreadsheet/examples/other/test_write_formula.lpi
+++ b/components/fpspreadsheet/examples/other/test_write_formula.lpi
@@ -7,12 +7,12 @@
+
-
@@ -20,7 +20,7 @@
-
+
@@ -39,152 +39,13 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -196,6 +57,9 @@
+
+
+
diff --git a/components/fpspreadsheet/examples/other/test_write_formula.pas b/components/fpspreadsheet/examples/other/test_write_formula.pas
index 817ed8b9a..83f6668ab 100644
--- a/components/fpspreadsheet/examples/other/test_write_formula.pas
+++ b/components/fpspreadsheet/examples/other/test_write_formula.pas
@@ -42,12 +42,12 @@ begin
MyWorksheet.WriteFormula(1, 2, MyFormula); // C3
SetLength(MyRPNFormula, 2);
- MyRPNFormula[0].ElementKind := fekOpSUM;
- MyRPNFormula[1].ElementKind := fekCellRange;
- MyRPNFormula[1].Row := 1;
- MyRPNFormula[1].Row := 4;
- MyRPNFormula[1].Col := 3;
- MyRPNFormula[1].Col := 3;
+ MyRPNFormula[0].ElementKind := fekCellRange;
+ MyRPNFormula[0].Row := 1;
+ MyRPNFormula[0].Row2 := 4;
+ MyRPNFormula[0].Col := 3;
+ MyRPNFormula[0].Col2 := 3;
+ MyRPNFormula[1].ElementKind := fekOpSUM;
MyWorksheet.WriteRPNFormula(1, 2, MyRPNFormula); // C2
end;
diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas
index d3990446b..01baa7232 100755
--- a/components/fpspreadsheet/xlsbiff8.pas
+++ b/components/fpspreadsheet/xlsbiff8.pas
@@ -860,18 +860,36 @@ begin
{ Additional data }
case TokenID of
+ { Operand Tokens }
+ //fekCell: Result := INT_EXCEL_TOKEN_TREFR;
- { binary operation tokens }
+ INT_EXCEL_TOKEN_TAREA_R: { fekCellRange }
+ begin
+ {
+ Cell range address, BIFF8:
+ Offset Size Contents
+ 0 2 Index to first row (0…65535) or offset of first row (method [B], -32768…32767)
+ 2 2 Index to last row (0…65535) or offset of last row (method [B], -32768…32767)
+ 4 2 Index to first column or offset of first column, with relative flags (see table above)
+ 6 2 Index to last column or offset of last column, with relative flags (see table above)
+ }
+ AStream.WriteWord(WordToLE(AFormula[i].Row));
+ AStream.WriteWord(WordToLE(AFormula[i].Row2));
+ AStream.WriteWord(WordToLE(AFormula[i].Col));
+ AStream.WriteWord(WordToLE(AFormula[i].Col2));
+ Inc(RPNLength, 8);
+ end;
- INT_EXCEL_TOKEN_TADD, INT_EXCEL_TOKEN_TSUB, INT_EXCEL_TOKEN_TMUL,
- INT_EXCEL_TOKEN_TDIV, INT_EXCEL_TOKEN_TPOWER: begin end;
-
- INT_EXCEL_TOKEN_TNUM:
+ INT_EXCEL_TOKEN_TNUM: { fekNum }
begin
AStream.WriteBuffer(AFormula[i].DoubleValue, 8);
Inc(RPNLength, 8);
end;
+ { binary operation tokens }
+ INT_EXCEL_TOKEN_TADD, INT_EXCEL_TOKEN_TSUB, INT_EXCEL_TOKEN_TMUL,
+ INT_EXCEL_TOKEN_TDIV, INT_EXCEL_TOKEN_TPOWER: begin end;
+
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
begin
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
@@ -879,6 +897,17 @@ begin
Inc(RPNLength, 3);
end;
+ { Other operations }
+ INT_EXCEL_TOKEN_TATTR: { fekOpSUM }
+ begin
+ // Uniry SUM Operation
+ AStream.WriteByte($10);
+ AStream.WriteByte(0);
+ AStream.WriteByte(0);
+ Inc(RPNLength, 3);
+ end;
+
+ else
end;
end;
@@ -1526,13 +1555,31 @@ var
Data: array [0..7] of BYTE;
Flags: WORD;
FormulaSize: BYTE;
+ i: Integer;
begin
+ { BIFF Record header }
+ { BIFF Record data }
+ { Index to XF Record }
ReadRowColXF(AStream,ARow,ACol,XF);
+ { Result of the formula in IEE 754 floating-point value }
AStream.ReadBuffer(Data,Sizeof(Data));
+
+ { Options flags }
Flags:=WordLEtoN(AStream.ReadWord);
- AStream.ReadDWord; //Not used.
- FormulaSize:=AStream.ReadByte;
+
+ { Not used }
+ AStream.ReadDWord;
+
+ { Formula size }
+ FormulaSize := WordLEtoN(AStream.ReadWord);
+
+ { Formula data, outputed as debug info }
+{ Write('Formula Element: ');
+ for i := 1 to FormulaSize do
+ Write(IntToHex(AStream.ReadByte, 2) + ' ');
+ WriteLn('');}
+
//RPN data not used by now
AStream.Position:=AStream.Position+FormulaSize;
diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas
index 82a637140..eb033d0e2 100644
--- a/components/fpspreadsheet/xlscommon.pas
+++ b/components/fpspreadsheet/xlscommon.pas
@@ -43,11 +43,21 @@ const
INT_EXCEL_TOKEN_FUNCVAR_R = $22;
INT_EXCEL_TOKEN_FUNCVAR_V = $42;
INT_EXCEL_TOKEN_FUNCVAR_A = $62;
+ INT_EXCEL_TOKEN_TAREA_R = $25;
{ Built-in functions }
INT_EXCEL_SHEET_FUNC_ABS = 24;
INT_EXCEL_SHEET_FUNC_ROUND = 27;
+ { Control Tokens, Special Tokens }
+// 01H tExp Matrix formula or shared formula
+// 02H tTbl Multiple operation table
+// 15H tParen Parentheses
+// 18H tNlr Natural language reference (BIFF8)
+ INT_EXCEL_TOKEN_TATTR = $19; // tAttr Special attribute
+// 1AH tSheet Start of external sheet reference (BIFF2-BIFF4)
+// 1BH tEndSheet End of external sheet reference (BIFF2-BIFF4)
+
{ Built In Color Pallete Indexes }
BUILT_IN_COLOR_PALLETE_BLACK = $08; // 000000H
BUILT_IN_COLOR_PALLETE_WHITE = $09; // FFFFFFH
@@ -148,7 +158,7 @@ begin
case AElementKind of
{ Operand Tokens }
fekCell: Result := INT_EXCEL_TOKEN_TREFR;
- fekCellRange: Result := INT_EXCEL_TOKEN_TRANGE;
+ fekCellRange: Result := INT_EXCEL_TOKEN_TAREA_R;
fekNum: Result := INT_EXCEL_TOKEN_TNUM;
{ Basic operations }
fekAdd: Result := INT_EXCEL_TOKEN_TADD;
@@ -159,7 +169,7 @@ begin
fekABS: Result := INT_EXCEL_SHEET_FUNC_ABS;
fekROUND: Result := INT_EXCEL_SHEET_FUNC_ROUND;
{ Other operations }
- fekOpSUM: Result := 0;
+ fekOpSUM: Result := INT_EXCEL_TOKEN_TATTR;
else
Result := 0;
end;