本文介绍了Delphi ADO:使用数据集过滤器定位错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的查询,它返回以下行:

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:使用数据集过滤器定位错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 10:24