fpspreadsheet: improves Excel 5 RPN formulas, add ABS and ROUND functions

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@833 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2009-06-09 21:34:58 +00:00
parent bb04dbc318
commit f3259be492
11 changed files with 319 additions and 190 deletions

View File

@ -15,6 +15,7 @@ uses
var
MyWorkbook: TsWorkbook;
MyWorksheet: TsWorksheet;
MyRPNFormula: TsRPNFormula;
MyDir: string;
begin
// Open the output file
@ -30,6 +31,24 @@ begin
MyWorksheet.WriteNumber(0, 2, 3.0);
MyWorksheet.WriteNumber(0, 3, 4.0);
// Write the formula E1 = ABS(A1)
SetLength(MyRPNFormula, 2);
MyRPNFormula[0].ElementKind := fekCell;
MyRPNFormula[0].Col := 0;
MyRPNFormula[0].Row := 0;
MyRPNFormula[1].ElementKind := fekABS;
MyWorksheet.WriteRPNFormula(0, 4, MyRPNFormula);
// Write the formula F1 = ROUND(A1, 0)
SetLength(MyRPNFormula, 3);
MyRPNFormula[0].ElementKind := fekCell;
MyRPNFormula[0].Col := 0;
MyRPNFormula[0].Row := 0;
MyRPNFormula[1].ElementKind := fekNum;
MyRPNFormula[1].DoubleValue := 0.0;
MyRPNFormula[2].ElementKind := fekROUND;
MyWorksheet.WriteRPNFormula(0, 5, MyRPNFormula);
// Write some string cells
MyWorksheet.WriteUTF8Text(1, 0, 'First');
MyWorksheet.WriteUTF8Text(1, 1, 'Second');

View File

