how to redo or undo in fpspreadsheet [done with snippet] lazarus / 49-FPSpreadsheet ---------------------------------------------------------------------- Mongkey · 2025-12-19 04:12 is there anyone here could do redo or undo under fpspreadsheet worksheetgrid editor? Thank you. ---------------------------------------------------------------------- Xenno · 2025-12-19 14:26 The simplest way would be saving the sheet to (temporary) files before any action. Keep the file names in a LIFO list (stack). Just load the file in reverse order to Undo or the opposite to Redo. These snapshot files must be removed when no longer needed. To save space, you may use compression with a little consequences. ---------------------------------------------------------------------- Mongkey · 2025-12-20 01:27 thank you bro, I got vision from gr*k, this code fully worked: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TCellEdit_ = record    Row, Col: integer;    OldValue, NewValue: variant;  end;   TUndoRedoList = array of TCellEdit_; var  UndoStack, RedoStack: array of TUndoRedoList;   OldCellValue, NewCellValue: variant; procedure Undo;var  LastActions: TUndoRedoList;  Act: TCellEdit_;  i: integer;begin  if Length(UndoStack) = 0 then Exit;   // Pop the last group of actions  LastActions := UndoStack[High(UndoStack)];  SetLength(UndoStack, Length(UndoStack) - 1);   // Push the whole group to Redo stack (important for batch undo)  SetLength(RedoStack, Length(RedoStack) + 1);  RedoStack[High(RedoStack)] := LastActions;   // Revert all actions in the group  for i := 0 to High(LastActions) do  begin    Act := LastActions[i];    Form1.WorksheetGrid.Cells[Act.Col, Act.Row] := Act.OldValue;  end;   // Optional: if you want the edit box to show the current (now old) value  if Length(LastActions) > 0 then  begin  Act := LastActions[High(LastActions)]; // last edited cell  end;end; procedure Redo;var  LastActions: TUndoRedoList;  Act: TCellEdit_;  i: integer;begin  if Length(RedoStack) = 0 then Exit;   // Pop the last group from redo  LastActions := RedoStack[High(RedoStack)];  SetLength(RedoStack, Length(RedoStack) - 1);   // Push the whole group back to Undo stack  SetLength(UndoStack, Length(UndoStack) + 1);  UndoStack[High(UndoStack)] := LastActions;   // Reapply all actions  for i := 0 to High(LastActions) do  begin    Act := LastActions[i];    Form1.WorksheetGrid.Cells[Act.Col, Act.Row] := Act.NewValue;  end;   // Update edit box to show the new value of the last edited cell  if Length(LastActions) > 0 then  begin    Act := LastActions[High(LastActions)];  end;end; procedure TForm1.WorksheetGridEditingDone(Sender: TObject);var  Action_: TCellEdit_;  CurrentValue: variant;begin  CurrentValue := WorksheetGrid.Cells[WorksheetGrid.Col, WorksheetGrid.Row];  edit1.Text := vartostr(OldCellValue);  // Only record if value actually changed  if vartostr(CurrentValue) <> vartostr(OldCellValue) then  begin    Action_.Row := WorksheetGrid.Row;    Action_.Col := WorksheetGrid.Col;    Action_.OldValue := OldCellValue;    Action_.NewValue := CurrentValue;     // Add a new group containing this single edit    SetLength(UndoStack, Length(UndoStack) + 1);    SetLength(UndoStack[High(UndoStack)], 1);    UndoStack[High(UndoStack)][0] := Action_;     // Clear redo stack when new edit is made (standard undo/redo behavior)    SetLength(RedoStack, 0);     //ShowMessage('add data');  end;end; procedure TForm1.WorksheetGridSelectCell(Sender: TObject; aCol, aRow: integer;  var CanSelect: boolean);begin  OldCellValue := WorksheetGrid.Cells[aCol, aRow]; end;    i hope this one usable for others, cheers! Thank you