利用table组件删除重复数据时数据只是打了删除标记,但是却删不了,在VFP中可以删除.为什么?(200分)

G

guist

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个表,有HM和HF两个字段,其中HM、HF字段都允许有重复,
现在要删除HM、HF都一样的重复数据。如果HM一样而HF不同则保留。
Table1.Active:=False;
Table1.TableName:=ModifyForm.FileListBox1.FileName;//选择数据表
Table1.Active:=True;
Table1.First;
temphm:='';//临时数据用于存储HM字段的值,用来判断HM是否一样
temphf:=0.0;//临时数据用于存储HF字段的值,用来判断HF是否一样
for j:=0 to Table1.RecordCount-1 do
begin
if Length(temphm)<=0 then
begin
temphf:=Table1.FieldByName('hf').Asfloat;//给HN、HF赋初值
temphm:=Table1.FieldByName('hm').Asstring;
continue;
end;
oldhf:=ModifyForm.Table1.FieldByName('hf').Asfloat;//读取当前记录的HM、HF
oldhm:=ModifyForm.Table1.FieldByName('hm').Asstring;
if oldhm=temphm then //当前HM与临时HM一样,表示为HM重复数据
begin
if oldhf=temphf then//当前HM与临时HM一样,HF与临时HF一样,则删除
begin
ModifyForm.Table1.Delete;
i:=i+1;//统计做了删除的数据个数。
end
else ModifyForm.Table1.Next;//当前HM与临时HM一样,HF与临时HF不一样,则保留
end
else //当前HM与临时HM不一样,则将当前HM与HF,赋给临时HM、HF,
begin
temphm:=ModifyForm.Table1.FieldByName('hm').Asstring;
temphf:=ModifyForm.Table1.FieldByName('hf').Asfloat;
Table1.Next;
end;
end;
ModifyForm.Table1.Edit;//table 改为编辑模式,否则无法进行POST操作。
ModifyForm.Table1.Post;//提交删除。
ModifyForm.Table1.Close;

在实际的运行中,我的表中有6000多个重复记录,i是实际作了删除的记录数,发现2个问题:
1、如果i的数值接近6000 ,则重复的数据被打上删除标记,但是实际上并没有删除,
用Database Desktop 可以看到记录的个数没变,而用VISUAL FOXPRO打开文件
可以看见记录带有删除标记,提交后记录才被删除;
2、同样一个表,如果i的值有时还会为1或14。这和实际上的重复记录数相差很远。

请高手帮忙解决一下。
 
老兄DELETE完成后POST
 
我是在作完一个表的DELETE后,再POST的,做其他程序时都这样的,
 
没用的,bde里有pack
 
可否给出我的程序的改进方法.
 
你的程序不用改进,这是dBase、Foxbase数据库的特点,被删除的记录并不从物理上删除,
只是打一下删除记号而已。要想从物理上删除,必须调用IDAPI函数XXXPacketTable,前面
那几个字母记不得了,而且手上没带着以前做过的资料。另:《Delphi5 开发人员指南》上
有讲解。如果今天内你还找不到解决方法,我明早一准告诉你(今天白天我没法回家去)。
 
大概看了一下,程序思路好像有问题(具体没分析)
重复记录数固定否(如1、4、15、19四条记录重复,2、25两条记录重复,即不固定)
实践证明一下是否重复记录全删除了(或全打上删除记号了) //(重点)
 
我提前做了索引,
另外想起了另一个问题,DBF表如何建立主和次多个索引.
 
真正的删除:
procedure TForm1.Button1Click(Sender: TObject);
var
Error: DbiResult;
ErrorMsg: String;
Special: DBIMSG;
begin
table1.Active := False;
try
Table1.Exclusive := True;
Table1.Active := True;
Error := DbiPackTable(Table1.DBHandle, Table1.Handle, nil, szdBASE, True);
Table1.Active := False;
Table1.Exclusive := False;
finally
Table1.Active := True;
end;
case Error of
DBIERR_NONE:
ErrorMsg := 'Successful';
DBIERR_INVALIDPARAM:
ErrorMsg := 'The specified table name or the pointer to the table ' +
'name is NULL';
DBIERR_INVALIDHNDL:
ErrorMsg := 'The specified database handle or cursor handle is ' +
'invalid or NULL';
DBIERR_NOSUCHTABLE:
ErrorMsg := 'Table name does not exist';
DBIERR_UNKNOWNTBLTYPE:
ErrorMsg := 'Table type is unknown';
DBIERR_NEEDEXCLACCESS:
ErrorMsg := 'The table is not open in exclusive mode';
else
DbiGetErrorString(Error, Special);
ErrorMsg := '[' + IntToStr(Error) + ']: ' + Special;
end;
MessageDlg(ErrorMsg, mtWarning, [mbOk], 0);
end;
 
我在post后面添加如下代码,
BDE.DbiPackTable(Table1.DBHandle,Table1.Handle,Nil,szDBASE,True);
可是还是不行.另外还出现2中的情况,提示I=1;
 
用这个命令dbipacktable(tabcards.DBHandle,tabcards.Handle,NIL,NIL,true);
其中的tabcards为Table控件名
 
注意dbipacktable(tabcards.DBHandle,tabcards.Handle,NIL,NIL,true);
要在tabcards.delete之后用
 
多人接受答案了。
naughtboy的程序是对的,我接受了.
另外我发现TABLE做数据库时我遇到的题挺多的,我是自己摸索着学习DELPHI的,没有和高手学习的机会,
不知道naughtboy兄是如何做到这么详细的,是不是每次都使用了TRY和ERROR 来分析错误的问题,
可否给小弟点知道.
 
另一个问题,DBF表如何建立主和次多个索引在我另外一个帖子中有,今天刚写的
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1388759
需要注意的是dbf数据库需要将其中的abc.db改为abc.dbf,还有
TableType := ttparadox;改为TableType := ttDbase或ttDefault也可
 
顶部