刪除記錄的基本思路:獲取當前記錄位置,將後續記錄逐個向前移動,最後在文件倒數第二條記錄處截斷(Truncate)。為防誤刪,操作前彈出確認對話框;刪除後更新全局變量 Count 並刷新顯示(ChangeGrid)。
procedure TRecFileForm.DeleteButtonClick(Sender: TObject);
var
MethodRec: TMethod;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGrid1.Row - 1;
if CurrentRec < 0 then Exit;
if MessageDlg('Delete Current Record?', mtConfirmation, [mbYes, mbNo], 0) = idYes then
begin
HazAttr.Text := '';
for I := CurrentRec + 1 to Count - 1 do
begin
Seek(MethodFile, i);
Read(MethodFile, MethodRec);
Seek(MethodFile, i - 1);
Write(MethodFile, MethodRec);
end;
Truncate(MethodFile);
Count := Count - 1;
ChangeGrid;
end;
end;
作者初期採用「創建新文件保存更新內容,成功則替換原文件」的策略,雖顯笨拙,但這恰恰是記錄插入和排序的核心思想。
procedure TRecFileForm.DeleteButtonClick(Sender: TObject);
var
NewFile: MethodFileType;
MethodRec: TMethod;
NewFileName: String;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGrid1.Row - 1;
if CurrentRec < 0 then Exit;
if MessageDlg('Delete Current Record?', mtConfirmation, [mbYes, mbNo], 0) = idYes then
begin
HazAttr.Text := '';
NewFileName := ChangeFileExt(FileName, '.sav');
try
AssignFile(NewFile, FileName);
Rewrite(NewFile);
except
on EInOutError do
begin
Rename(MethodFile, FileName);
Exit;
end;
end;
for i := 1 to Count do
if I <> CurrentRec + 1 then
begin
MethodRec := GridToRec(i);
Write(NewFile, MethodRec);
end;
CloseFile(MethodFile);
try
AssignFile(MethodFile, FileName);
Reset(MethodFile);
except
on EInOutError do
begin
DeleteFile(FileName);
AssignFile(MethodFile, NewFileName);
Reset(MethodFile);
Rename(MethodFile, FileName);
Exit;
end;
end;
DeleteFile(NewFileName);
Count := Count - 1;
ChangeGrid;
end;
end;
這種「新文件替換舊文件」模式雖增加 I/O 開銷,但邏輯清晰、易於擴展,特別適合插入、排序等涉及大量記錄位移的操作。