@ -11,7 +11,7 @@
<TargetFileExt Value=".exe"/>
<Title Value="excel5write"/>
<UseAppBundle Value="False"/>
<ActiveEditorIndexAtStart Value="1"/>
<ActiveEditorIndexAtStart Value="6"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
@ -33,13 +33,13 @@
<PackageName Value="laz_fpspreadsheet"/>
</Item1>
</RequiredPackages>
<Units Count="14">
<Units Count="21">
<Unit0>
<Filename Value="excel5write.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="excel5write"/>
<CursorPos X="25" Y="56"/>
<TopLine Value="37"/>
<CursorPos X="61" Y="49"/>
<TopLine Value="45"/>
<EditorIndex Value="0"/>
<UsageCount Value="309"/>
<Loaded Value="True"/>
@ -68,38 +68,34 @@
<Unit4>
<Filename Value="..\..\xlsbiff5.pas"/>
<UnitName Value="xlsbiff5"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
<EditorIndex Value="3"/>
<CursorPos X="1" Y="59"/>
<TopLine Value="47"/>
<EditorIndex Value="4"/>
<UsageCount Value="140"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\..\fpsutils.pas"/>
<UnitName Value="fpsutils"/>
<CursorPos X="1" Y="49"/>
<TopLine Value="30"/>
<EditorIndex Value="2"/>
<CursorPos X="1" Y="11"/>
<TopLine Value="1"/>
<EditorIndex Value="3"/>
<UsageCount Value="140"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\..\xlsbiff2.pas"/>
<UnitName Value="xlsbiff2"/>
<CursorPos X="1" Y="286"/>
<CursorPos X="39" Y="281"/>
<TopLine Value="275"/>
<EditorIndex Value="6"/>
<UsageCount Value="139"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\..\fpolestorage.pas"/>
<UnitName Value="fpolestorage"/>
<CursorPos X="30" Y="654"/>
<TopLine Value="642"/>
<EditorIndex Value="7"/>
<CursorPos X="38" Y="48"/>
<TopLine Value="41"/>
<UsageCount Value="139"/>
<Loaded Value="True"/>
</Unit7>
<Unit8>
<Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\classesh.inc"/>
@ -116,10 +112,10 @@
<Unit10>
<Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/>
<CursorPos X="79" Y="836"/>
<TopLine Value="819"/>
<EditorIndex Value="1"/>
<UsageCount Value="92"/>
<CursorPos X="12" Y="205"/>
<TopLine Value="193"/>
<EditorIndex Value="2"/>
<UsageCount Value="93"/>
<Loaded Value="True"/>
</Unit10>
<Unit11>
@ -131,143 +127,158 @@
<Unit12>
<Filename Value="..\..\fpsopendocument.pas"/>
<UnitName Value="fpsopendocument"/>
<CursorPos X="20" Y="383"/>
<TopLine Value="369"/>
<EditorIndex Value="4"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
<CursorPos X="53" Y="49"/>
<TopLine Value="44"/>
<UsageCount Value="11"/>
</Unit12>
<Unit13>
<Filename Value="..\..\xlsbiff8.pas"/>
<UnitName Value="xlsbiff8"/>
<CursorPos X="34" Y="339"/>
<TopLine Value="317"/>
<CursorPos X="56" Y="53"/>
<TopLine Value="45"/>
<UsageCount Value="11"/>
</Unit13>
<Unit14>
<Filename Value="..\..\xlscommon.pas"/>
<UnitName Value="xlscommon"/>
<CursorPos X="19" Y="15"/>
<TopLine Value="1"/>
<EditorIndex Value="1"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit14>
<Unit15>
<Filename Value="..\..\uvirtuallayer.pas"/>
<UnitName Value="uvirtuallayer"/>
<CursorPos X="1" Y="17"/>
<TopLine Value="5"/>
<EditorIndex Value="5"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit13>
</Unit15>
<Unit16>
<Filename Value="..\..\uvirtuallayer_ole.pas"/>
<UnitName Value="uvirtuallayer_ole"/>
<CursorPos X="37" Y="61"/>
<TopLine Value="56"/>
<EditorIndex Value="6"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit16>
<Unit17>
<Filename Value="..\..\uvirtuallayer_ole_helpers.pas"/>
<UnitName Value="uvirtuallayer_ole_helpers"/>
<CursorPos X="94" Y="3"/>
<TopLine Value="1"/>
<UsageCount Value="10"/>
</Unit17>
<Unit18>
<Filename Value="..\..\uvirtuallayer_ole_types.pas"/>
<UnitName Value="uvirtuallayer_ole_types"/>
<CursorPos X="89" Y="6"/>
<TopLine Value="1"/>
<UsageCount Value="10"/>
</Unit18>
<Unit19>
<Filename Value="..\..\uvirtuallayer_stream.pas"/>
<UnitName Value="uvirtuallayer_stream"/>
<CursorPos X="71" Y="10"/>
<TopLine Value="1"/>
<UsageCount Value="10"/>
</Unit19>
<Unit20>
<Filename Value="..\..\..\..\..\lazarus\lcl\masks.pas"/>
<UnitName Value="Masks"/>
<CursorPos X="35" Y="9"/>
<TopLine Value="1"/>
<UsageCount Value="10"/>
</Unit20>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<JumpHistory Count="21" HistoryIndex="20">
<Position1>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="314" Column="39" TopLine="296"/>
</Position1>
<Position2>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="479" Column="1" TopLine="469"/>
</Position2>
<Position3>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="470" Column="1" TopLine="460"/>
</Position3>
<Position4>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="217" Column="3" TopLine="205"/>
</Position4>
<Position5>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="218" Column="23" TopLine="208"/>
</Position5>
<Position6>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="78" Column="10" TopLine="66"/>
</Position6>
<Position7>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="375" Column="1" TopLine="367"/>
</Position7>
<Position8>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="76" Column="17" TopLine="65"/>
</Position8>
<Position9>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="363" Column="1" TopLine="357"/>
</Position9>
<Position10>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="77" Column="7" TopLine="76"/>
</Position10>
<Position11>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="137" Column="40" TopLine="129"/>
</Position11>
<Position12>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="563" Column="5" TopLine="544"/>
</Position12>
<Position13>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="486" Column="5" TopLine="467"/>
</Position13>
<Position14>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="510" Column="5" TopLine="491"/>
</Position14>
<Position15>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="94" Column="46" TopLine="84"/>
</Position15>
<Position16>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="686" Column="5" TopLine="667"/>
</Position16>
<Position17>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="567" Column="5" TopLine="548"/>
</Position17>
<Position18>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="622" Column="1" TopLine="618"/>
</Position18>
<Position19>
<Filename Value="..\..\fpolestorage.pas"/>
<Caret Line="621" Column="29" TopLine="611"/>
</Position19>
<Position20>
</Position1>
<Position2>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="100" Column="17" TopLine="92"/>
</Position20>
<Position21>
</Position2>
<Position3>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="615" Column="34" TopLine="593"/>
</Position21>
<Position22>
<Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position22>
<Position23>
<Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="56" Column="88" TopLine="43"/>
</Position23>
<Position24>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position24>
<Position25>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="69" Column="88" TopLine="56"/>
</Position25>
<Position26>
</Position3>
<Position4>
<Filename Value="excel5write.lpr"/>
<Caret Line="47" Column="30" TopLine="33"/>
</Position26>
<Position27>
</Position4>
<Position5>
<Filename Value="excel5write.lpr"/>
<Caret Line="53" Column="21" TopLine="40"/>
</Position27>
<Position28>
</Position5>
<Position6>
<Filename Value="excel5write.lpr"/>
<Caret Line="54" Column="27" TopLine="40"/>
</Position28>
<Position29>
</Position6>
<Position7>
<Filename Value="excel5write.lpr"/>
<Caret Line="52" Column="38" TopLine="43"/>
</Position29>
<Position30>
</Position7>
<Position8>
<Filename Value="excel5write.lpr"/>
<Caret Line="56" Column="25" TopLine="37"/>
</Position30>
</Position8>
<Position9>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="101" Column="27" TopLine="89"/>
</Position9>
<Position10>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="263" Column="5" TopLine="256"/>
</Position10>
<Position11>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="101" Column="48" TopLine="90"/>
</Position11>
<Position12>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="250" Column="3" TopLine="238"/>
</Position12>
<Position13>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="245" Column="28" TopLine="234"/>
</Position13>
<Position14>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="268" Column="40" TopLine="248"/>
</Position14>
<Position15>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="101" Column="54" TopLine="90"/>
</Position15>
<Position16>
<Filename Value="..\..\uvirtuallayer.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position16>
<Position17>
<Filename Value="..\..\uvirtuallayer.pas"/>
<Caret Line="962" Column="3" TopLine="960"/>
</Position17>
<Position18>
<Filename Value="..\..\uvirtuallayer.pas"/>
<Caret Line="567" Column="1" TopLine="563"/>
</Position18>
<Position19>
<Filename Value="..\..\uvirtuallayer_ole.pas"/>
<Caret Line="70" Column="3" TopLine="61"/>
</Position19>
<Position20>
<Filename Value="..\..\uvirtuallayer_ole.pas"/>
<Caret Line="69" Column="5" TopLine="58"/>
</Position20>
<Position21>
<Filename Value="..\..\uvirtuallayer_ole.pas"/>
<Caret Line="68" Column="5" TopLine="56"/>
</Position21>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>

