//Added by Zlatko Matić
procedure TMainForm.AcRecalculateFormulasExecute(Sender: TObject);
var
WasDeferred: Boolean;
SavedOptions: TsWorkbookOptions;
OriginalCursor: TCursor; // Variable to store the original cursor
StartTime, EndTime: Int64;
begin
OriginalCursor := Screen.Cursor; // Save the current cursor
Screen.Cursor := crHourglass; // Change to hourglass cursor
Application.ProcessMessages;
StartTime := GetHighResolutionTime;
try
// Save current workbook options and deferral flag.
SavedOptions := WorkbookSource.Workbook.Options;
WasDeferred := DeferFormulaCalculation;
if WasDeferred then
begin
DeferFormulaCalculation := False;
AcSettingsDeferCalculation.Checked := False;
WorkbookSource.Workbook.Options := WorkbookSource.Workbook.Options + [boAutoCalc];
end;
try
RecalculateFormulas; // Perform recalculation logic here...
finally
// Restore the original workbook options and deferral state.
DeferFormulaCalculation := WasDeferred;
WorkbookSource.Workbook.Options := SavedOptions;
AcSettingsDeferCalculation.Checked := WasDeferred;
end;
finally
EndTime := GetHighResolutionTime; // Capture end time
Screen.Cursor := OriginalCursor; // Restore the original cursor
Application.ProcessMessages;
// Show completion message with flexible time formatting
ShowMessage(Format('(Re)calculation completed in %s.', [FormatElapsedTime(EndTime - StartTime)]));
end;
end;
//------------------------------------------------------------------------
// MANUALLY RECALCULATE SELECTED CELL OR RANGE (Added by Zlatko Matić)
//------------------------------------------------------------------------
procedure TMainForm.RecalculateSelectedRange(Selection: TRect);
var
sheet: TsWorksheet;
row, col: Integer;
ACell: PCell;
SavedOptions: TsWorkbookOptions;
WasDeferred: Boolean;
OriginalCursor: TCursor;
StartTime, EndTime: Int64;
f: PsFormula; // local variable for the parsed formula pointer
begin
OriginalCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
Application.ProcessMessages;
StartTime := GetHighResolutionTime;
try
sheet := WorkbookSource.Worksheet;
if sheet = nil then
begin
ShowMessage('Error: Worksheet is not assigned.');
Exit;
end;
// Save current options and deferral state.
SavedOptions := WorkbookSource.Workbook.Options;
WasDeferred := DeferFormulaCalculation;
try
// Temporarily disable automatic recalculation for a targeted update.
WorkbookSource.Workbook.Options := SavedOptions - [boAutoCalc, boCalcBeforeSaving];
DeferFormulaCalculation := False;
for row := Selection.Top - 1 to Selection.Bottom - 1 do
for col := Selection.Left - 1 to Selection.Right - 1 do
begin
// Check if the coordinates are within bounds.
if (row < 0) or (row > sheet.GetLastRowIndex) or (col < 0) or (col > sheet.GetLastColIndex) then
Continue;
ACell := sheet.FindCell(row, col);
//if Assigned(ACell) and (ACell^.ContentType = cctFormula) then // does not work!
if Assigned(ACell) and (cfHasFormula in ACell^.Flags) then
begin
f := sheet.Formulas.FindFormula(row, col);
if Assigned(f) then begin
//ShowMessage(Format('Parsed formula found for cell (%d, %d): %p', [row, col, f]));
sheet.CalcFormula(f);
end
else
ShowMessage(Format('Error: No parsed formula found for cell (%d, %d).', [row, col]));
end;
end;
WorksheetGrid.InvalidateRange(Selection);
except
on E: Exception do
ShowMessage('Error recalculating range: ' + E.Message);
end;
// Restore original workbook options and deferral flag.
WorkbookSource.Workbook.Options := SavedOptions;
DeferFormulaCalculation := WasDeferred;
finally
EndTime := GetHighResolutionTime;
Screen.Cursor := OriginalCursor;
Application.ProcessMessages;
ShowMessage(Format('Range recalculation completed in %s.', [FormatElapsedTime(EndTime - StartTime)]));
end;
end;
procedure TMainForm.AcRecalculateSelectedCellExecute(Sender: TObject);
var
Selection: TRect;
OriginalCursor: TCursor;
begin
OriginalCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
Application.ProcessMessages;
try
// Create a one-cell selection at the active cell.
Selection := Rect(WorksheetGrid.Col, WorksheetGrid.Row, WorksheetGrid.Col, WorksheetGrid.Row);
RecalculateSelectedRange(Selection);
finally
Screen.Cursor := OriginalCursor;
Application.ProcessMessages;
end;
end;
procedure TMainForm.AcRecalculateSelectedRangeExecute(Sender: TObject);
var
OriginalCursor: TCursor;
begin
OriginalCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
Application.ProcessMessages;
try
RecalculateSelectedRange(WorksheetGrid.Selection);
finally
Screen.Cursor := OriginalCursor;
Application.ProcessMessages;
end;
end;