简要说明
除了Locate和Lookup之外,事实上,数据集的过滤器功能是非常有用的,因为过滤器不但能够查寻数据,更棒的是它可以再把结果数据集中的数据进行分门别类,让应用程序只存取特定群组的数据。这个行为有点像是把从后端数据库回传的结果数据集中的数据,再使用额外的条件来取得子结果数据集。
Delphi的过滤器功能不但可以让开发人员对单一字段下达过滤条件,也可以对多个字段下达过滤条件,同时不限定字段是否为索引字段。此外开发人员有两种方法来使用过滤器,第一种方法是使用数据集控件的Filter特性值,第二种方法是使用数据集控件的OnFilterRecord事件处理函数。
这两种方法的不同点是,Filter特性值只能让开发人员使用字符串来设定过滤条件,而OnFilterRecord事件处理函数却能够让开发人员使用Delphi程序语言来执行任何复杂的过滤条件。Delphi提供和过滤功能相关的特性和事件处理函数如下表所示。
特性/事件处理函数 | 意义 |
Filter特性值 | 使用字符串条件来过滤数据 |
OnFilterRecord事件处理函数 | 使用事件处理函数程序代码来过滤数据 |
Filtered | 决定是否打开过滤器功能的特性值 |
FilterOptions | 过滤功能使用的额外条件 |
要使用过滤器功能,开发人员必须设定Filtered特性值为True。一旦Filtered特性值为True之后,如果Filter特性值有任何的过滤条件,Delphi便会以这个过滤条件作为标准来过滤目前在结果数据集之中的数据。只有符合过滤条件的数据才能够显示在数据感知控件之中,或是被存取,而不符合过滤条件的数据暂时无法被存取到。此外如果开发人员有定义OnFilterRecord事件处理函数,那么Delphi也会执行OnFilterRecord事件处理函数来过滤数据。因此,如果开发人员同时设定了Filter特性值以及OnFilterRecord事件处理函数,那么这两个过滤条件都会被执行。
至于FilterOptions特性则类似Locate的第三个参数,用来指明在过滤数据时是否需要分别大小写,或是是否需要比对完整的字符串过滤值。
运用实例(1)
procedure TfrmMain.btnFilterClick(Sender: TObject);
begin
dmSearchData.sqlcdsTest.Filtered := False;
dmSearchData.sqlcdsTest.Filter :=‘ LENGTH_CM>=60 AND LENGTH_CM <= 80’;
dmSearchData.sqlcdsTest.Filtered := True;
end;
接着点击按钮,那么,我们就可以在数据感知控件中看到只有符合这个过滤条件的数据会显示出来。
当然,过滤器并不是只能以一个字段为过滤目标,开发人员可以同时使用多个字段来过滤数据,例如下面的过滤条件同时以LENGTH_CM和TOPOTYPE这两个字段为目标来查寻数据。请注意由于TOPOTYPE字段是字符串类型,因此它的查寻数值必须使用单引号来设定。
LENGTH_CM>=10 AND LENGTH_CM <= 80 AND TOPOTYPE='China'
使用OnFilterRecord事件处理函数
TClientDataSet等数据集控件有一个OnFilterRecord事件处理函数可以让开发人员使用Object Pascal程序代码来处理任何复杂的过滤条件。OnFilterRecord事件处理函数的原型如下:
procedure FilterRecord(DataSet: TDataSet; var Accept: Boolean);
当开发人员打开过滤器功能时,Delphi会为每一笔在结果数据集中的数据调用一次OnFilterRecord事件处理函数,
其中OnFilterRecord事件处理函数的第一个参数便是目前执行过滤功能的数据集控件,
第二个参数Accept是一个var类型的布尔值参数。如果在OnFilterRecord事件处理函数中这笔数据符合过滤条件的话,那么开发人员就必须设定Accept为True,以便让这笔数据存在于经过过滤之后的子结果数据集之中。相反,如果这笔数据不符合过滤条件,那么开发人员就必须设定Accept参数为False以剔除这笔数据。
运用实例(2)
现在就让我们在下面的实例中使用OnFilterRecord事件处理函数来过滤数据。在刚才使用过滤器的例子中,我们以LENGTH_CM和TOPOTYPE这两个字段为目标来查寻数据。如果现在我们希望寻找LENGTH_CM在10和50之间,并且TOPOTYPE是以'China'为开头的数据,那么使用OnFilterRecord事件处理函数可以非常简单地找到我们需要的数据。
在它的OnClick事件处理函数中撰写如下的程序代码:
procedure TfrmMain.btnOnFilterRecordClick(Sender: TObject);
begin
dmSearchData.sqlcdsTest.Filtered := False;
dmSearchData.sqlcdsTest.Filter := '';
dmSearchData.sqlcdsTest.Filtered := True;
end;
在上面的程序代码中我们先关闭过滤器功能,并且清除Filter特性值以避免dbExpress同时以Filter特性值和OnFilterRecord事件处理函数来过滤数据。
接着在数据集的OnFilterRecord事件处理函数中撰写如下的程序代码:
procedure TdmSearchData.sqlcdsTestFilterRecord(DataSet: TDataSet;
var Accept: Boolean);
begin
if ( (DataSet.FieldByName('LENGTH_CM').Value >= 10) and
(DataSet.FieldByName('LENGTH_CM').Value <= 50) and
( Pos('China', DataSet.FieldByName('TOPOTYPE').Value ) <> 0 ) ) then
Accept := True
else
Accept := False;
end;
在上面的程序代码中先使用第一个参数DataSet来找到目前正在被过滤的数据,判断它的'LENGTH_CM'字段值是否在10和50之间,而且'TOPOTYPE'字段是不是以'China'为开头的数值,如果是的话就设定Accept为True,反之则设定Accept为False。
注意
上面的例子应用程序果然顺利地找到了符合过滤条件的数据。请注意,由于过滤器功能对每一笔在结果数据集中的数据都会进行一次过滤的操作,因此,如果结果数据集中的数据数量很大,那么在使用过滤器功能之前,开发人员必须很小心地评估过滤器的影响。
学习大师整理编辑文档,请勿转载,侵权必究。
|