From c9280da776f9d0eecff41cb2421de36e261273c1 Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Mon, 30 May 2011 10:03:04 +0000 Subject: [PATCH] FPSpreadsheet: Implements enough to write SUM(A1:A5) formulas in BIFF8 git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1660 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../examples/other/test_write_formula.lpi | 148 +----------------- .../examples/other/test_write_formula.pas | 12 +- components/fpspreadsheet/xlsbiff8.pas | 61 +++++++- components/fpspreadsheet/xlscommon.pas | 14 +- 4 files changed, 78 insertions(+), 157 deletions(-) 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 @@ + <ResourceType Value="res"/> <UseXPManifest Value="True"/> <Icon Value="0"/> - <ActiveWindowIndexAtStart Value="0"/> </General> <i18n> <EnableI18N LFM="False"/> @@ -20,7 +20,7 @@ <VersionInfo> <StringTable ProductVersion=""/> </VersionInfo> - <BuildModes Count="1" Active="Default"> + <BuildModes Count="1"> <Item1 Name="Default" Default="True"/> </BuildModes> <PublishOptions> @@ -39,152 +39,13 @@ <PackageName Value="laz_fpspreadsheet"/> </Item1> </RequiredPackages> - <Units Count="4"> + <Units Count="1"> <Unit0> <Filename Value="test_write_formula.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="test_write_formula"/> - <IsVisibleTab Value="True"/> - <EditorIndex Value="0"/> - <WindowIndex Value="0"/> - <TopLine Value="23"/> - <CursorPos X="42" Y="45"/> - <UsageCount Value="20"/> - <Loaded Value="True"/> </Unit0> - <Unit1> - <Filename Value="../../fpspreadsheet.pas"/> - <UnitName Value="fpspreadsheet"/> - <EditorIndex Value="3"/> - <WindowIndex Value="0"/> - <TopLine Value="38"/> - <CursorPos X="13" Y="66"/> - <UsageCount Value="10"/> - <Loaded Value="True"/> - </Unit1> - <Unit2> - <Filename Value="../../xlsbiff8.pas"/> - <UnitName Value="xlsbiff8"/> - <EditorIndex Value="1"/> - <WindowIndex Value="0"/> - <TopLine Value="840"/> - <CursorPos X="10" Y="862"/> - <UsageCount Value="10"/> - <Loaded Value="True"/> - </Unit2> - <Unit3> - <Filename Value="../../xlscommon.pas"/> - <UnitName Value="xlscommon"/> - <EditorIndex Value="2"/> - <WindowIndex Value="0"/> - <TopLine Value="125"/> - <CursorPos X="1" Y="150"/> - <UsageCount Value="10"/> - <Loaded Value="True"/> - </Unit3> </Units> - <JumpHistory Count="25" HistoryIndex="24"> - <Position1> - <Filename Value="test_write_formula.pas"/> - <Caret Line="3" Column="1" TopLine="1"/> - </Position1> - <Position2> - <Filename Value="test_write_formula.pas"/> - <Caret Line="179" Column="1" TopLine="136"/> - </Position2> - <Position3> - <Filename Value="test_write_formula.pas"/> - <Caret Line="29" Column="17" TopLine="10"/> - </Position3> - <Position4> - <Filename Value="test_write_formula.pas"/> - <Caret Line="27" Column="24" TopLine="1"/> - </Position4> - <Position5> - <Filename Value="../../fpspreadsheet.pas"/> - <Caret Line="205" Column="64" TopLine="181"/> - </Position5> - <Position6> - <Filename Value="test_write_formula.pas"/> - <Caret Line="35" Column="22" TopLine="3"/> - </Position6> - <Position7> - <Filename Value="test_write_formula.pas"/> - <Caret Line="13" Column="42" TopLine="1"/> - </Position7> - <Position8> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="524" Column="14" TopLine="493"/> - </Position8> - <Position9> - <Filename Value="../../fpspreadsheet.pas"/> - <Caret Line="1147" Column="27" TopLine="1123"/> - </Position9> - <Position10> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="124" Column="25" TopLine="94"/> - </Position10> - <Position11> - <Filename Value="../../fpspreadsheet.pas"/> - <Caret Line="1072" Column="74" TopLine="1067"/> - </Position11> - <Position12> - <Filename Value="../../fpspreadsheet.pas"/> - <Caret Line="206" Column="70" TopLine="175"/> - </Position12> - <Position13> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="850" Column="14" TopLine="831"/> - </Position13> - <Position14> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="104" Column="35" TopLine="102"/> - </Position14> - <Position15> - <Filename Value="../../xlscommon.pas"/> - <Caret Line="81" Column="76" TopLine="49"/> - </Position15> - <Position16> - <Filename Value="../../xlscommon.pas"/> - <Caret Line="40" Column="1" TopLine="17"/> - </Position16> - <Position17> - <Filename Value="../../xlscommon.pas"/> - <Caret Line="145" Column="41" TopLine="129"/> - </Position17> - <Position18> - <Filename Value="../../xlscommon.pas"/> - <Caret Line="91" Column="40" TopLine="69"/> - </Position18> - <Position19> - <Filename Value="../../xlscommon.pas"/> - <Caret Line="149" Column="3" TopLine="128"/> - </Position19> - <Position20> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="104" Column="35" TopLine="102"/> - </Position20> - <Position21> - <Filename Value="../../xlsbiff8.pas"/> - <Caret Line="857" Column="72" TopLine="835"/> - </Position21> - <Position22> - <Filename Value="test_write_formula.pas"/> - <Caret Line="52" Column="1" TopLine="18"/> - </Position22> - <Position23> - <Filename Value="test_write_formula.pas"/> - <Caret Line="42" Column="27" TopLine="20"/> - </Position23> - <Position24> - <Filename Value="test_write_formula.pas"/> - <Caret Line="45" Column="15" TopLine="23"/> - </Position24> - <Position25> - <Filename Value="test_write_formula.pas"/> - <Caret Line="46" Column="38" TopLine="23"/> - </Position25> - </JumpHistory> </ProjectOptions> <CompilerOptions> <Version Value="10"/> @@ -196,6 +57,9 @@ <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> </SearchPaths> <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> <CompilerPath Value="$(CompPath)"/> </Other> </CompilerOptions> 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;