fpspreadsheet: Read results of formulas that return strings

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3045 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2014-05-14 16:30:33 +00:00
parent c36a5e80ce
commit c3f5600c0d
7 changed files with 172 additions and 69 deletions

View File

@ -69,6 +69,13 @@ begin
MyRPNFormula[2].ElementKind := fekROUND;
MyWorksheet.WriteRPNFormula(0, 5, MyRPNFormula);
// Write a string formula to G1 = "A" & "B"
MyWorksheet.WriteRPNFormula(0, 6, CreateRPNFormula(
RPNString('A',
RPNSTring('B',
RPNFunc(fekConcat,
nil)))));
// Write some string cells
MyWorksheet.WriteUTF8Text(1, 0, 'First');
MyWorksheet.WriteFont(1, 0, 'Arial', 12, [fssBold, fssItalic, fssUnderline], scRed);

View File

@ -156,7 +156,14 @@ begin
MyRPNFormula[1].ElementKind := fekABS;
MyWorksheet.WriteRPNFormula(0, 5, MyRPNFormula);
r:= 10;
// Write a string formula to G1 = "A" & "B"
MyWorksheet.WriteRPNFormula(0, 6, CreateRPNFormula(
RPNString('A',
RPNSTring('B',
RPNFunc(fekConcat,
nil)))));
r := 10;
// Write current date/time to cells B11:B16
MyWorksheet.WriteUTF8Text(r, 0, 'nfShortDate');
MyWorksheet.WriteDateTime(r, 1, now, nfShortDate);

View File

@ -126,7 +126,6 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="mainform"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="309"/>
@ -143,9 +142,6 @@
<TopLine Value="2539"/>
<CursorPos X="19" Y="2550"/>
<UsageCount Value="100"/>
<Bookmarks Count="1">
<Item0 X="33" Y="1214" ID="1"/>
</Bookmarks>
<Loaded Value="True"/>
</Unit2>
<Unit3>
@ -266,9 +262,12 @@
<UnitName Value="xlsbiff8"/>
<EditorIndex Value="5"/>
<WindowIndex Value="0"/>
<TopLine Value="61"/>
<CursorPos X="26" Y="70"/>
<TopLine Value="1747"/>
<CursorPos X="1" Y="1764"/>
<UsageCount Value="78"/>
<Bookmarks Count="1">
<Item0 X="1" Y="1761" ID="1"/>
</Bookmarks>
<Loaded Value="True"/>
</Unit17>
<Unit18>
@ -291,8 +290,8 @@
<UnitName Value="xlscommon"/>
<EditorIndex Value="4"/>
<WindowIndex Value="0"/>
<TopLine Value="1139"/>
<CursorPos X="12" Y="1157"/>
<TopLine Value="1207"/>
<CursorPos X="1" Y="1217"/>
<UsageCount Value="74"/>
<Loaded Value="True"/>
</Unit20>
@ -301,18 +300,19 @@
<UnitName Value="xlsbiff5"/>
<EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="1230"/>
<CursorPos X="39" Y="1257"/>
<TopLine Value="1363"/>
<CursorPos X="1" Y="1364"/>
<UsageCount Value="61"/>
<Loaded Value="True"/>
</Unit21>
<Unit22>
<Filename Value="..\..\xlsbiff2.pas"/>
<UnitName Value="xlsbiff2"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="7"/>
<WindowIndex Value="0"/>
<TopLine Value="225"/>
<CursorPos X="37" Y="224"/>
<TopLine Value="664"/>
<CursorPos X="30" Y="687"/>
<UsageCount Value="62"/>
<Loaded Value="True"/>
</Unit22>
@ -574,123 +574,127 @@
<UsageCount Value="12"/>
</Unit56>
</Units>
<JumpHistory Count="29" HistoryIndex="28">
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1365" Column="1" TopLine="1346"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1755" Column="19" TopLine="1715"/>
</Position1>
<Position2>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1366" Column="1" TopLine="1346"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1964" Column="1" TopLine="1924"/>
</Position2>
<Position3>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1624" Column="1" TopLine="1621"/>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1210" Column="81" TopLine="1176"/>
</Position3>
<Position4>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1627" Column="1" TopLine="1621"/>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1959" Column="1" TopLine="1919"/>
</Position4>
<Position5>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1630" Column="1" TopLine="1621"/>
<Caret Line="41" Column="1" TopLine="41"/>
</Position5>
<Position6>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1633" Column="1" TopLine="1621"/>
<Caret Line="1753" Column="1" TopLine="1738"/>
</Position6>
<Position7>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="11" Column="45" TopLine="1"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1968" Column="1" TopLine="1928"/>
</Position7>
<Position8>
<Filename Value="..\..\xlsbiff5.pas"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position8>
<Position9>
<Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="563" Column="1" TopLine="547"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="80" Column="21" TopLine="47"/>
</Position9>
<Position10>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="351" Column="26" TopLine="340"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1760" Column="1" TopLine="1744"/>
</Position10>
<Position11>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1611" Column="1" TopLine="1582"/>
<Caret Line="95" Column="22" TopLine="75"/>
</Position11>
<Position12>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1034" Column="35" TopLine="1026"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position12>
<Position13>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="2021" Column="1" TopLine="1991"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1524" Column="37" TopLine="1516"/>
</Position13>
<Position14>
<Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="82" Column="57" TopLine="52"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1649" Column="21" TopLine="1622"/>
</Position14>
<Position15>
<Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="1702" Column="5" TopLine="1672"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1527" Column="3" TopLine="1524"/>
</Position15>
<Position16>
<Filename Value="..\..\fpsutils.pas"/>
<Caret Line="634" Column="32" TopLine="609"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1758" Column="3" TopLine="1733"/>
</Position16>
<Position17>
<Filename Value="..\..\fpsutils.pas"/>
<Caret Line="629" Column="17" TopLine="612"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position17>
<Position18>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="266" Column="28" TopLine="244"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="51" Column="19" TopLine="18"/>
</Position18>
<Position19>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1150" Column="3" TopLine="1136"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="57" Column="11" TopLine="24"/>
</Position19>
<Position20>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="386" Column="15" TopLine="370"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="67" Column="13" TopLine="34"/>
</Position20>
<Position21>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1938" Column="1" TopLine="1908"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1394" Column="3" TopLine="1388"/>
</Position21>
<Position22>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1761" Column="3" TopLine="1738"/>
</Position22>
<Position23>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="393" Column="20" TopLine="368"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="95" Column="75" TopLine="76"/>
</Position23>
<Position24>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="796" Column="35" TopLine="771"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1749" Column="8" TopLine="1747"/>
</Position24>
<Position25>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="980" Column="14" TopLine="956"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="95" Column="55" TopLine="95"/>
</Position25>
<Position26>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1038" Column="14" TopLine="1013"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1748" Column="49" TopLine="1733"/>
</Position26>
<Position27>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1073" Column="12" TopLine="1048"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="95" Column="55" TopLine="95"/>
</Position27>
<Position28>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="524" Column="36" TopLine="519"/>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1749" Column="8" TopLine="1747"/>
</Position28>
<Position29>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1370" Column="1" TopLine="1358"/>
</Position29>
<Position30>
<Filename Value="..\..\xlscommon.pas"/>
<Caret Line="39" Column="3" TopLine="10"/>
</Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>