View File

@ -55,6 +55,14 @@ begin
MyRPNFormula[2].ElementKind := fekAdd;
MyWorksheet.WriteRPNFormula(0, 4, MyRPNFormula);
// Write the formula F1 = ABS(A1)
SetLength(MyRPNFormula, 2);
MyRPNFormula[0].ElementKind := fekCell;
MyRPNFormula[0].Col := 0;
MyRPNFormula[0].Row := 0;
MyRPNFormula[1].ElementKind := fekABS;
MyWorksheet.WriteRPNFormula(0, 5, MyRPNFormula);
//MyFormula.FormulaStr := '';
// Creates a new worksheet

View File

@ -44,13 +44,22 @@ type
{@@ Expanded formula. Used by backend modules. Provides more information then the text only }
TFEKind = (fekCell, fekAdd, fekSub, fekDiv, fekMul,
fekOpSUM);
TFEKind = (
{ Basic operands }
fekCell, fekNum,
{ Basic operations }
fekAdd, fekSub, fekDiv, fekMul,
{ Build-in Functions}
fekABS, fekROUND,
{ Other operations }
fekOpSUM
);
TsFormulaElement = record
ElementKind: TFEKind;
Row, Row2: Word; // zero-based
Col, Col2: Byte; // zero-based
Param1, Param2: Word; // Extra parameters
DoubleValue: double;
end;

