Delphi - 恢复DBGrid中的实际行 [英] Delphi - restore actual row in DBGrid

查看:150
本文介绍了Delphi - 恢复DBGrid中的实际行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

D6 prof。



以前我们使用了DBISAM和DBISAMTable。它处理RecNo,并且在修改(删除,编辑等)中工作得很好。



现在我们替换为不处理RecNo的ElevateDB,还有许多时间我们使用查询而不是表。



查询必须重新打开才能看到修改。



但是,如果我们重新打开查询,我们需要重新定位到最后一个记录。
找不到,因为Grid在另一行中显示。
这是非常令人不安的事情,因为修改记录进入另一行后,你很难遵循,用户讨厌这个。



我们发现这个代码:

 函数TBaseDBGrid.GetActRow:integer; 
begin
结果:= -1 +行;
结束


程序TBasepDBGrid.SetActRow(aRow:integer);
var
bm:TBookMark;
begin
如果IsDataSourceValid(DataSource)然后与DataSource.DataSet开始
bm:= GetBookmark;
DisableControls;
try
MoveBy(-aRow);
MoveBy(aRow);
// GotoBookmark(bm);
finally
FreebookMark(bm);
EnableControls;
结束
结束
结束

原始示例是使用移动。这个工作与Queries很好,因为我们看不到Query在后台重新打开,视觉控制没有改变行位置。



但是当我们有EDBTable或者Live /敏感查询,MoveBy是危险的使用,因为如果有人删除或附加一行,我们可以重新定位到错误的记录。



然后我试图使用BookMark (见注)。但是这种技术不起作用,因为它在另一行位置显示记录...



所以问题是:如何强制行位置和记录DBGrid?



或者什么样的DBGrid可以重新定位到底层DataSet刷新后的记录/行?



