急切求助! 插入记录后数据行显示问题 ( 积分: 100 )

  • 主题发起人 主题发起人 xhqing
  • 开始时间 开始时间
X

xhqing

Unregistered / Unconfirmed
GUEST, unregistred user!
我在DBGrid中插入一行保存后到了最后边,DBGrid的数据源的数据集是ADOQuery1.
我把ADOQuery1.sort:='辅助编号 asc'写在AfterPost事件里或OnNewRecord事件里或AfterOpen事件里, 但是不行,保存后还是自动到了最后一行,而且还会出错"由于将在索引、 主关键字、或关系中创建重复的值,请求对表的改变没有成功。 改变该字段中的或包含重复数据的字段中的数据,删除索引或重新定义索引以允许重复的值并再试一次。",或提示"索引或主关键字不能包含一个空(Null)值。".
请问:1、如果另外做个按钮,又觉得不方便,请问排序的代码写在什么事件里?或者有其它实现方法.
2、如何更改从插入记录之后的数据行的"辅助编号"的序号值?我Access2000数据表的主键是"职工号".该有关代码写在谁的什么事件里?
怎么解决?谢谢!
举个例子:
辅助编号 姓名
1 a
2 b
3 c
5 e
6 f
我在3与5之间插入一条记录4,但录入后,4会跳到6的后面,不会跳到3的后面。另外如何修改"辅助编号"值,即:从插入记录之后的数据行的"辅助编号"的序号值加 1 .
我查过以前的有关讨论,还是没有能解决问题,敬请大家帮忙,环境为:Delphi 7 + Access2000, 在此十分感谢!谢谢您!
 
with adoquery1 do
begin
..
sql.add('order by 辅助编号');
open;
end;
这个试试
 
请问把它写在什么事件里?
 
这个问题很简单,你在设计表的时候,把那个辅助编号设为主键字段,再把它的[字段大小]设为长整型,再把[新值]设为递增,排序的问题只要写在SQL里面就可以了。ORDER BY 辅助字段就可以了,如果你是按[辅助字段]默认的字段排序的话,ORDER BY都不用了,试试罗
 
如果还不行,你就在ADOQuery1AfterPost事件中写入
ADOQUERY.CLOSE;
ADOQUERY.OPEN;
你出现这样的原因主要是因为你没有用功能按钮去实现表操作,你为什么不考虑下加几个
新增/修改/删除/保存/取消/刷新 这样的按钮呢,这样就好多了,不过你这种情况也有罗,就是要录入大量数据时,就是这样的,录入快,但至少可以加/保存/取消/删除,这些按钮呀
 
这是 ADO 的 BUG 引起的,换成 BDE 就正常了。
 
谢谢大家的关心,这么晚了还能给我回答问题,多谢你们的热情和关心!
HJ.Yao提出的想法,把"辅助编号"设为"自动编号"的"递增"型,我以前试过了,我现在又试了一下,不行,那个"辅助编号"不会按我们的需要去增加,如我现删除了4号记录,再增加4号记录,则程序会把4号记录的"辅助编号"字段自动编号为原先记录总数加1;又如我现在输入完6条记录,而我又发现在第5行位置,漏掉了一行数据,想在第6行之前增加一行,位置排在第5行,而它又会把5号记录的"辅助编号"字段自动编号为原先记录总数加1.这样我需要按"辅助字段"升序排序又达不到目的.
还敬请大家帮忙!
 
用 Clone!
Sn:= QryDetail.FieldByName('Sn').AsInteger; //¨ú¥X·í«e°O¿ý½s¸¹

qryClone:=TAdoquery.Create(nil);
qryClone.clone(QryDetail);
qryClone.Sort:='Sn';
if qryClone.Locate('sn',sn,[]) then
begin
qryClone.Prior;
Sn:= QryClone.FieldByName('Sn').AsInteger; //¨ú¥X·í«e°O¿ý¤W¤@±ø°O¿ý½s¸¹
end;

QryDetail.Insert;
QryDetail.FieldByName('Sn').AsInteger :=Sn+1;
finally
qryClone.Close;
qryClone.Free;
end;
 
敬请大家关心和指导!非常感谢!
 
