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

View File

@ -44,13 +44,17 @@ const
INT_EXCEL_TOKEN_TREFA = $64;
{ 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_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_ABS = 24; // $18
INT_EXCEL_SHEET_FUNC_ROUND = 27;
{ Control Tokens, Special Tokens }
@ -124,7 +128,7 @@ type
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
procedure GetLastColCallback(ACell: PCell; AStream: TStream);
function GetLastColIndex(AWorksheet: TsWorksheet): Word;
function FormulaElementKindToExcelTokenID(AElementKind: TFEKind): Byte;
function FormulaElementKindToExcelTokenID(AElementKind: TFEKind; out ASecondaryID: Word): Byte;
// Other records which didn't change
// Workbook Globals records
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
@ -271,8 +275,10 @@ begin
end;
function TsSpreadBIFFWriter.FormulaElementKindToExcelTokenID(
AElementKind: TFEKind): Byte;
AElementKind: TFEKind; out ASecondaryID: Word): Byte;
begin
ASecondaryID := 0;
case AElementKind of
{ Operand Tokens }
fekCell: Result := INT_EXCEL_TOKEN_TREFR;
@ -284,8 +290,16 @@ begin
fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL;
{ Build-in Functions}
fekABS: Result := INT_EXCEL_SHEET_FUNC_ABS;
fekROUND: Result := INT_EXCEL_SHEET_FUNC_ROUND;
fekABS:
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 }
fekOpSUM: Result := INT_EXCEL_TOKEN_TATTR;
else