我搜索用户友好的解决方案,我明白他们,因为我试图使用这个跳跨DBGrid,非常糟糕的使用,因为我的眼睛正在出来,当尝试找到更新后的原始记录...: - (



感谢您的每一个帮助,链接,信息:
dd

解决方案>

由于'MoveBy'正在为您工作,请使用它们。



在关闭数据集之前获取书签。做你的工作,重新打开数据集,然后重新定位你的记录在GridGateBy的网格上,当你完成后,得到另一个书签,并将其与上一个DataSet.CompareBookmarks进行比较,如果结果为0,如果没有,那么只会为之前的书签发出GotoBookmark。



这样,只要另一个用户没有删除/插入记录,你的网格似乎不会跳跃,如果不是这样,至少你会在同一条记录上。






编辑:代码示例,即使在数据集中已删除/插入时,也应将所选记录重新定位在正确的位置。请注意,代码省略禁用/启用控件,特殊情况下,为了简单起见,有较少的记录来填充网格。

 键入
TAccessDBGrid = class(TDBGrid);

procedure TForm1.Button1Click(Sender:TObject);
var
BmSave,Bm:TBookmark;
GridRow,TotalRow:Integer;
begin
GridRow:= TAccessDBGrid(DBGrid1).Row;
TotalRow:= TAccessDBGrid(DBGrid1).RowCount;
BmSave:= DBGrid1.DataSource.DataSet.GetBookmark;
try

//关闭数据集,打开数据集...

如果DBGrid1.DataSource.DataSet.BookmarkValid(BmSave)然后
DBGrid1.DataSource .DataSet.GotoBookmark(BmSave);
Dec(TotalRow);
如果GridRow< TotalRow div 2然后开始
DBGrid1.DataSource.DataSet.MoveBy(TotalRow - GridRow);
DBGrid1.DataSource.DataSet.MoveBy(GridRow - TotalRow);
end else begin
如果dGTitles在DBGrid1.Options然后
Dec(GridRow);
DBGrid1.DataSource.DataSet.MoveBy(-GridRow);
DBGrid1.DataSource.DataSet.MoveBy(GridRow);
结束
Bm:= DBGrid1.DataSource.DataSet.GetBookmark;
尝试
如果(DBGrid1.DataSource.DataSet.BookmarkValid(Bm)和
DBGrid1.DataSource.DataSet.BookmarkValid(BmSave))和
(DBGrid1.DataSource.DataSet.CompareBookmarks (Bm,BmSave)0)然后
DBGrid1.DataSource.DataSet.GotoBookmark(BmSave);
finally
DBGrid1.DataSource.DataSet.FreeBookmark(Bm);
结束
finally
DBGrid1.DataSource.DataSet.FreeBookmark(BmSave);
结束
结束


D6 prof.

Formerly we used DBISAM and DBISAMTable. That handle the RecNo, and it is working good with modifications (Delete, edit, etc).

Now we replaced with ElevateDB, that don't handle RecNo, and many times we use Queries, not Tables.

Query must reopen to see the modifications.

But if we Reopen the Query, we need to repositioning to the last record. Locate isn't enough, because Grid is show it in another Row. This is very disturbing thing, because after the modification record is moving into another row, you hard to follow it, and users hate this.

We found this code:

function TBaseDBGrid.GetActRow: integer;
begin
 Result := -1 + Row;
end;


procedure TBasepDBGrid.SetActRow(aRow: integer);
var
 bm : TBookMark;
begin
 if IsDataSourceValid(DataSource) then with DataSource.DataSet do begin
  bm := GetBookmark;
  DisableControls;
  try
   MoveBy(-aRow);
   MoveBy(aRow);
   //GotoBookmark(bm);
  finally
   FreebookMark(bm);
   EnableControls;
  end;
 end;
end;

The original example is uses moveby. This working good with Queries, because we cannot see that Query reopened in the background, the visual control is not changed the row position.

But when we have EDBTable, or Live/Sensitive Query, the MoveBy is dangerous to use, because if somebody delete or append a new row, we can relocate into wrong record.

Then I tried to use the BookMark (see remark). But this technique isn't working, because it is show the record in another Row position...

So the question: how to force both the row position and record in DBGrid?

Or what kind of DBGrid can relocate to the record/row after the underlying DataSet refreshed?

I search for user friendly solution, I understand them, because I tried to use this jump-across DBGrid, and very bad to use, because my eyes are getting out when try to find the original record after update... :-(

Thanks for your every help, link, info: dd

解决方案

Since 'MoveBy's are working for you, use them.

Get a 'Bookmark' before closing the dataset. Do your work, reopen the dataset and then reposition your record on the grid with 'MoveBy's. When you're done, get another Bookmark and compare it with the previous one with DataSet.CompareBookmarks. If the result is 0 fine, if not, only then issue a 'GotoBookmark' for the previous bookmark.

This way, as long as another user have not deleted/inserted records your grid will not seem to be jumpy, and if this is not the case at least you'd be on the same record.


edit: Here's some code sample that should reposition the selected record in the correct place even when there had been deletes/inserts in the dataset. Note that the code omits disabling/enabling controls, and the special case when there are less records to fill the grid for simplicity.

type
  TAccessDBGrid = class(TDBGrid);

procedure TForm1.Button1Click(Sender: TObject);
var
  BmSave, Bm: TBookmark;
  GridRow, TotalRow: Integer;
begin
  GridRow := TAccessDBGrid(DBGrid1).Row;
  TotalRow := TAccessDBGrid(DBGrid1).RowCount;
  BmSave := DBGrid1.DataSource.DataSet.GetBookmark;
  try

    // close dataset, open dataset...

    if DBGrid1.DataSource.DataSet.BookmarkValid(BmSave) then
      DBGrid1.DataSource.DataSet.GotoBookmark(BmSave);
    Dec(TotalRow);
    if GridRow < TotalRow div 2 then begin
      DBGrid1.DataSource.DataSet.MoveBy(TotalRow - GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(GridRow - TotalRow);
    end else begin
      if dgTitles in DBGrid1.Options then
        Dec(GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(-GridRow);
      DBGrid1.DataSource.DataSet.MoveBy(GridRow);
    end;
    Bm := DBGrid1.DataSource.DataSet.GetBookmark;
    try
      if (DBGrid1.DataSource.DataSet.BookmarkValid(Bm) and
          DBGrid1.DataSource.DataSet.BookmarkValid(BmSave)) and
          (DBGrid1.DataSource.DataSet.CompareBookmarks(Bm, BmSave) <> 0) then
        DBGrid1.DataSource.DataSet.GotoBookmark(BmSave);
    finally
      DBGrid1.DataSource.DataSet.FreeBookmark(Bm);
    end;
  finally
    DBGrid1.DataSource.DataSet.FreeBookmark(BmSave);
  end;
end;

这篇关于Delphi - 恢复DBGrid中的实际行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