spready: Update to recent changes in fpspreadsheet formula engine

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6490 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-06-12 20:06:46 +00:00
parent 947657a4ac
commit dad93e638e
3 changed files with 59 additions and 32 deletions

View File

@ -6,7 +6,7 @@ interface
uses uses
Classes, SysUtils, Classes, SysUtils,
fpstypes, fpspreadsheet, fpsReaderWriter, xlsCommon; fpstypes, fpsReaderWriter, xlsCommon;
type type
TsSYLKField = record TsSYLKField = record
@ -30,7 +30,7 @@ type
procedure ProcessLine(const ALine: String); procedure ProcessLine(const ALine: String);
procedure ProcessRecord(ARecordType: String; const AFields: TsSYLKFields); procedure ProcessRecord(ARecordType: String; const AFields: TsSYLKFields);
public public
constructor Create(AWorkbook: TsWorkbook); override; constructor Create(AWorkbook: TsBasicWorkbook); override;
procedure ReadFromFile(AFileName: String; APassword: String = ''; procedure ReadFromFile(AFileName: String; APassword: String = '';
AParams: TsStreamParams = []); override; AParams: TsStreamParams = []); override;
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override; procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
@ -62,7 +62,7 @@ type
procedure WriteNumberFormatList(AStream: TStream); procedure WriteNumberFormatList(AStream: TStream);
procedure WriteOptions(AStream: TStream); procedure WriteOptions(AStream: TStream);
public public
constructor Create(AWorkbook: TsWorkbook); override; constructor Create(AWorkbook: TsBasicWorkbook); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override; procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end; end;
@ -87,13 +87,13 @@ var
implementation implementation
uses uses
fpsUtils, fpsNumFormat; fpsUtils, fpsNumFormat, fpspreadsheet;
{==============================================================================} {==============================================================================}
{ TsSYLKReader } { TsSYLKReader }
{==============================================================================} {==============================================================================}
constructor TsSYLKReader.Create(AWorkbook: TsWorkbook); constructor TsSYLKReader.Create(AWorkbook: TsBasicWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
FWorksheetName := 'Sheet1'; // will be replaced by filename FWorksheetName := 'Sheet1'; // will be replaced by filename
@ -121,17 +121,20 @@ var
sval, expr: String; sval, expr: String;
val: Double; val: Double;
cell: PCell; cell: PCell;
sheet: TsWorksheet;
begin begin
sheet := FWorksheet as TsWorksheet;
col := StrToInt(GetFieldValue(AFields, 'X')) - 1; col := StrToInt(GetFieldValue(AFields, 'X')) - 1;
row := StrToInt(GetFieldValue(AFields, 'Y')) - 1; row := StrToInt(GetFieldValue(AFields, 'Y')) - 1;
cell := FWorksheet.GetCell(row, col); cell := sheet.GetCell(row, col);
// Formula // Formula
expr := GetFieldValue(AFields, 'E'); // expression in R1C1 syntax expr := GetFieldValue(AFields, 'E'); // expression in R1C1 syntax
if expr <> '' then if expr <> '' then
begin begin
expr := 'A1'; // to do: Convert R1C1 expression to A1 expression! expr := 'A1'; // to do: Convert R1C1 expression to A1 expression!
FWorksheet.WriteFormula(cell, expr); // to do!!!! sheet.WriteFormula(cell, expr); // to do!!!!
exit; exit;
end; end;
@ -142,13 +145,13 @@ begin
begin begin
sval := UnquoteStr(sval); sval := UnquoteStr(sval);
if (sval = 'TRUE') or (sval = 'FALSE') then if (sval = 'TRUE') or (sval = 'FALSE') then
FWorksheet.WriteBoolValue(cell, (sval = 'TRUE')) sheet.WriteBoolValue(cell, (sval = 'TRUE'))
else else
FWorksheet.WriteText(cell, UnquoteStr(sval)) sheet.WriteText(cell, UnquoteStr(sval))
// to do: error values // to do: error values
end else begin end else begin
val := StrToFloat(sval, FPointSeparatorSettings); val := StrToFloat(sval, FPointSeparatorSettings);
FWorksheet.WriteNumber(cell, val); sheet.WriteNumber(cell, val);
// to do: dates // to do: dates
end; end;
end; end;
@ -165,7 +168,10 @@ var
ha: TsHorAlignment; ha: TsHorAlignment;
val: Double; val: Double;
P: PChar; P: PChar;
sheet: TsWorksheet;
begin begin
sheet := FWorksheet as TsWorksheet;
nf := nfGeneral; nf := nfGeneral;
ha := haDefault; ha := haDefault;
decs := 0; decs := 0;
@ -223,10 +229,10 @@ begin
begin begin
if not TryStrToInt(scol, col) then exit; if not TryStrToInt(scol, col) then exit;
if not TryStrToInt(srow, row) then exit; if not TryStrToInt(srow, row) then exit;
cell := FWorksheet.GetCell(row, col); cell := sheet.GetCell(row, col);
FWorksheet.WriteNumberFormat(cell, nf, decs); sheet.WriteNumberFormat(cell, nf, decs);
FWorksheet.WriteHorAlignment(cell, ha); sheet.WriteHorAlignment(cell, ha);
end; end;
end; end;
@ -257,7 +263,7 @@ begin
TryStrToFloat(sval, val, FPointSeparatorSettings) then TryStrToFloat(sval, val, FPointSeparatorSettings) then
begin begin
for col := col1-1 to col2-1 do for col := col1-1 to col2-1 do
FWorksheet.WriteColWidth(col, val, suChars); sheet.WriteColWidth(col, val, suChars);
end; end;
end; end;
end; end;
@ -350,7 +356,7 @@ begin
Unused(AParams); Unused(AParams);
// Create worksheet // Create worksheet
FWorksheet := FWorkbook.AddWorksheet(FWorksheetName, true); FWorksheet := (FWorkbook as TsWorkbook).AddWorksheet(FWorksheetName, true);
for i:=0 to AStrings.Count-1 do for i:=0 to AStrings.Count-1 do
ProcessLine(AStrings[i]); ProcessLine(AStrings[i]);
@ -361,7 +367,7 @@ end;
{ TsSYLKWriter } { TsSYLKWriter }
{==============================================================================} {==============================================================================}
constructor TsSYLKWriter.Create(AWorkbook: TsWorkbook); constructor TsSYLKWriter.Create(AWorkbook: TsBasicWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
FDateMode := SYLKSettings.DateMode; FDateMode := SYLKSettings.DateMode;
@ -378,9 +384,13 @@ var
nfp: TsNumFormatParams; nfp: TsNumFormatParams;
style: String; style: String;
fnt: TsFont; fnt: TsFont;
wkBook: TsWorkbook;
begin begin
Result := ''; Result := '';
cellFmt := FWorkbook.GetPointerToCellFormat(ACell^.FormatIndex);
wkBook := FWorkbook as TsWorkbook;
cellFmt := wkBook.GetPointerToCellFormat(ACell^.FormatIndex);
if cellFmt <> nil then if cellFmt <> nil then
begin begin
// Number format --> field ";P" // Number format --> field ";P"
@ -388,7 +398,7 @@ begin
decs := '0'; // decimal places decs := '0'; // decimal places
if (uffNumberFormat in cellFmt^.UsedFormattingFields) then begin if (uffNumberFormat in cellFmt^.UsedFormattingFields) then begin
Result := Result + Format(';P%d', [cellFmt^.NumberFormatIndex+1]); // +1 because of General format not in list Result := Result + Format(';P%d', [cellFmt^.NumberFormatIndex+1]); // +1 because of General format not in list
nfp := FWorkbook.GetNumberFormat(cellFmt^.NumberFormatIndex); nfp := wkBook.GetNumberFormat(cellFmt^.NumberFormatIndex);
case nfp.Sections[0].NumFormat of case nfp.Sections[0].NumFormat of
nfFixed : ch1 := 'F'; nfFixed : ch1 := 'F';
nfCurrency : ch1 := 'C'; nfCurrency : ch1 := 'C';
@ -414,7 +424,7 @@ begin
style := ''; style := '';
if (uffFont in cellFmt^.UsedFormattingFields) then if (uffFont in cellFmt^.UsedFormattingFields) then
begin begin
fnt := FWorkbook.GetFont(cellFmt^.FontIndex); fnt := wkBook.GetFont(cellFmt^.FontIndex);
if (fssBold in fnt.Style) then style := style + 'D'; if (fssBold in fnt.Style) then style := style + 'D';
if (fssItalic in fnt.Style) then style := style + 'I'; if (fssItalic in fnt.Style) then style := style + 'I';
end; end;
@ -438,7 +448,8 @@ end;
function TsSYLKWriter.GetFormulaStr(ACell: PCell): String; function TsSYLKWriter.GetFormulaStr(ACell: PCell): String;
begin begin
if HasFormula(ACell) then if HasFormula(ACell) then
Result := ';E' + FWorksheet.ConvertFormulaDialect(ACell, fdExcelR1C1) else Result := ';E' + (FWorksheet as TsWorksheet).ConvertFormulaDialect(ACell, fdExcelR1C1)
else
Result := ''; Result := '';
end; end;
@ -487,7 +498,7 @@ begin
cctUTF8String: cctUTF8String:
WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell); WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell);
end; end;
if FWorksheet.HasComment(ACell) then if (FWorksheet as TsWorksheet).HasComment(ACell) then
WriteComment(AStream, ACell); WriteComment(AStream, ACell);
end; end;
@ -501,7 +512,7 @@ procedure TsSYLKWriter.WriteComment(AStream: TStream; ACell: PCell);
var var
comment: String; comment: String;
begin begin
comment := FWorksheet.ReadComment(ACell); comment := (FWorksheet as TsWorksheet).ReadComment(ACell);
if comment <> '' then if comment <> '' then
AppendToStream(AStream, Format( AppendToStream(AStream, Format(
'C;Y%d;X%d;A%s' + LineEnding, [ACell^.Row+1, ACell^.Col+1, comment])); 'C;Y%d;X%d;A%s' + LineEnding, [ACell^.Row+1, ACell^.Col+1, comment]));
@ -526,12 +537,15 @@ end;
the row and column counts. the row and column counts.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSYLKWriter.WriteDimensions(AStream: TStream); procedure TsSYLKWriter.WriteDimensions(AStream: TStream);
var
sheet: TsWorksheet;
begin begin
sheet := FWorksheet as TsWorksheet;
AppendToStream(AStream, Format( AppendToStream(AStream, Format(
'B;Y%d;X%d;D%d %d %d %d' + LineEnding, [ 'B;Y%d;X%d;D%d %d %d %d' + LineEnding, [
FWorksheet.GetLastRowIndex+1, FWorksheet.GetLastColIndex+1, sheet.GetLastRowIndex+1, sheet.GetLastColIndex+1,
FWorksheet.GetFirstRowIndex, FWorksheet.GetFirstColIndex, sheet.GetFirstRowIndex, sheet.GetFirstColIndex,
FWorksheet.GetLastRowIndex, FWorksheet.GetLastColIndex sheet.GetLastRowIndex, sheet.GetLastColIndex
])); ]));
end; end;
@ -615,12 +629,15 @@ var
nfp: TsNumFormatParams; nfp: TsNumFormatParams;
nfs: String; nfs: String;
i, j: Integer; i, j: Integer;
wkbook: TsWorkbook;
begin begin
wkbook := FWorkbook as TsWorkbook;
AppendToStream(AStream, AppendToStream(AStream,
'P;PGeneral' + LineEnding); 'P;PGeneral' + LineEnding);
for i:=0 to FWorkbook.GetNumberFormatCount-1 do begin for i:=0 to wkBook.GetNumberFormatCount-1 do begin
nfp := FWorkbook.GetNumberFormat(i); nfp := wkBook.GetNumberFormat(i);
nfs := BuildFormatStringFromSection(nfp.Sections[0]); nfs := BuildFormatStringFromSection(nfp.Sections[0]);
for j:=1 to High(nfp.Sections) do for j:=1 to High(nfp.Sections) do
nfs := nfs + ';;' + BuildFormatStringFromSection(nfp.Sections[j]); nfs := nfs + ';;' + BuildFormatStringFromSection(nfp.Sections[j]);
@ -648,18 +665,22 @@ end;
procedure TsSYLKWriter.WriteToStream(AStream: TStream; procedure TsSYLKWriter.WriteToStream(AStream: TStream;
AParams: TsStreamParams = []); AParams: TsStreamParams = []);
var
wkBook: TsWorkbook;
begin begin
Unused(AParams); Unused(AParams);
if (FSheetIndex < 0) or (FSheetIndex >= FWorkbook.GetWorksheetCount) then wkbook := FWorkbook as TsWorkbook;
if (FSheetIndex < 0) or (FSheetIndex >= wkBook.GetWorksheetCount) then
raise Exception.Create('[TsSYLKWriter.WriteToStream] Non-existing worksheet.'); raise Exception.Create('[TsSYLKWriter.WriteToStream] Non-existing worksheet.');
FWorksheet := FWorkbook.GetWorksheetByIndex(FSheetIndex); FWorksheet := wkBook.GetWorksheetByIndex(FSheetIndex);
WriteHeader(AStream); WriteHeader(AStream);
WriteNumberFormatList(AStream); WriteNumberFormatList(AStream);
WriteDimensions(AStream); WriteDimensions(AStream);
WriteOptions(AStream); WriteOptions(AStream);
WriteCellsToStream(AStream, FWorksheet.Cells); WriteCellsToStream(AStream, (FWorksheet as TsWorksheet).Cells);
WriteEndOfFile(AStream); WriteEndOfFile(AStream);
end; end;

