fpspreadsheet: Introduce infrastructure to fix formulas when sheets are added, renamed etc. Not functional at the moment.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6442 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-05-21 08:28:51 +00:00
parent 84f17e1bb2
commit b9ac1ebf02

View File

@ -704,6 +704,8 @@ type
{@@ Event procedure called when a worksheet is removed. ASheetIndex = -1 --> all sheets } {@@ Event procedure called when a worksheet is removed. ASheetIndex = -1 --> all sheets }
TsRemoveWorksheetEvent = procedure (Sender: TObject; ASheetIndex: Integer) of object; TsRemoveWorksheetEvent = procedure (Sender: TObject; ASheetIndex: Integer) of object;
{@@ FSome action has an effect on existing formulas which must be corrected. }
TsFormulaCorrection = (fcWorksheetRenamed);
{ TsWorkbook } { TsWorkbook }
@ -756,6 +758,9 @@ type
procedure PrepareBeforeReading; procedure PrepareBeforeReading;
procedure PrepareBeforeSaving; procedure PrepareBeforeSaving;
procedure FixFormula(ACell: PCell; ACorrection: TsFormulaCorrection;
AData: Pointer; AParam: PtrInt);
// procedure ReCalc; // procedure ReCalc;
public public
@ -854,8 +859,10 @@ type
function GetNumberFormat(AIndex: Integer): TsNumFormatParams; function GetNumberFormat(AIndex: Integer): TsNumFormatParams;
function GetNumberFormatCount: Integer; function GetNumberFormatCount: Integer;
{ Calculation } { Formulas }
procedure CalcFormulas; procedure CalcFormulas;
procedure FixFormulas(ACorrection: TsFormulaCorrection; AData: Pointer;
AParam: PtrInt);
{ Clipboard } { Clipboard }
procedure CopyToClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat; procedure CopyToClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
@ -4214,6 +4221,7 @@ begin
if (FWorkbook <> nil) then //and FWorkbook.ValidWorksheetName(AName) then if (FWorkbook <> nil) then //and FWorkbook.ValidWorksheetName(AName) then
begin begin
FName := AName; FName := AName;
FWorkbook.FixFormulas(fcWorksheetRenamed, self, 0);
if (FWorkbook.FLockCount = 0) and Assigned(FWorkbook.FOnRenameWorksheet) then if (FWorkbook.FLockCount = 0) and Assigned(FWorkbook.FOnRenameWorksheet) then
FWorkbook.FOnRenameWorksheet(FWorkbook, self); FWorkbook.FOnRenameWorksheet(FWorkbook, self);
end; end;
@ -9767,6 +9775,87 @@ begin
end; end;
end; end;
{@@ ----------------------------------------------------------------------------
Something was changed anywhere in the workbook which has an effect on existing
formulas. This procedure runs through all formulas and performs the
correction.
@param ACorrection Describes what has to be corrected.
Example: fcWorksheetRenamed means that a worksheet has
been renamed and the new name must be used in
corresponding formulas
@param AData A pointer with further information on the correction to
be made. Depends on ACorrection.
Example:
In the fcWorksheetRenamed example above this points to
the worksheet that was renamed.
@param AParam Provides additional information. Depends on ACorrection
-------------------------------------------------------------------------------}
procedure TsWorkbook.FixFormulas(ACorrection: TsFormulaCorrection;
AData: Pointer; AParam: PtrInt);
var
i: Integer;
sheet: TsWorksheet;
cell: PCell;
begin
if (boIgnoreFormulas in Options) then
exit;
inc(FCalculationLock);
try
for i := 0 to GetWorksheetCount-1 do begin
sheet := GetWorksheetByIndex(i);
for cell in sheet.Cells do begin
if HasFormula(cell) then
FixFormula(cell, ACorrection, AData, AParam);
end;
end;
finally
dec(FCalculationLock);
if (boAutoCalc in Options) then
CalcFormulas;
end;
end;
procedure TsWorkbook.FixFormula(ACell: PCell; ACorrection: TsFormulaCorrection;
AData: Pointer; AParam: PtrInt);
var
rpn: TsRPNFormula;
i: Integer;
elem: TsFormulaElement;
sheet: TsWorksheet;
begin
// Skeleton only - to be updated when new formula handling is finished.
(*
sheet := TsWorksheet(ACell^.Worksheet);
case ACorrection of
fcWorksheetrenamed:
if (cf3dFormula in ACell^.Flags) then
begin
// The rpn formula contains the worksheet index which does not
// change upon sheet renaming. Simple rebuilding the string formula
// from rpn will insert the new sheet name.
rpn := sheet.BuildRPNFormula(ACell);
ACell^.FormulaValue := sheet.ConvertRPNFormulaToStringFormula(rpn);
exit;
end;
end;
rpn := sheet.BuildRPNFormula(ACell);
for i:=0 to High(rpn) do begin
elem := rpn[i];
{
case ACorrection of
... // do specifice rpn corrections here
end;
}
end;
ACell^.FormulaValue := sheet.ConvertRPNFormulaToStringFormula(rpn);
*)
end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Writes the selected cells to a stream for usage in the clipboard. Writes the selected cells to a stream for usage in the clipboard.
Transfer to the clipboard has do be done by the calling routine since Transfer to the clipboard has do be done by the calling routine since