You've already forked lazarus-ccr
fpspreadsheet: Reorganize formula recalculation code to achieve more stability against infinite loops.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3477 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -513,6 +513,7 @@ type
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
procedure CalcRPNFormula(ACell: PCell);
|
procedure CalcRPNFormula(ACell: PCell);
|
||||||
|
function CellUsedInFormula(ARow, ACol: Cardinal): Boolean;
|
||||||
|
|
||||||
procedure ChangedCell(ARow, ACol: Cardinal);
|
procedure ChangedCell(ARow, ACol: Cardinal);
|
||||||
procedure ChangedFont(ARow, ACol: Cardinal);
|
procedure ChangedFont(ARow, ACol: Cardinal);
|
||||||
@ -678,7 +679,6 @@ type
|
|||||||
|
|
||||||
{ Formulas }
|
{ Formulas }
|
||||||
procedure CalcFormulas;
|
procedure CalcFormulas;
|
||||||
function CellUsedInFormula(ARow, ACol: Cardinal): Boolean;
|
|
||||||
|
|
||||||
{ Data manipulation methods - For Cells }
|
{ Data manipulation methods - For Cells }
|
||||||
procedure CopyCell(AFromRow, AFromCol, AToRow, AToCol: Cardinal; AFromWorksheet: TsWorksheet);
|
procedure CopyCell(AFromRow, AFromCol, AToRow, AToCol: Cardinal; AFromWorksheet: TsWorksheet);
|
||||||
@ -1728,6 +1728,10 @@ procedure TsWorksheet.CalcFormulas;
|
|||||||
var
|
var
|
||||||
node: TAVLTreeNode;
|
node: TAVLTreeNode;
|
||||||
begin
|
begin
|
||||||
|
// prevent infinite loop due to triggering of formula calculation whenever
|
||||||
|
// a cell changes during execution of CalcFormulas.
|
||||||
|
FWorkbook.FCalculating := true;
|
||||||
|
try
|
||||||
// Step 1 - mark all formula cells as "not calculated"
|
// Step 1 - mark all formula cells as "not calculated"
|
||||||
node := FCells.FindLowest;
|
node := FCells.FindLowest;
|
||||||
while Assigned(node) do begin
|
while Assigned(node) do begin
|
||||||
@ -1742,6 +1746,9 @@ begin
|
|||||||
CalcFormulaCallback(Node.Data, nil);
|
CalcFormulaCallback(Node.Data, nil);
|
||||||
node := FCells.FindSuccessor(node);
|
node := FCells.FindSuccessor(node);
|
||||||
end;
|
end;
|
||||||
|
finally
|
||||||
|
FWorkbook.FCalculating := false;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -1907,17 +1914,13 @@ end;
|
|||||||
}
|
}
|
||||||
procedure TsWorksheet.ChangedCell(ARow, ACol: Cardinal);
|
procedure TsWorksheet.ChangedCell(ARow, ACol: Cardinal);
|
||||||
begin
|
begin
|
||||||
if not FWorkbook.FCalculating and (boAutoCalc in FWorkbook.Options) then begin
|
if not FWorkbook.FCalculating and (boAutoCalc in FWorkbook.Options) then
|
||||||
if CellUsedInFormula(ARow, ACol) then begin
|
begin
|
||||||
FWorkbook.FCalculating := true;
|
if CellUsedInFormula(ARow, ACol) then
|
||||||
try
|
|
||||||
CalcFormulas;
|
CalcFormulas;
|
||||||
finally
|
|
||||||
FWorkbook.FCalculating := false;
|
|
||||||
end;
|
end;
|
||||||
end;
|
if Assigned(FOnChangeCell) then
|
||||||
end;
|
FOnChangeCell(Self, ARow, ACol);
|
||||||
if Assigned(FOnChangeCell) then FOnChangeCell(Self, ARow, ACol);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
|
Reference in New Issue
Block a user