fpspreadsheet: Greatly improves the biff8 formula writing, now supports ABS and fixed =Cell+Cell

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2674 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2013-02-12 12:13:49 +00:00
parent 2630770763
commit e70e659419
2 changed files with 32 additions and 9 deletions

View File

@ -186,6 +186,7 @@ const
{ Cell Addresses constants } { Cell Addresses constants }
MASK_EXCEL_ROW = $3FFF; MASK_EXCEL_ROW = $3FFF;
MASK_EXCEL_COL_BITS_BIFF8=$00FF;
MASK_EXCEL_RELATIVE_ROW = $4000; MASK_EXCEL_RELATIVE_ROW = $4000;
MASK_EXCEL_RELATIVE_COL = $8000; MASK_EXCEL_RELATIVE_COL = $8000;
@ -842,6 +843,7 @@ var
RPNLength: Word; RPNLength: Word;
TokenArraySizePos, RecordSizePos, FinalPos: Int64; TokenArraySizePos, RecordSizePos, FinalPos: Int64;
TokenID: Byte; TokenID: Byte;
lSecondaryID: Word;
begin begin
RPNLength := 0; RPNLength := 0;
FormulaResult := 0.0; FormulaResult := 0.0;
@ -880,7 +882,7 @@ begin
for i := 0 to Length(AFormula) - 1 do for i := 0 to Length(AFormula) - 1 do
begin begin
{ Token identifier } { Token identifier }
TokenID := FormulaElementKindToExcelTokenID(AFormula[i].ElementKind); TokenID := FormulaElementKindToExcelTokenID(AFormula[i].ElementKind, lSecondaryID);
AStream.WriteByte(TokenID); AStream.WriteByte(TokenID);
Inc(RPNLength); Inc(RPNLength);
@ -889,9 +891,9 @@ begin
{ Operand Tokens } { Operand Tokens }
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA: { fekCell } INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA: { fekCell }
begin begin
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW); AStream.WriteWord(AFormula[i].Row);
AStream.WriteByte(AFormula[i].Col); AStream.WriteWord(AFormula[i].Col and MASK_EXCEL_COL_BITS_BIFF8);
Inc(RPNLength, 3); Inc(RPNLength, 4);
end; end;
INT_EXCEL_TOKEN_TAREA_R: { fekCellRange } INT_EXCEL_TOKEN_TAREA_R: { fekCellRange }
@ -931,6 +933,13 @@ begin
Inc(RPNLength, 3); Inc(RPNLength, 3);
end; end;
// Functions
INT_EXCEL_TOKEN_FUNC_R, INT_EXCEL_TOKEN_FUNC_V, INT_EXCEL_TOKEN_FUNC_A:
begin
AStream.WriteWord(lSecondaryID);
Inc(RPNLength, 2);
end;
else else
end; end;
end; end;

View File

@ -44,13 +44,17 @@ const
INT_EXCEL_TOKEN_TREFA = $64; INT_EXCEL_TOKEN_TREFA = $64;
{ Function Tokens } { Function Tokens }
INT_EXCEL_TOKEN_FUNC_R = $21;
INT_EXCEL_TOKEN_FUNC_V = $41;
INT_EXCEL_TOKEN_FUNC_A = $61;
INT_EXCEL_TOKEN_FUNCVAR_R = $22; INT_EXCEL_TOKEN_FUNCVAR_R = $22;
INT_EXCEL_TOKEN_FUNCVAR_V = $42; INT_EXCEL_TOKEN_FUNCVAR_V = $42;
INT_EXCEL_TOKEN_FUNCVAR_A = $62; INT_EXCEL_TOKEN_FUNCVAR_A = $62;
INT_EXCEL_TOKEN_TAREA_R = $25; INT_EXCEL_TOKEN_TAREA_R = $25;
{ Built-in functions } { Built-in functions }
INT_EXCEL_SHEET_FUNC_ABS = 24; INT_EXCEL_SHEET_FUNC_ABS = 24; // $18
INT_EXCEL_SHEET_FUNC_ROUND = 27; INT_EXCEL_SHEET_FUNC_ROUND = 27;
{ Control Tokens, Special Tokens } { Control Tokens, Special Tokens }
@ -124,7 +128,7 @@ type
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer; function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
procedure GetLastColCallback(ACell: PCell; AStream: TStream); procedure GetLastColCallback(ACell: PCell; AStream: TStream);
function GetLastColIndex(AWorksheet: TsWorksheet): Word; function GetLastColIndex(AWorksheet: TsWorksheet): Word;
function FormulaElementKindToExcelTokenID(AElementKind: TFEKind): Byte; function FormulaElementKindToExcelTokenID(AElementKind: TFEKind; out ASecondaryID: Word): Byte;
// Other records which didn't change // Other records which didn't change
// Workbook Globals records // Workbook Globals records
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding); procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
@ -271,8 +275,10 @@ begin
end; end;
function TsSpreadBIFFWriter.FormulaElementKindToExcelTokenID( function TsSpreadBIFFWriter.FormulaElementKindToExcelTokenID(
AElementKind: TFEKind): Byte; AElementKind: TFEKind; out ASecondaryID: Word): Byte;
begin begin
ASecondaryID := 0;
case AElementKind of case AElementKind of
{ Operand Tokens } { Operand Tokens }
fekCell: Result := INT_EXCEL_TOKEN_TREFR; fekCell: Result := INT_EXCEL_TOKEN_TREFR;
@ -284,8 +290,16 @@ begin
fekDiv: Result := INT_EXCEL_TOKEN_TDIV; fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL; fekMul: Result := INT_EXCEL_TOKEN_TMUL;
{ Build-in Functions} { Build-in Functions}
fekABS: Result := INT_EXCEL_SHEET_FUNC_ABS; fekABS:
fekROUND: Result := INT_EXCEL_SHEET_FUNC_ROUND; begin
Result := INT_EXCEL_TOKEN_FUNC_V;
ASecondaryID := INT_EXCEL_SHEET_FUNC_ABS;
end;
fekROUND:
begin
Result := INT_EXCEL_TOKEN_FUNC_V;
ASecondaryID := INT_EXCEL_SHEET_FUNC_ROUND;
end;
{ Other operations } { Other operations }
fekOpSUM: Result := INT_EXCEL_TOKEN_TATTR; fekOpSUM: Result := INT_EXCEL_TOKEN_TATTR;
else else