View File

@ -7,7 +7,7 @@ interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ButtonPanel, ExtCtrls, ComCtrls, StdCtrls, ButtonPanel, ExtCtrls, ComCtrls, StdCtrls,
fpsCSV, fpsTypes, fpsCSV,
sCtrls; sCtrls;
type type

View File

@ -84,7 +84,10 @@
<Unit2> <Unit2>
<Filename Value="scsvparamsform.pas"/> <Filename Value="scsvparamsform.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<ComponentName Value="CSVParamsForm"/>
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="sCSVParamsForm"/>
</Unit2> </Unit2>
<Unit3> <Unit3>
<Filename Value="sctrls.pas"/> <Filename Value="sctrls.pas"/>
@ -195,7 +198,7 @@
</Linking> </Linking>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>
<Exceptions Count="5"> <Exceptions Count="6">
<Item1> <Item1>
<Name Value="EAbort"/> <Name Value="EAbort"/>
</Item1> </Item1>
@ -211,6 +214,9 @@
<Item5> <Item5>
<Name Value="ECalcEngine"/> <Name Value="ECalcEngine"/>
</Item5> </Item5>
<Item6>
<Name Value="EFpSpreadsheet"/>
</Item6>
</Exceptions> </Exceptions>
</Debugging> </Debugging>
</CONFIG> </CONFIG>