至今还未解决问题,敬请大家关心和指导!非常感谢!
 
我的解决办法是你当时就调出你要插入的上一行的辅助编号,然后将此辅助编号加一,然后付给此行的辅助编号,如果这个编号在数据库中存在,则所有大于等于这个号的辅助编号都加一,如果没有那就直接提交好了,然后提交之后,要刷新按辅助编号排序的就好了
 
重新OPEN就可以了。
 
在你们这些热心朋友的支持与帮助下,问题得到解决(kunwyf12345提出的方案的具体化).
基本思想:我的解决办法是你当时就调出你要插入的上一行的辅助编号,然后将此辅助编号加一,然后付给此行的辅助编号,如果这个编号在数据库中存在,则所有大于等于这个号的辅助编号都加一,如果没有那就直接提交好了,然后提交之后,要刷新按辅助编号排序的就好了
代码如下:
procedure TForm1.Button3Click(Sender: TObject);
var sn_found,is_bof:integer;

begin
//showmessage('RecNo = '+inttostr(adoquery1.RecNo));
row_sn:=adoquery1.RecNo;
sn_found:=0;
is_bof:=0;
adoquery1.DisableControls;
if (adoquery1.Bof = true) then begin
sn_pred:=adoquery1['sn'];
is_bof:=1;
end
else begin
adoquery1.Prior;
sn_pred:=adoquery1['sn'];
//showmessage('sn_pred = '+floattostr(sn_pred));
end;
adoquery1.First;
while (not adoquery1.eof) and (sn_found=0) do
begin
if (adoquery1['sn'] = sn_pred +1)
then begin
sn_found:=1;
//showmessage('this ''sn_pred +1'' is found');
end;
try
adoquery1.Next;
except
end;
end;
if (sn_found = 1)
then begin
adoquery1.Last;
if is_bof =0 then
while (not adoquery1.bof) and (adoquery1['sn'] > sn_pred)
do begin
adoquery1.Edit;
//showmessage('sn = '+floattostr(adoquery1['sn']));
adoquery1['sn']:=adoquery1['sn'] +1;
adoquery1.Post; //一定要此句
try
adoquery1.Prior;
except
end;
end
else begin
while (not adoquery1.bof) and (adoquery1['sn'] >= sn_pred)
do begin
adoquery1.Edit;
//showmessage('sn = '+floattostr(adoquery1['sn']));
adoquery1['sn']:=adoquery1['sn'] +1;
adoquery1.Post; //一定要此句
try
adoquery1.Prior;
except
end;
end
end;

end;
if is_bof =1 then begin
adoquery1.Edit;
try
adoquery1.Last;
adoquery1.AppendRecord([sn_pred,nil,nil]);
except
showmessage('insert fail!');
adoquery1.Cancel;
end;
end

else begin
adoquery1.Edit;
//showmessage('befor insert sn_pred = '+ floatTostr(sn_pred));
try
adoquery1.Last;
adoquery1.AppendRecord([sn_pred +1,nil,nil]);
except
showmessage('insert fail!');
adoquery1.Cancel;
end;
end;
//isInsert:=1;
adoquery1.Sort:='sn';
adoquery1.First;
//showmessage('row_sn befoe insert = ' + inttostr(row_sn));
adoquery1.MoveBy(row_sn - 1);
//showmessage(inttostr(adoquery1.RecNo));
adoquery1.EnableControls;
adoquery1.Refresh;
dbgrid1.Refresh;


end;

procedure TForm1.FormCreate(Sender: TObject);
begin
isInsert:=0;
sn_pred:=1;
end;

procedure TForm1.ADOQuery1AfterPost(DataSet: TDataSet);
begin
{if isInsert=1
then begin


adoquery1.DisableControls;
adoquery1.Sort:='sn';
adoquery1.EnableControls;
adoquery1.Refresh;
dbgrid1.Refresh;
isInsert:=0;
adoquery1.First;
adoquery1.MoveBy(row_sn -1);
end;}
end;
这已可以用了,但还不太完美,应加上判断一下空表:如为空表则直接赋值即可:
if (adoquery1.bof=true) and (adoquery1.recordCount=0)
then begin
//直接赋值......
end;
 
后退
顶部