View File

@ -14,7 +14,7 @@
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Files Count="17">
<Files Count="18">
<Item1>
<Filename Value="fpolestorage.pas"/>
<UnitName Value="fpolestorage"/>
@ -83,6 +83,10 @@
<Filename Value="fpolebasic.pas"/>
<UnitName Value="fpolebasic"/>
</Item17>
<Item18>
<Filename Value="xlscommon.pas"/>
<UnitName Value="xlscommon"/>
</Item18>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">

View File

@ -8,12 +8,9 @@ interface
uses
fpolestorage, fpsallformats, fpsopendocument, fpspreadsheet, xlsbiff2,
xlsbiff5, xlsbiff8, xlsxooxml, fpsutils, fpszipper,
{$ifdef USE_NEW_OLE}
uvirtuallayer_types,
xlsbiff5, xlsbiff8, xlsxooxml, fpsutils, fpszipper, uvirtuallayer_types,
uvirtuallayer, uvirtuallayer_ole, uvirtuallayer_ole_helpers,
uvirtuallayer_ole_types, uvirtuallayer_stream, fpolebasic,
{$endif}
uvirtuallayer_ole_types, uvirtuallayer_stream, fpolebasic, xlscommon,
LazarusPackageIntf;
implementation

View File

@ -5,7 +5,10 @@ unit uvirtuallayer;
interface
uses
Classes, SysUtils,strutils, Graphics,
Classes, SysUtils,strutils,
{$ifdef FPSUSELCL}
Graphics,
{$endif}
uvirtuallayer_types,uvirtuallayer_stream;
type
@ -57,7 +60,9 @@ protected
function intfCopy(const ASourceFileName,ATargetFileName: UTF8String): Boolean; virtual;
function intfMove(const ASourceFileName,ATargetFileName: UTF8String): Boolean; virtual;
{$ifdef FPSUSELCL}
function IntfGetIcon(const APath: UTF8String): TIcon; virtual;
{$endif}
procedure Lock(); virtual;
procedure Unlock(); virtual;
@ -94,7 +99,9 @@ public
property RootLayer: TVirtualLayer read GetRootLayer;
property ParentLayer: TVirtualLayer read FParentLayer write SetParentLayer;
{$ifdef FPSUSELCL}
function GetIcon(const APath: UTF8String): TIcon;
{$endif}
Constructor Create(const AVirtualLayerStream: TStream);
procedure PrepareDestroy(); virtual;
@ -556,11 +563,13 @@ begin
MountPath+RemoveRootPathDelimiter(ATargetFileName));
end;
{$ifdef FPSUSELCL}
function TVirtualLayer.IntfGetIcon(const APath: UTF8String): TIcon;
begin
Result:=nil;
if Length(APath)=0 then Result:=nil; //Avoid hint.
end;
{$endif}
function TVirtualLayer.AcrossLayersMove(const ASourceFileName,
ATargetFileName: UTF8String): Boolean;
@ -820,6 +829,7 @@ begin
Unlock();
end;
{$ifdef FPSUSELCL}
function TVirtualLayer.GetIcon(const APath: UTF8String): TIcon;
var
VL: TVirtualLayer;
@ -832,6 +842,7 @@ begin
Result:=IntfGetIcon(APath);
end;
end;
{$endif}
function TVirtualLayer.PathToVirtualLayer(const APath: UTF8String
): TVirtualLayer;

