DBGRID的BUG?用DBGRID翻页时的奇怪现象(200分)

  • 主题发起人 主题发起人 qlj
  • 开始时间 开始时间
Q

qlj

Unregistered / Unconfirmed
GUEST, unregistred user!
最近想做个程序自动将数据库中的数据用DBGRID以每页5行的方式显示出来,如下所示:
11111 66666 - 22222
22222 77777 不论是手工翻还是 | 33333
33333 希望第二页===》 88888 将记录指针指向66666 ===》44444
44444 99999 其结果都是: | 55555
55555 00000 - 66666
(第一页) (希望得到的第二页) (现实的第二页)

如果记录数是53条我的最后一页应该是:
第51条 第49条
第52条 第50条
第53条 但现在是===》 第51条
空 的 第52条
空 的 第53条
(希望得到的) (现实显示的)

下载了各种DBGRID的替代品都有这个问题,不知道应该怎么解决,修改源码却又不知道该改
哪里,难道只有使用STRINGGRID代替,可DBGRID的功能又吸引着我,哎,头疼。。。。:-(


 
这一点也不奇怪。
你可用Data.First; Data.MoveBy(inc);控制首条显示记录,再用空记录
补齐数据库即可。以前我是这样实现的。
 
我的环境是WINDOW2000 Professional +DELPHI 5.0 +DBF
部分代码:用一个按钮打开数据库,用一个TIMER自动移动记录指针
PROCEDURE TMAIN_FORM.OPENCLICK;
BEGIN
DATA。ACTIVE;
DATA。FIRST;//按你的说法我加了这句,可是我想TABEL ACTIVE 时当前记录应该是FIRST
END;

PROCEDURE TMAIN_FORM.SHOWTIMER(SENDER:TOBJECTS);
BEGIN
IF DATA.ACTIVE THEN
BEGIN
IF DATA.RECORDCOUNT>=(DATA.RECNO+5) THEN
DATA.MOVEBY(5)
ELSE
DATA.FIRST;
END;
END;
我看了,这样控制数据库的指针的确改变了,但第一次翻页的时候却没有把当前记录显示成
第一页,而是如上所示的成了第二页的最后一条记录。
至于最后一页,通过添加空记录的方法,我想应该可以吧,还得试试。
你说你成功了的,是否可以把那段CODE贴出来看看,EMAIL TO ME 也行。
拜托。。
 
var
nRec: Integer;
begin
if not Data.Active then Exit;
if Data.RecNo mod 5 = 0 then Exit;
nRec := (Data.RecNo div 5 + 1) * 5;
if nRec < Data.RecordCount then Data.MoveBy(nRec - Data.RecNo);
end;
 
TO dq:
你的CODE中如果有下面这条
if Data.RecNo mod 5 = 0 then Exit;
那我当 RECNO=1时 根据 NREC:=(1 DIV 5 +1)*5; NREC:=5;
那么就NREC-RECNO=4了然后就MOVEBY(4)后 RECNO:=5;了
这时 RECNO MOD 5=0 了,不就EXIT了吗?
我去掉这句后可以达到我需要的第二页的显示效果了,可我奇怪的是,一般每页的第一条记录
不是当前的记录吗?用你的方法是当前记录为1时,第一页的第一条是当前记录,而当前记录
为N*5时,第N页的第一条却是N*5+1号记录的内容(虽然满足了我的要求,可我没明白道理)
为什么要把当前记录设置为要显示成某页第一条的记录的前一条才行?而不是直接把某页的
第一条设置为当前记录?还请详细赐教!
还有,这段只能显示N*5条,比如我有53条,最后三条就不能显示了,难道我只有增加三条空
记录?
 
>>我去掉这句后可以达到我需要的第二页的显示效果了
——哦,原来你是想要自动连续翻页的效果;呵呵,那就去掉吧。

>>为什么要把当前记录设置为要显示成某页第一条的记录的前一条才行?
——这也是没办法的办法,是通过观察DBGrid滚动时的行为得出来的;
至于为什么会表现得这样,我也说不清。(看了看源码,没找着:(,不知道是不是和ScrollWindowEx那一句有关)

>>难道我只有增加三条空记录?
——我看差不多:),再听听别人的意见吧。
 
严格来讲dbgid是连续显示的,可能无法实现真正的
分页显示!
 
TO DQ:
多试了几次,对你的算法想了半天才发现实质是。。。就在第一页,当前记录为1的时候
要做手脚。别笑我笨,呵~~~

你的CODE:
temp:=(recno div t +1)*t;
if temp<recordcount then
moveby(temp-recno);
我修改后的CODE:
REFRESH;//因为我希望每次都看到最新的数据,因为数据同时在被其他程序修改。
if recno=1 then t:=t-1;
if (recno +t)<recordcount then
moveby(t);
我想这样应该也可以,似乎和你的有异曲同工之效,还请指正。。。
顺便问一下,如果我在添加空记录后,在REFRESH后,DATASET是会将空记录保存,或者是
将空记录刷新掉了,需要我从新添加空记录呢?如果被刷掉了的话,那我岂不是要每次检查
是否RECORDCOUNT MOD 5<>0 了,如果不等于0我就得添加空记录了!哎,有点麻烦呀!不知
道有没有高手能找到源码中的那一句自动做一下判断,不要把最后一页给添满?

WAITING。。。。。。
 
怎么贴进来成这个样子了,在贴一次咯.
TO DQ:
多试了几次,对你的算法想了半天才发现实质是。。。就在第一页,当前记录为1的时候
要做手脚。别笑我笨,呵~~~

你的CODE: 我的CODE:
temp:=(recno div t +1)*t; IF RECNO=1 THEN T:=T-1;
if temp<RECORDCOUNT THEN IF (RECNO+T)<RECORDCOUNT THEN
MOVEBY(TEMP-RECNO); MOVEBY(T);
这样应该也行,还请指教.
对了,顺便问一下,如果我添加了空记录后REFRESH了,那我的那些空记录是消失了,还是会写
库,是否只要让DATASET 的READONEY:=TRUE就可以防止写库了,如果消失的话不得从新计算需要
添加的空记录数了(因为数据会被其他程序修改)!哎,有点麻烦呀!不知道有没有高手能
找到源码中的那一句自动做一下判断,不要把最后一页给添满?

WAITING。。。。。。

 
岂有此理,怎么贴都乱七八遭,大BUG!!!
不管了,发分了!!!
 
多人接受答案了。
 
to qlj:
呵呵,你太性急了——贴乱了是HTML语言造成的,是因为小于号:)
我本来也想等高手把滚动的问题解决呢,另外我也想找出方法来然后一起回答你的。
现在我还是没解决让DBGrid在最后一页往上多滚几条的方法,就把前面的问题先说说吧。

如果你并不要求RecNo为T的整数倍的记录显示为每页的最后一条,
并且不允许用户点击DBGrid更改当前记录位置的话,你的代码也没问题的。

如果你没有用缓存的话,在添加了空记录的当时(Refresh之前)就应该被写入表里了,
因此你必须在刷新之前删除这些空记录;
如果用了缓存,那就没问题了,只要你不调用ApplyUpdate,空记录不会影响数据的。

因为没有找到有效的滚动方法,所以我认为只要你的表里的字段都允许为空值,
添加空记录的方法不失为一个合理的解决方案,只要控制好空记录的个数和删除就行了。
其实逻辑上并不难,只是要细心些,做些适当的判断。

实在抱歉,没有能给出更好的答案。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部