记录的删除插入排序
删除一条记录的基本思路是获取当前记录的位置并把该位置后的记录逐个向前移动 文件在最后一条记录前截断
for i:=CurrentRec+ to Count do
begin
seek(MethodFilei)
read(MethodFileMethodRec)
seek(MethodFilei)
Write(MethodFileMethodRec)
end;
Truncate(MethodFile)
为避免误删除在进行删除操作前弹出一个消息框进行确认删除后要更新全局变量的值和显示内容
Count := Count ;
ChangeGrid;
完整的程序如下
procedure TRecFileFormDeleteButtonClick(Sender: TObject)
var
NewFile: MethodFileType;
MethodRec: TMethod;
NewFileName: String;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGridRow;
if CurrentRec < then Exit;
if MessageDlg(Delete Current Record ? mtConfirmation
[mbYes mbNo] ) = idYes then
begin
HazAttrtext := ;
for I := CurrentRec+ to Count do
begin
seek(MethodFilei)
read(MethodFileMethodRec)
seek(MethodFilei)
Write(MethodFileMethodRec)
end;
Truncate(MethodFile)
Count := Count;
ChangeGrid;
end;
end;
这里所显示的删除操作简单明了但在程序开始设计时我却走了一条弯路后来发现虽然这种方法用于记录的删除操作显得笨拙可笑但却恰恰是记录插入排序的思想
这种思想的核心是创建一个新文件保存更新后的内容若新文件顺利创建则删除原文件否则恢复原来的文件程序清单如下
procedure TRecFileFormDeleteButtonClick(Sender: TObject)
var
NewFile: MethodFileType;
MethodRec: TMethod;
NewFileName: String;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGridRow;
if CurrentRec < then Exit;
if MessageDlg(Delete Current Record ? mtConfirmation
[mbYes mbNo] ) = idYes then
begin
HazAttrtext := ;
NewFileName := ChangeFileExt(FileNamesav)
try
AssignFile(NewFileFileName)
ReWrite(NewFile)
Except
On EInOutError do
begin
Rename(MethodFileFileName)
Exit;
end;
end;
for i := to Count do
if I <> CurrentRec+ then
begin
MethodRec := GridToRec(i)
Write(NewFileMethodRec)
end;
closeFile(MethodFile)
try
AssignFile(MethodFileFilename)
Reset(MethodFile)
except
on EInOutError do
begin
DeleteFile(FileName)
AssignFile(MethodFileNewFileName)
Reset(MethodFile)
Rename(MethodFileFileName)
Exit;
end;
DeleteFile(NewFileName)
Count:=Count;
ChangeGrid;
end;
end;
对于记录插入方法基本同上对于排序可先将关键域读入排序而后再按排序结果对应的记录号顺序重写文件
结果综合
对不同方法的评估结果可按一定的公式进行综合当用户按下计算按钮时系统进行计算并把综合结果写入HazAttr只读编辑框中
为保证结果显示的正确性每次增加修改删除操作确认后HazAttr编辑框清空
编辑对话框的输入检查
当用户单击增加或修改按钮时系统将弹出一个编辑对话框让用户输入或修改记录内容其中的三个编辑框一个组合列表框分别对应TMethod 的四个域由于TMethod的Result域必须是[]间的小数因此当用户按OK键关闭对话框时应进行类型和范围检查
在VB中我做过同样的工作那时需要对用户输入的键码逐个进行判断但这种方法很繁琐很难做圆满(如不能很好地支持编辑键)而Object Pascal提供了更好的方法这种方法的关键就在于它的类型转换函数Val:
procedure Val(Str: String;var V; var Code: Integer)
V是由Str转换成的整型或实型数若字符串非法则出错位置返至Code;否则置Code为字符串非法并不会引发一个转换异常
如果转换后的数超出了我们的范围则显式把Code置为最后统一通过检测Code是否为来判断输入是否合法
我们把输入检查放在对话框的OnCloseQuery事件处理过程中如输入非法则禁止对话框关闭并将输入焦点置于Result编辑框中但假如用户按了Cancel按钮则这种检查是多余的为此定义一个布尔变量IsCancel对话框生成时置为False假如用户按下Cancel则置为True此时OnCloseQuery事件不进行输入检查
[] [] [] []