View File

@ -63,8 +63,11 @@ unit uvirtuallayer_ole;
interface
uses
Classes, SysUtils, Masks
,uvirtuallayer_types
Classes, SysUtils,
{.$ifdef FPSUSELCL}
Masks,
{.$endif}
uvirtuallayer_types
,uvirtuallayer
,uvirtuallayer_ole_helpers
,uvirtuallayer_ole_types

View File

@ -31,7 +31,7 @@ interface
uses
Classes, SysUtils,
fpspreadsheet, fpsutils;
fpspreadsheet, xlscommon, fpsutils;
type
@ -54,7 +54,7 @@ type
TsSpreadBIFF2Writer = class(TsCustomSpreadWriter)
private
function FEKindToExcelID(AElement: TFEKind): Byte;
function FEKindToExcelID(AElement: TFEKind; var AParamsNum, AFuncNum: Byte): Byte;
public
{ General writing methods }
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
@ -86,34 +86,34 @@ const
INT_EXCEL_CHART = $0020;
INT_EXCEL_MACRO_SHEET = $0040;
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;
{ TsSpreadBIFF2Writer }
function TsSpreadBIFF2Writer.FEKindToExcelID(AElement: TFEKind): Byte;
function TsSpreadBIFF2Writer.FEKindToExcelID(AElement: TFEKind; var AParamsNum, AFuncNum: Byte): Byte;
begin
AFuncNum := 0;
case AElement of
{ Operands }
fekCell: Result := INT_EXCEL_TOKEN_TREFV;
fekNum: Result := INT_EXCEL_TOKEN_TNUM;
{ Operators }
fekAdd: Result := INT_EXCEL_TOKEN_TADD;
fekSub: Result := INT_EXCEL_TOKEN_TSUB;
fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL;
{ Build-in functions }
fekABS:
begin
Result := INT_EXCEL_TOKEN_FUNCVAR_V;
AParamsNum := 1;
AFuncNum := INT_EXCEL_SHEET_FUNC_ABS;
end;
fekROUND:
begin
Result := INT_EXCEL_TOKEN_FUNCVAR_V;
AParamsNum := 2;
AFuncNum := INT_EXCEL_SHEET_FUNC_ROUND;
end;
end;
end;
@ -185,7 +185,7 @@ var
i: Integer;
RPNLength: Word;
TokenArraySizePos, RecordSizePos, FinalPos: Cardinal;
FormulaKind: Byte;
FormulaKind, ParamsNum, ExtraInfo: Byte;
begin
RPNLength := 0;
FormulaResult := 0.0;
@ -223,7 +223,7 @@ begin
for i := 0 to Length(AFormula) - 1 do
begin
{ Token identifier }
FormulaKind := FEKindToExcelID(AFormula[i].ElementKind);
FormulaKind := FEKindToExcelID(AFormula[i].ElementKind, ParamsNum, ExtraInfo);
AStream.WriteByte(FormulaKind);
Inc(RPNLength);
@ -248,6 +248,13 @@ begin
Inc(RPNLength, 3);
end;
INT_EXCEL_TOKEN_FUNCVAR_V:
begin
AStream.WriteByte(ParamsNum);
AStream.WriteByte(ExtraInfo);
Inc(RPNLength, 2);
end;
end;
end;

View File

