fpspreadsheet: starts implementing formulas. RPN version working for Excel 5

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@832 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2009-06-09 11:19:10 +00:00
parent 6eb3432e9a
commit bb04dbc318
5 changed files with 179 additions and 100 deletions

View File

@ -11,7 +11,7 @@
<TargetFileExt Value=".exe"/> <TargetFileExt Value=".exe"/>
<Title Value="excel5write"/> <Title Value="excel5write"/>
<UseAppBundle Value="False"/> <UseAppBundle Value="False"/>
<ActiveEditorIndexAtStart Value="3"/> <ActiveEditorIndexAtStart Value="1"/>
</General> </General>
<VersionInfo> <VersionInfo>
<ProjectVersion Value=""/> <ProjectVersion Value=""/>
@ -38,8 +38,8 @@
<Filename Value="excel5write.lpr"/> <Filename Value="excel5write.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="excel5write"/> <UnitName Value="excel5write"/>
<CursorPos X="36" Y="32"/> <CursorPos X="25" Y="56"/>
<TopLine Value="26"/> <TopLine Value="37"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="309"/> <UsageCount Value="309"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -68,8 +68,8 @@
<Unit4> <Unit4>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<UnitName Value="xlsbiff5"/> <UnitName Value="xlsbiff5"/>
<CursorPos X="1" Y="1063"/> <CursorPos X="1" Y="1"/>
<TopLine Value="1047"/> <TopLine Value="1"/>
<EditorIndex Value="3"/> <EditorIndex Value="3"/>
<UsageCount Value="140"/> <UsageCount Value="140"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -86,8 +86,8 @@
<Unit6> <Unit6>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<UnitName Value="xlsbiff2"/> <UnitName Value="xlsbiff2"/>
<CursorPos X="34" Y="256"/> <CursorPos X="1" Y="286"/>
<TopLine Value="236"/> <TopLine Value="275"/>
<EditorIndex Value="6"/> <EditorIndex Value="6"/>
<UsageCount Value="139"/> <UsageCount Value="139"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -116,8 +116,8 @@
<Unit10> <Unit10>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/> <UnitName Value="fpspreadsheet"/>
<CursorPos X="1" Y="13"/> <CursorPos X="79" Y="836"/>
<TopLine Value="12"/> <TopLine Value="819"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="92"/> <UsageCount Value="92"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -150,123 +150,123 @@
<JumpHistory Count="30" HistoryIndex="29"> <JumpHistory Count="30" HistoryIndex="29">
<Position1> <Position1>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="405" Column="5" TopLine="386"/> <Caret Line="314" Column="39" TopLine="296"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="404" Column="14" TopLine="401"/> <Caret Line="479" Column="1" TopLine="469"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="79" Column="42" TopLine="72"/> <Caret Line="470" Column="1" TopLine="460"/>
</Position3> </Position3>
<Position4> <Position4>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="78" Column="31" TopLine="67"/> <Caret Line="217" Column="3" TopLine="205"/>
</Position4> </Position4>
<Position5> <Position5>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="314" Column="39" TopLine="296"/> <Caret Line="218" Column="23" TopLine="208"/>
</Position5> </Position5>
<Position6> <Position6>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="479" Column="1" TopLine="469"/> <Caret Line="78" Column="10" TopLine="66"/>
</Position6> </Position6>
<Position7> <Position7>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="470" Column="1" TopLine="460"/> <Caret Line="375" Column="1" TopLine="367"/>
</Position7> </Position7>
<Position8> <Position8>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="217" Column="3" TopLine="205"/> <Caret Line="76" Column="17" TopLine="65"/>
</Position8> </Position8>
<Position9> <Position9>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="218" Column="23" TopLine="208"/> <Caret Line="363" Column="1" TopLine="357"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="78" Column="10" TopLine="66"/> <Caret Line="77" Column="7" TopLine="76"/>
</Position10> </Position10>
<Position11> <Position11>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="375" Column="1" TopLine="367"/> <Caret Line="137" Column="40" TopLine="129"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="76" Column="17" TopLine="65"/> <Caret Line="563" Column="5" TopLine="544"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="363" Column="1" TopLine="357"/> <Caret Line="486" Column="5" TopLine="467"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="77" Column="7" TopLine="76"/> <Caret Line="510" Column="5" TopLine="491"/>
</Position14> </Position14>
<Position15> <Position15>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="137" Column="40" TopLine="129"/> <Caret Line="94" Column="46" TopLine="84"/>
</Position15> </Position15>
<Position16> <Position16>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="563" Column="5" TopLine="544"/> <Caret Line="686" Column="5" TopLine="667"/>
</Position16> </Position16>
<Position17> <Position17>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="486" Column="5" TopLine="467"/> <Caret Line="567" Column="5" TopLine="548"/>
</Position17> </Position17>
<Position18> <Position18>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="510" Column="5" TopLine="491"/> <Caret Line="622" Column="1" TopLine="618"/>
</Position18> </Position18>
<Position19> <Position19>
<Filename Value="..\..\fpolestorage.pas"/> <Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="94" Column="46" TopLine="84"/> <Caret Line="621" Column="29" TopLine="611"/>
</Position19> </Position19>
<Position20> <Position20>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="686" Column="5" TopLine="667"/>
</Position20>
<Position21>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="567" Column="5" TopLine="548"/>
</Position21>
<Position22>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="622" Column="1" TopLine="618"/>
</Position22>
<Position23>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="621" Column="29" TopLine="611"/>
</Position23>
<Position24>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="100" Column="17" TopLine="92"/> <Caret Line="100" Column="17" TopLine="92"/>
</Position24> </Position20>
<Position25> <Position21>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="615" Column="34" TopLine="593"/> <Caret Line="615" Column="34" TopLine="593"/>
</Position25> </Position21>
<Position26> <Position22>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position26> </Position22>
<Position27> <Position23>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="56" Column="88" TopLine="43"/> <Caret Line="56" Column="88" TopLine="43"/>
</Position27> </Position23>
<Position28> <Position24>
<Filename Value="..\..\xlsbiff8.pas"/> <Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position28> </Position24>
<Position29> <Position25>
<Filename Value="..\..\xlsbiff8.pas"/> <Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="69" Column="88" TopLine="56"/> <Caret Line="69" Column="88" TopLine="56"/>
</Position25>
<Position26>
<Filename Value="excel5write.lpr"/>
<Caret Line="47" Column="30" TopLine="33"/>
</Position26>
<Position27>
<Filename Value="excel5write.lpr"/>
<Caret Line="53" Column="21" TopLine="40"/>
</Position27>
<Position28>
<Filename Value="excel5write.lpr"/>
<Caret Line="54" Column="27" TopLine="40"/>
</Position28>
<Position29>
<Filename Value="excel5write.lpr"/>
<Caret Line="52" Column="38" TopLine="43"/>
</Position29> </Position29>
<Position30> <Position30>
<Filename Value="excel5write.lpr"/> <Filename Value="excel5write.lpr"/>
<Caret Line="47" Column="30" TopLine="33"/> <Caret Line="56" Column="25" TopLine="37"/>
</Position30> </Position30>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>

