问题描述
我有一个简单的查询,它返回以下行:
名称值
Peter 1
彼得2
彼得3
约翰1
约翰2
申请过滤器:
ADO.Filter:='Name =John';
ADO.Filtered:= True; //现在,它在数据集中只有2行
ADO.Locate('Value',2);
光标应指向John 2,但它指向Peter 2通过过滤器)。并找到返回True。
在Delphi 7上试用,Rad studio XE 6.似乎这个错误在过去15年里生活在
任何解决方案?
是内部使用,并尝试在克隆的记录集中查找记录,而不将筛选器设置为克隆的记录集(请参阅ADODB TCustomADODataSet.LocateRecord
)。
从文档中的注释:
我已经使用我自己的简单的为过滤的ADO DataSet定位
函数:基本上,存储当前书签,移动到第一个记录并迭代DataSet,直到找到比赛。如果没有找到匹配项可以恢复以前的书签。
Bellow是一个非常有限的实现,适用于我(很多要做完美的解决方案):
class function TData.Locate(DataSet:TDataSet; const KeyFields:string;
const KeyValues:Variant; Options:TLocateOptions):Boolean;
{一个非常简单的定位函数 - todo:TLocateOptions&多个KeyFields / KeyValues}
var
BM:TBookmarkStr;
begin
结果:= False;
如果DataSet.IsEmpty然后退出;
BM:= DataSet.Bookmark;
DataSet.DisableControls;
try
DataSet.First;
而不是DataSet.Eof do
begin
如果DataSet.FieldByName(KeyFields).Value = KeyValues then
begin
结果:= True;
休息;
结束
DataSet.Next;
结束
如果不是结果然后DataSet.Bookmark:= BM;
finally
DataSet.EnableControls;
结束
结束
另一个选项是修补ADODB.pas TCustomADODataSet.LocateRecord
并设置 FLookupCursor.Filter
以匹配当前的数据集过滤器。只要将ADODB.pas作为新的副本放在项目文件夹中,该选项就可以接受。
另一个选项是使用方法(另见:)。
I have as simple query, which returns following rows:
Name Value
Peter 1
Peter 2
Peter 3
John 1
John 2
Applying filter:
ADO.Filter := 'Name="John"';
ADO.Filtered := True; // Now, its only 2 rows in dataset
ADO.Locate('Value', 2);
Cursor should point to "John 2", but it points to "Peter 2" (which being filtered out by filter). And locate returns True.
Tried on Delphi 7, Rad studio XE 6. It seems that this error is living there for the last 15 yearsAny solution ?
The problem with TCustomADODataSet.Locate
is that it's internally using Recordset.Clone
and trying to locate a record in the cloned recordset, without setting the filter to the cloned recordset (see ADODB TCustomADODataSet.LocateRecord
).
From the Remarks in the docs:
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;
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.
Yet another option is to use TCustomADODataSet.Recordset.Find
method (See also: How to use a RecordSet.Find with TADOQuery?).
这篇关于Delphi ADO:使用数据集过滤器查找错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!