@ -58,6 +58,7 @@ interface
uses
Classes, SysUtils, fpcanvas,
fpspreadsheet,
xlscommon,
{$ifdef USE_NEW_OLE}
fpolebasic,
{$else}
@ -98,7 +99,7 @@ type
TsSpreadBIFF5Writer = class(TsCustomSpreadWriter)
private
function FEKindToExcelID(AElement: TFEKind): Byte;
function FEKindToExcelID(AElement: TFEKind; var AParamsNum: Byte; var AExtra: Word): Byte;
public
// constructor Create;
// destructor Destroy; override;
@ -222,38 +223,39 @@ const
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
}
{ TsSpreadBIFF5Writer }
function TsSpreadBIFF5Writer.FEKindToExcelID(AElement: TFEKind): Byte;
function TsSpreadBIFF5Writer.FEKindToExcelID(AElement: TFEKind;
var AParamsNum: Byte; var AExtra: Word): Byte;
begin
AExtra := 0;
case AElement of
{ Operands }
fekCell: Result := INT_EXCEL_TOKEN_TREFV;
fekNum: Result := INT_EXCEL_TOKEN_TNUM;
{ Operators }
fekAdd: Result := INT_EXCEL_TOKEN_TADD;
fekSub: Result := INT_EXCEL_TOKEN_TSUB;
fekDiv: Result := INT_EXCEL_TOKEN_TDIV;
fekMul: Result := INT_EXCEL_TOKEN_TMUL;
{ Build-in Function }
fekABS:
begin
Result := INT_EXCEL_TOKEN_FUNCVAR_V;
AParamsNum := 1;
AExtra := INT_EXCEL_SHEET_FUNC_ABS;
end;
fekROUND:
begin
Result := INT_EXCEL_TOKEN_FUNCVAR_V;
AParamsNum := 2;
AExtra := INT_EXCEL_SHEET_FUNC_ROUND;
end;
end;
end;
@ -588,7 +590,8 @@ var
i: Integer;
RPNLength: Word;
TokenArraySizePos, RecordSizePos, FinalPos: Int64;
FormulaKind: Byte;
FormulaKind, ParamsNum: Byte;
ExtraInfo: Word;
begin
RPNLength := 0;
FormulaResult := 0.0;
@ -626,7 +629,7 @@ begin
for i := 0 to Length(AFormula) - 1 do
begin
{ Token identifier }
FormulaKind := FEKindToExcelID(AFormula[i].ElementKind);
FormulaKind := FEKindToExcelID(AFormula[i].ElementKind, ParamsNum, ExtraInfo);
AStream.WriteByte(FormulaKind);
Inc(RPNLength);
@ -651,6 +654,26 @@ begin
Inc(RPNLength, 3);
end;
{
sOffset Size Contents
0 1 22H (tFuncVarR), 42H (tFuncVarV), 62H (tFuncVarA)
1 1 Number of arguments
Bit Mask Contents
6-0 7FH Number of arguments
7 80H 1 = User prompt for macro commands (shown by a question mark
following the command name)
2 2 Index to a sheet function
Bit Mask Contents
14-0 7FFFH Index to a built-in sheet function (➜3.11) or a macro command
15 8000H 0 = Built-in function; 1 = Macro command
}
INT_EXCEL_TOKEN_FUNCVAR_V:
begin
AStream.WriteByte(ParamsNum);
AStream.WriteWord(WordToLE(ExtraInfo));
Inc(RPNLength, 3);
end;
end;
end;

View File

@ -0,0 +1,37 @@
unit xlscommon;
{$mode objfpc}{$H+}
interface
const
{ Formula constants 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;
{ Function Tokens }
INT_EXCEL_TOKEN_FUNCVAR_R = $22;
INT_EXCEL_TOKEN_FUNCVAR_V = $42;
INT_EXCEL_TOKEN_FUNCVAR_A = $62;
{ Built-in functions }
INT_EXCEL_SHEET_FUNC_ABS = 24;
INT_EXCEL_SHEET_FUNC_ROUND = 27;
implementation
end.