Delphi - 在DBGrid中恢复实际行

dur*_*ara 5 delphi row dataset dbgrid locate

D6教授.

以前我们使用DBISAM和DBISAMTable.处理RecNo,它可以很好地修改(删除,编辑等).

现在我们替换为不处理RecNo的ElevateDB,很多时候我们使用Queries,而不是Tables.

查询必须重新打开以查看修改.

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

我们发现此代码:

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;
Run Code Online (Sandbox Code Playgroud)

最初的例子是使用moveby.这与Queries工作得很好,因为我们无法看到Query在后台重新打开,可视控件没有改变行位置.

但是当我们有EDBTable或Live/Sensitive Query时,MoveBy使用起来很危险,因为如果有人删除或追加新行,我们可以重新定位到错误的记录中.

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

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

或者,在基础DataSet刷新后,哪种DBGrid可以重定位到记录/行?

我搜索用户友好的解决方案,我理解他们,因为我试图使用这个跳过DBGrid,并且使用非常糟糕,因为我的眼睛在更新后试图找到原始记录时出现... :-(

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

Ser*_*yuz 8

由于'MoveBy'正在为你工作,请使用它们.

在关闭数据集之前获取"书签".做你的工作,重新打开数据集,然后用'MoveBy'重新定位你在网格上的记录.完成后,获取另一个书签,并将其与之前的Bookmark与DataSet.CompareBookmarks进行比较.如果结果为0,如果没有,则仅为前一个书签发出'GotoBookmark'.

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


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

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;
Run Code Online (Sandbox Code Playgroud)