问题描述
D6 教授
以前我们使用 DBISAM 和 DBISAMTable.它处理 RecNo,并且可以很好地进行修改(删除、编辑等).
Formerly we used DBISAM and DBISAMTable. That handle the RecNo, and it is working good with modifications (Delete, edit, etc).
现在我们用不处理 RecNo 的 ElevateDB 替换,而且很多时候我们使用查询,而不是表.
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.
但是如果我们重新打开查询,我们需要重新定位到最后一条记录.仅定位是不够的,因为 Grid 将其显示在另一行中.这是一件很烦人的事,因为修改记录移到另一排后,你很难跟上,用户讨厌这个.
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.
我们找到了这段代码:
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;
最初的例子是使用 moveby.这对查询很好,因为我们看不到查询在后台重新打开,视觉控件没有改变行位置.
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.
但是当我们有 EDBTable 或 Live/Sensitive Query 时,使用 MoveBy 很危险,因为如果有人删除或追加新行,我们可能会重新定位到错误的记录中.
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.
然后我尝试使用书签(见备注).但是这种技术不起作用,因为它是在另一个 Row 位置显示记录...
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...
那么问题来了:如何在 DBGrid 中强制行位置和记录?
So the question: how to force both the row position and record in DBGrid?
或者在底层DataSet刷新后,什么样的DBGrid可以重定位到记录/行?
Or what kind of DBGrid can relocate to the record/row after the underlying DataSet refreshed?
我在寻找用户友好的解决方案,我理解他们,因为我尝试使用这个跳转 DBGrid,并且使用起来非常糟糕,因为更新后尝试查找原始记录时我的眼睛都出来了......:-(
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... :-(
感谢您的每一个帮助、链接、信息:dd
Thanks for your every help, link, info: dd
推荐答案
既然 'MoveBy's 对您有用,请使用它们.
Since 'MoveBy's are working for you, use them.
在关闭数据集之前获取一个书签".完成您的工作,重新打开数据集,然后使用MoveBy"将您的记录重新定位在网格上.完成后,获取另一个 Bookmark 并使用 DataSet.CompareBookmarks 将其与前一个进行比较.如果结果是 0 很好,如果不是,那么只有为上一个书签发出GotoBookmark".
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 中的实际行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!