View File

@ -16,7 +16,7 @@ uses
var var
MyWorkbook: TsWorkbook; MyWorkbook: TsWorkbook;
MyWorksheet: TsWorksheet; MyWorksheet: TsWorksheet;
MyFormula: TsFormula; MyRPNFormula: TsRPNFormula;
MyDir: string; MyDir: string;
i: Integer; i: Integer;
begin begin
@ -45,8 +45,17 @@ begin
} }
// Write the formula E1 = A1 + B1 // Write the formula E1 = A1 + B1
// MyFormula.FormulaStr := ''; SetLength(MyRPNFormula, 3);
// MyWorksheet.WriteFormula(0, 4, MyFormula); MyRPNFormula[0].ElementKind := fekCell;
MyRPNFormula[0].Col := 0;
MyRPNFormula[0].Row := 0;
MyRPNFormula[1].ElementKind := fekCell;
MyRPNFormula[1].Col := 1;
MyRPNFormula[1].Row := 0;
MyRPNFormula[2].ElementKind := fekAdd;
MyWorksheet.WriteRPNFormula(0, 4, MyRPNFormula);
//MyFormula.FormulaStr := '';
// Creates a new worksheet // Creates a new worksheet
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');

View File

@ -49,24 +49,31 @@ type
TsFormulaElement = record TsFormulaElement = record
ElementKind: TFEKind; ElementKind: TFEKind;
Row1, Row2: Word; Row, Row2: Word; // zero-based
Col1, Col2: Byte; Col, Col2: Byte; // zero-based
DoubleValue: double; DoubleValue: double;
end; end;
TsExpandedFormula = array of TsFormulaElement; TsExpandedFormula = array of TsFormulaElement;
{@@ RPN formula. Similar to the expanded formula, but in RPN notation.
Simplifies the task of format writers which need RPN }
TsRPNFormula = array of TsFormulaElement;
{@@ Describes the type of content of a cell on a TsWorksheet } {@@ Describes the type of content of a cell on a TsWorksheet }
TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String); TCellContentType = (cctEmpty, cctFormula, cctRPNFormula, cctNumber, cctUTF8String);
{@@ Cell structure for TsWorksheet } {@@ Cell structure for TsWorksheet }
TCell = record TCell = record
Col: Byte; Col: Byte; // zero-based
Row: Word; Row: Word; // zero-based
ContentType: TCellContentType; ContentType: TCellContentType;
{ Possible values for the cells }
FormulaValue: TsFormula; FormulaValue: TsFormula;
RPNFormulaValue: TsRPNFormula;
NumberValue: double; NumberValue: double;
UTF8StringValue: ansistring; UTF8StringValue: ansistring;
end; end;
@ -101,6 +108,7 @@ type
procedure WriteUTF8Text(ARow, ACol: Cardinal; AText: ansistring); procedure WriteUTF8Text(ARow, ACol: Cardinal; AText: ansistring);
procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double); procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double);
procedure WriteFormula(ARow, ACol: Cardinal; AFormula: TsFormula); procedure WriteFormula(ARow, ACol: Cardinal; AFormula: TsFormula);
procedure WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TsRPNFormula);
end; end;
{ TsWorkbook } { TsWorkbook }
@ -165,7 +173,8 @@ type
procedure WriteToFile(AFileName: string; AData: TsWorkbook); virtual; procedure WriteToFile(AFileName: string; AData: TsWorkbook); virtual;
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); virtual; procedure WriteToStream(AStream: TStream; AData: TsWorkbook); virtual;
{ Record writing methods } { Record writing methods }
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsFormula); virtual; abstract; procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsFormula); virtual;
procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsRPNFormula); virtual;
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); virtual; abstract; procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); virtual; abstract;
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); virtual; abstract; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); virtual; abstract;
end; end;
@ -500,6 +509,17 @@ begin
ACell^.FormulaValue := AFormula; ACell^.FormulaValue := AFormula;
end; end;
procedure TsWorksheet.WriteRPNFormula(ARow, ACol: Cardinal;
AFormula: TsRPNFormula);
var
ACell: PCell;
begin
ACell := GetCell(ARow, ACol);
ACell^.ContentType := cctRPNFormula;
ACell^.RPNFormulaValue := AFormula;
end;
{ TsWorkbook } { TsWorkbook }
{@@ {@@
@ -810,9 +830,10 @@ begin
AStream := TStream(arg); AStream := TStream(arg);
case ACell.ContentType of case ACell.ContentType of
cctFormula: WriteFormula(AStream, ACell^.Row, ACell^.Col, ACell^.FormulaValue);
cctNumber: WriteNumber(AStream, ACell^.Row, ACell^.Col, ACell^.NumberValue); cctNumber: WriteNumber(AStream, ACell^.Row, ACell^.Col, ACell^.NumberValue);
cctUTF8String: WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue); cctUTF8String: WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue);
cctFormula: WriteFormula(AStream, ACell^.Row, ACell^.Col, ACell^.FormulaValue);
cctRPNFormula: WriteRPNFormula(AStream, ACell^.Row, ACell^.Col, ACell^.RPNFormulaValue);
end; end;
end; end;
@ -861,6 +882,18 @@ begin
end; end;
procedure TsCustomSpreadWriter.WriteFormula(AStream: TStream; const ARow,
ACol: Word; const AFormula: TsFormula);
begin
end;
procedure TsCustomSpreadWriter.WriteRPNFormula(AStream: TStream; const ARow,
ACol: Word; const AFormula: TsRPNFormula);
begin
end;
finalization finalization
SetLength(GsSpreadFormats, 0); SetLength(GsSpreadFormats, 0);