View File

@ -70,6 +70,7 @@ type
procedure ReadNumber(AStream: TStream); override;
procedure ReadRowColXF(AStream: TStream; out ARow, ACol: Cardinal; out AXF: Word); override;
procedure ReadRowInfo(AStream: TStream); override;
procedure ReadStringRecord(AStream: TStream; var AStringResult: String); override;
procedure ReadWindow2(AStream: TStream); override;
procedure ReadXF(AStream: TStream);
public
@ -662,6 +663,30 @@ begin
end;
end;
{ Reads a STRING record which contains the result of string formula. }
procedure TsSpreadBIFF2Reader.ReadStringRecord(AStream: TStream;
var AStringResult: String);
var
record_id: Word;
record_size: word;
len: Byte;
s: ansistring;
begin
record_id := WordLEToN(AStream.ReadWord);
if record_id <> INT_EXCEL_ID_STRING then
raise Exception.Create('ReadStringRecord: wrong record found.');
record_size := WordLEToN(AStream.ReadWord);
// The string is a byte-string with 16 bit length
len := AStream.ReadByte;
if len > 0 then begin
SetLength(s, Len);
AStream.ReadBuffer(s[1], len);
end else
s := '';
AStringResult := s;
end;
{ Reads the WINDOW2 record containing information like "show grid lines",
"show sheet headers", "panes are frozen", etc. }
procedure TsSpreadBIFF2Reader.ReadWindow2(AStream: TStream);

View File

