如何及时更新与数据库相连的DBGrid部件?(100分)

  • 主题发起人 主题发起人 Freeman
  • 开始时间 开始时间
F

Freeman

Unregistered / Unconfirmed
GUEST, unregistred user!
我在应用程序中,使用OnFilterRecord对TTable的一个日期型

字段设置了过滤条件.希望改变日期后,连接到同一个TTable的

DBGrid中的内容能相应变化.

但实际情况是,必须滚动DBGrid中的数据后,DBGrid中的内容

才会更新.我试过DBGrid的Refresh、Update,甚至重新建立

DBGrid与DataSource的联系都不行,请问有什么办法能达到我

的目的。
 
table.close
table.open
 
老兄手好快!
Table1.Active:=False;
Table1.Active:=True;
好象比open,close 快的多!
 
Can it work? not tested yet.

Dbgrid1.DisableControls;
Dbgrid1.EnableControls;

if Can't, then:

DbGrid1.Perform(WM_VSCROLL, SB_TOP);

hehehehe....
 
如果光DisableControls, EnableControls不能解决问题的话:
var
p: pointer;
begin
DbGrid1.DisableControls;
Table1.GetBookmark(p);
Table1.First;
Table1.GotoBookmark(p);
Table1.FreeBookmark(p);
DbGrid1.EnableControls;
end;
应该没问题, 好处是当前DbGrid中的光标位置不变.
 
如果光DisableControls, EnableControls不能解决问题的话:
var
p: pointer;
begin
DbGrid1.DisableControls;
Table1.GetBookmark(p);
Table1.First;
Table1.GotoBookmark(p);
Table1.FreeBookmark(p);
DbGrid1.EnableControls;
end;
应该没问题, 好处是当前DbGrid中的光标位置不变. (相当然的, 同样没试过)
 
datasource.dataset.active:=false;
datasource.dataset.active:=true;
 
datasource.dataset.active:=false;
datasource.dataset.active:=true;
 
感谢各位的回答.
poopoo、唐晓锋、yaojiaqing提出的方法,实质和都是通过开关数据库,
来达到更新的目的,但是我的数据库是放在网上的,每次开关数据库的时间
消耗较大,不能达到实时变化的效果.

Another_eYes提出使用DisableControls和EnableControls,应该有笔误, 这
两个方法是属于TDataSet,试过了,没有用.
发出WM_VSCROLL消息,从滚动条来看,DBGrid确实滚动了,但显示的内容却没有
更新,即使再使用Refresh方法也一样.
Another_eYes提出的另一种方法,是移动Table的指针.因为我设了过滤,所以
应该用FindFirst,而不是First.这种方法也没有用.

上面几位的解决办法都是想办法更新TTable,但从实际的情况来看,是DBGrid
没有更新.不知有没有办法能够强制更新?
 
DBGrid.DataSet := TmpTable;
DBGrid.DataSet := DataSource1;

如果dwwang来了一定劝你用SQL
 
有这问题吗?
我怎么试下来dbgrid都能响应?(delphi 3)
不过你可以试试一下代码: (假设你的OnFilterRecord过程名为Table1FilterRecord)

procedure Edit1Exit(Sender:TObject);
begin
table1.OnFilterRecord:=nil;
table1.filtered:=false;
table1.First;
table1.OnFilterRecord:=Table1FilterRecord;
table1.filtered:=true;
end;
我遇到的问题是第二次filter是在第一次filter之后的结果上进行的, 因此基本上
第二次就找不到记录了, 用以上代码解决了.

另外你可以试试dbgrid1.perform(CM_CONTROLLISTCHANGE,0,0);
 
我用的一个比较土的方法:

table1.disablecontrol;
if table1.eof() then
table1.moveby(-1)
else begin
table1.moveby(1);
table1.moveby(-1);
end;
table1.enablecontrol;
 
为什么不用SQL呢,当你日期改变的时候,执行一下SQL,并且
不涉及开关table!加个SQL控件就可以了!
 
什么sql控件? TQuery? TQuery也需要close然后open才会执行sql的
 
关键问题是看OnFilterRecord事件是在什么时候触发,我估计它是在记录指针移动时
才触发.在你滚动DBGrid时记录指针发生了移动,才触发了OnFilterRecord事件,
你可以在改变日期后显示的执行OnFilterRecord事件
 

Table.filtered:=false;
Table.refresh;
Table.filtered:true;
Table.refresh;
 
直接用TABLE的FILTERRECORD事件,没有问题的
procedure TForm1.Table1FilterRecord(DataSet: TDataSet;
var Accept: Boolean);
begin
Accept := table1.FieldValues['SaleDate']>self.DateTimePicker1.Date;//用DateTimePicker返回的日期(Tdatetime)
//accept为 Boolean 类型
end;
//一定先要把Table1的Filtered属性改为True
end.

我是在D4下用demos 中的ORDERS.DB试的,绝对没有问题
 
本来很简单的事为什么搞得那么复杂, 本来CJ的想法是对的
将数据源Datasource断开再重新接上便可以了. 谁知CJ稀里糊涂
写了一个

>DBGrid.DataSet := TmpTable;
>DBGrid.DataSet := DataSource1;

应该是
DBGrid.DataSource := nil
DBGrid.DataSource := Datasource1;


 
多人接受答案了。
 
后退
顶部