问题描述
我有一个简单的查询,它返回以下行:
I have as simple query, which returns following rows:
Name Value
Peter 1
Peter 2
Peter 3
John 1
John 2
应用过滤器:
ADO.Filter := 'Name="John"';
ADO.Filtered := True; // Now, its only 2 rows in dataset
ADO.Locate('Value', 2);
光标应该指向John 2",但它指向Peter 2"(被过滤器过滤掉).并且 locate 返回 True.
Cursor should point to "John 2", but it points to "Peter 2" (which being filtered out by filter). And locate returns True.
在 Delphi 7、Rad studio XE 6 上试过.似乎这个错误在过去的 15 年里一直存在有什么解决办法吗?
Tried on Delphi 7, Rad studio XE 6. It seems that this error is living there for the last 15 yearsAny solution ?
推荐答案
TCustomADODataSet.Locate
是它在内部使用 Recordset.Clone
并尝试在克隆的记录集中定位记录,而不进行设置克隆记录集的过滤器(请参阅 ADODB TCustomADODataSet.LocateRecord
).
来自文档中的备注:
原始 Recordset 的 Filter 属性,如果有的话,不会被应用于克隆.设置新 Recordset 的 Filter 属性过滤结果.复制任何现有过滤器的最简单方法value是直接赋值,如下.rsNew.Filter =rsOriginal.Filter 设置新创建的克隆的当前记录到第一条记录.
我一直在使用我自己的简单 Locate
函数来过滤 ADO 数据集:基本上,存储当前书签,移动到第一条记录并迭代数据集直到找到匹配.如果未找到匹配项,则恢复以前的书签.
Bellow 是一个对我有用的非常有限的实现(为了完美的解决方案需要做很多事情):
I have been using my own simple Locate
function for filtered ADO DataSets: Basically, storing the current bookmark, moving to the first record and iterating the DataSet until it found a match. If no match found restore the previous bookmark.
Bellow is a really limited implementation that worked for me (a lot of todo tho for a perfect solution):
class function TData.Locate(DataSet: TDataSet; const KeyFields: string;
const KeyValues: Variant; Options: TLocateOptions): Boolean;
{ a very simple Locate function - todo: TLocateOptions & multiple KeyFields/KeyValues }
var
BM: TBookmarkStr;
begin
Result := False;
if DataSet.IsEmpty then Exit;
BM := DataSet.Bookmark;
DataSet.DisableControls;
try
DataSet.First;
while not DataSet.Eof do
begin
if DataSet.FieldByName(KeyFields).Value = KeyValues then
begin
Result := True;
Break;
end;
DataSet.Next;
end;
if not Result then DataSet.Bookmark := BM;
finally
DataSet.EnableControls;
end;
end;
另一个选项是修补 ADODB.pas TCustomADODataSet.LocateRecord
并设置 FLookupCursor.Filter
以匹配当前数据集过滤器.只要您将 ADODB.pas 修补为放置在项目文件夹中的新副本,此选项就可以接受.
Another option is to patch ADODB.pas TCustomADODataSet.LocateRecord
and set the FLookupCursor.Filter
to match the current dataset filter. This option is acceptable as long as you patch ADODB.pas as a new copy placed in your project folder.
另一种选择是使用 TCustomADODataSet.Recordset.Find
方法(另见:如何使用 RecordSet.Find 和 TADOQuery?).
Yet another option is to use TCustomADODataSet.Recordset.Find
method (See also: How to use a RecordSet.Find with TADOQuery?).
这篇关于Delphi ADO:使用数据集过滤器定位错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!