View File

@ -53,13 +53,15 @@ type
{ TsSpreadBIFF2Writer } { TsSpreadBIFF2Writer }
TsSpreadBIFF2Writer = class(TsCustomSpreadWriter) TsSpreadBIFF2Writer = class(TsCustomSpreadWriter)
private
function FEKindToExcelID(AElement: TFEKind): Byte;
public public
{ General writing methods } { General writing methods }
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override; procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
{ Record writing methods } { Record writing methods }
procedure WriteBOF(AStream: TStream); procedure WriteBOF(AStream: TStream);
procedure WriteEOF(AStream: TStream); procedure WriteEOF(AStream: TStream);
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsFormula); override; procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsRPNFormula); override;
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override; procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
end; end;
@ -84,17 +86,6 @@ const
INT_EXCEL_CHART = $0020; INT_EXCEL_CHART = $0020;
INT_EXCEL_MACRO_SHEET = $0040; INT_EXCEL_MACRO_SHEET = $0040;
{ Types and constants for formulas }
type
TRPNItem = record
TokenID: Byte;
Col: Byte;
Row: Word;
DoubleValue: Double;
end;
TRPNFormula = array of TRPNItem;
const const
{ TokenID values } { TokenID values }
@ -115,6 +106,17 @@ const
{ TsSpreadBIFF2Writer } { TsSpreadBIFF2Writer }
function TsSpreadBIFF2Writer.FEKindToExcelID(AElement: TFEKind): Byte;
begin
case AElement of
fekCell: Result := INT_EXCEL_TOKEN_TREFV;
fekAdd: Result := INT_EXCEL_TOKEN_TADD;
fekSub: Result := INT_EXCEL_TOKEN_TSUB;
fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL;
end;
end;
{ {
Writes an Excel 2 file to a stream Writes an Excel 2 file to a stream
@ -176,15 +178,16 @@ end;
MyFormula[1].Row := 0; MyFormula[1].Row := 0;
MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; + MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; +
} }
procedure TsSpreadBIFF2Writer.WriteFormula(AStream: TStream; const ARow, procedure TsSpreadBIFF2Writer.WriteRPNFormula(AStream: TStream; const ARow,
ACol: Word; const AFormula: TsFormula); ACol: Word; const AFormula: TsRPNFormula);
{var var
FormulaResult: double; FormulaResult: double;
i: Integer; i: Integer;
RPNLength: Word; RPNLength: Word;
TokenArraySizePos, RecordSizePos, FinalPos: Cardinal;} TokenArraySizePos, RecordSizePos, FinalPos: Cardinal;
FormulaKind: Byte;
begin begin
(* RPNLength := 0; RPNLength := 0;
FormulaResult := 0.0; FormulaResult := 0.0;
{ BIFF Record header } { BIFF Record header }
@ -220,11 +223,12 @@ begin
for i := 0 to Length(AFormula) - 1 do for i := 0 to Length(AFormula) - 1 do
begin begin
{ Token identifier } { Token identifier }
AStream.WriteByte(AFormula[i].TokenID); FormulaKind := FEKindToExcelID(AFormula[i].ElementKind);
AStream.WriteByte(FormulaKind);
Inc(RPNLength); Inc(RPNLength);
{ Additional data } { Additional data }
case AFormula[i].TokenID of case FormulaKind of
{ binary operation tokens } { binary operation tokens }
@ -253,7 +257,7 @@ begin
AStream.WriteByte(RPNLength); AStream.WriteByte(RPNLength);
AStream.Position := RecordSizePos; AStream.Position := RecordSizePos;
AStream.WriteWord(WordToLE(17 + RPNLength)); AStream.WriteWord(WordToLE(17 + RPNLength));
AStream.position := FinalPos;*) AStream.position := FinalPos;
end; end;
{******************************************************************* {*******************************************************************

View File

@ -97,6 +97,8 @@ type
{ TsSpreadBIFF5Writer } { TsSpreadBIFF5Writer }
TsSpreadBIFF5Writer = class(TsCustomSpreadWriter) TsSpreadBIFF5Writer = class(TsCustomSpreadWriter)
private
function FEKindToExcelID(AElement: TFEKind): Byte;
public public
// constructor Create; // constructor Create;
// destructor Destroy; override; // destructor Destroy; override;
@ -109,7 +111,7 @@ type
procedure WriteDimensions(AStream: TStream); procedure WriteDimensions(AStream: TStream);
procedure WriteEOF(AStream: TStream); procedure WriteEOF(AStream: TStream);
procedure WriteFont(AStream: TStream; AFont: TFPCustomFont); procedure WriteFont(AStream: TStream; AFont: TFPCustomFont);
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsFormula); override; procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsRPNFormula); override;
procedure WriteIndex(AStream: TStream); procedure WriteIndex(AStream: TStream);
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override; procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
@ -220,12 +222,41 @@ const
MASK_XF_VERT_ALIGN = $70; MASK_XF_VERT_ALIGN = $70;
const
{ TokenID values }
{ Binary Operator Tokens }
INT_EXCEL_TOKEN_TADD = $03;
INT_EXCEL_TOKEN_TSUB = $04;
INT_EXCEL_TOKEN_TMUL = $05;
INT_EXCEL_TOKEN_TDIV = $06;
INT_EXCEL_TOKEN_TPOWER = $07;
{ Constant Operand Tokens }
INT_EXCEL_TOKEN_TNUM = $1F;
{ Operand Tokens }
INT_EXCEL_TOKEN_TREFR = $24;
INT_EXCEL_TOKEN_TREFV = $44;
INT_EXCEL_TOKEN_TREFA = $64;
{ {
Exported functions Exported functions
} }
{ TsSpreadBIFF5Writer } { TsSpreadBIFF5Writer }
function TsSpreadBIFF5Writer.FEKindToExcelID(AElement: TFEKind): Byte;
begin
case AElement of
fekCell: Result := INT_EXCEL_TOKEN_TREFV;
fekAdd: Result := INT_EXCEL_TOKEN_TADD;
fekSub: Result := INT_EXCEL_TOKEN_TSUB;
fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL;
end;
end;
{******************************************************************* {*******************************************************************
* TsSpreadBIFF5Writer.WriteToFile () * TsSpreadBIFF5Writer.WriteToFile ()
* *
@ -550,15 +581,16 @@ end;
* AFormula array * AFormula array
* *
*******************************************************************} *******************************************************************}
procedure TsSpreadBIFF5Writer.WriteFormula(AStream: TStream; const ARow, procedure TsSpreadBIFF5Writer.WriteRPNFormula(AStream: TStream; const ARow,
ACol: Word; const AFormula: TsFormula); ACol: Word; const AFormula: TsRPNFormula);
{var var
FormulaResult: double; FormulaResult: double;
i: Integer; i: Integer;
RPNLength: Word; RPNLength: Word;
TokenArraySizePos, RecordSizePos, FinalPos: Int64;} TokenArraySizePos, RecordSizePos, FinalPos: Int64;
FormulaKind: Byte;
begin begin
(* RPNLength := 0; RPNLength := 0;
FormulaResult := 0.0; FormulaResult := 0.0;
{ BIFF Record header } { BIFF Record header }
@ -594,11 +626,12 @@ begin
for i := 0 to Length(AFormula) - 1 do for i := 0 to Length(AFormula) - 1 do
begin begin
{ Token identifier } { Token identifier }
AStream.WriteByte(AFormula[i].TokenID); FormulaKind := FEKindToExcelID(AFormula[i].ElementKind);
AStream.WriteByte(FormulaKind);
Inc(RPNLength); Inc(RPNLength);
{ Additional data } { Additional data }
case AFormula[i].TokenID of case FormulaKind of
{ binary operation tokens } { binary operation tokens }
@ -627,7 +660,7 @@ begin
AStream.WriteByte(RPNLength); AStream.WriteByte(RPNLength);
AStream.Position := RecordSizePos; AStream.Position := RecordSizePos;
AStream.WriteWord(WordToLE(22 + RPNLength)); AStream.WriteWord(WordToLE(22 + RPNLength));
AStream.position := FinalPos;*) AStream.position := FinalPos;
end; end;
{******************************************************************* {*******************************************************************