@ -89,6 +89,7 @@ type
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
procedure ReadBoundsheet(AStream: TStream);
procedure ReadRichString(AStream: TStream);
procedure ReadStringRecord(AStream: TStream; var AStringResult: String); override;
procedure ReadXF(AStream: TStream);
public
{ General reading methods }
@ -1360,6 +1361,30 @@ begin
ApplyCellFormatting(ARow, ACol, XF);
end;
{ Reads a STRING record which contains the result of string formula. }
procedure TsSpreadBIFF5Reader.ReadStringRecord(AStream: TStream;
var AStringResult: String);
var
record_id: Word;
record_size: word;
len: Word;
s: ansistring;
begin
record_id := WordLEToN(AStream.ReadWord);
if record_id <> INT_EXCEL_ID_STRING then
raise Exception.Create('ReadStringRecord: wrong record found.');
record_size := WordLEToN(AStream.ReadWord);
// The string is a byte-string with 16 bit length
len := WordLEToN(AStream.ReadWord);
if len > 0 then begin
SetLength(s, Len);
AStream.ReadBuffer(s[1], len);
end else
s := '';
AStringResult := s;
end;
procedure TsSpreadBIFF5Reader.ReadFromFile(AFileName: string; AData: TsWorkbook);
var
MemStream: TMemoryStream;

View File

@ -91,6 +91,8 @@ type
procedure ReadBlank(AStream: TStream); override;
procedure ReadLabel(AStream: TStream); override;
procedure ReadRichString(const AStream: TStream);
protected
procedure ReadStringRecord(AStream: TStream; var AStringResult: String); override;
public
destructor Destroy; override;
{ General reading methods }
@ -1743,6 +1745,23 @@ begin
ApplyCellFormatting(ARow, ACol, XF);
end;
procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream;
var AStringResult: String);
var
record_id: Word;
record_size: word;
p: Cardinal;
begin
record_id := WordLEToN(AStream.ReadWord);
if record_id <> INT_EXCEL_ID_STRING then
raise Exception.Create('ReadStringRecord: wrong record found.');
record_size := WordLEToN(AStream.ReadWord);
p := AStream.Position;
AStringResult := ReadWideString(AStream, false);
AStream.Position := p + record_size;
end;
procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream);
function FixLineStyle(dw: DWord): TsLineStyle;

View File

@ -36,6 +36,7 @@ const
INT_EXCEL_ID_BLANK = $0201; // BIFF2: $0001
INT_EXCEL_ID_NUMBER = $0203; // BIFF2: $0003
INT_EXCEL_ID_LABEL = $0204; // BIFF2: $0004
INT_EXCEL_ID_STRING = $0207; // BIFF2: $0007;
INT_EXCEL_ID_ROW = $0208; // BIFF2: $0008
INT_EXCEL_ID_INDEX = $020B; // BIFF2: $000B
INT_EXCEL_ID_WINDOW2 = $023E; // BIFF2: $003E
@ -417,6 +418,8 @@ type
procedure ReadRowColXF(AStream: TStream; out ARow, ACol: Cardinal; out AXF: Word); virtual;
// Read row info
procedure ReadRowInfo(AStream: TStream); virtual;
// Read STRING record (result of string formula)
procedure ReadStringRecord(AStream: TStream; var AResultString: String); virtual;
// Read WINDOW2 record (gridlines, sheet headers)
procedure ReadWindow2(AStream: TStream); virtual;
public
@ -939,6 +942,7 @@ var
nf: TsNumberFormat;
nd: Word;
nfs: String;
resultStr: String;
begin
{ BIFF Record header }
@ -969,7 +973,10 @@ begin
if (Data[6] = $FF) and (Data[7] = $FF) then
case Data[0] of
0: FWorksheet.WriteUTF8Text(ARow, ACol, '(String)');
0: begin
ReadStringRecord(AStream, resultStr);
FWorksheet.WriteUTF8Text(ARow, ACol, resultStr);
end;
1: FWorksheet.WriteUTF8Text(ARow, ACol, '(Bool)');
2: FWorksheet.WriteUTF8Text(ARow, ACol, '(ERROR)');
3: FWorksheet.WriteUTF8Text(ARow, ACol, '(empty)');
@ -1199,6 +1206,15 @@ begin
// changed manually.
end;
{ Reads a STRING record. It immediately precedes a FORMULA record which has a
string result.
Returns here just a dummy string. Has to be overridden to read the real text. }
procedure TsSpreadBIFFReader.ReadStringRecord(AStream: TStream;
var AResultString: String);
begin
AResultString := '(STRING)';
end;
{ Reads the WINDOW2 record containing information like "show grid lines",
"show sheet headers", "panes are frozen", etc.
The record structure is slightly different for BIFF5 and BIFF8, but we use