计算机世界日报
返回首页 产品报价 实用技巧 国产软件 技术天地 站点精选

计算机世界展览会日报

  综合要闻
  企业&人.com
  产品与技术
  网络与通信
  市场与渠道
  99全文检索

CCW网站

  网络世界
  微电脑世界
  IT经理世界
  CCW展览
  信息服务中心   家用电脑世界

兄弟刊物

  电子与信息化
  今日电子
  中国新闻科技
  电子知识产权
  电子产品世界

网上专递

  Linux园地
  友情链接
  冬涛谈法
Dongtao on Law

98内容总汇



实用技巧

数据过滤技术在Delphi中的使用

十堰东风汽车工程研究院
杨中明

---- 使用Delphi可以方便而又快速地建立强大的数据库应用程序,Delphi的数据库应用程序开发,无论是客户/服务器数据库还是本地数据库,必须用到组件(组件的英文为Component,有叫控件、元件、构件的,本文称组件)TDataSource和Ttable,其中Ttable组件中有多种过滤记录的方法,现用最简单例子分别说明。

---- 1.给字段设置限制值,过滤记录

---- 下面是Delphi4帮助中的一个例子,设置了数据表Table1中的"City"字段检索范围,即上限值和下限值。范围一旦被设定,在整个应用程序执行过程中都是有效的。也可以调用CancelRange方法暂时使范围失效,以后需要范围生效时,可直接调用ApplyRange方法,而不需要再次设定范围的上下限。另外,可以调用EditRangeStart和EditRangeEnd的方法来改变范围的上下限。

	with Table1 do
	begin
	  SetRangeStart; { Set the beginning key }
	  FieldByName('City').AsString := 'Felton';
	  SetRangeEnd; { Set the ending key }
	  FieldByName('City').AsString := 'Scotts Valley';
	  ApplyRange; { Tell the dataset to establish the range }
	end;

---- 需要特别说明的是,如果Table1是Paradox表或是dBASE表,在调用SetRangeStart,SetRangeEnd,ApplyRange,CancelRange等方法时,只能为Table1表中的索引字段或定义的索引指定相应的字段值,以设定检索范围,也就是说"City"字段必须是索引字段。另外要说明的是,KeyExclusive属性值为True时不包括边界值,为False时包括边界值,缺省为False。

---- 2.在OnFilterRecord事件中过滤记录

---- 例如要对某数据表(Table)的Degree字段进行"工程师"和"高级工程师"的数据过滤(或称筛选数据),可以通过下面的程序具体实现。

 unit Unit1;

interface

uses
  Windows, Messages, SysUtils, 
  Classes, Graphics, Controls, Forms, Dialogs,
  Grids, DBGrids, Db, DBTables, StdCtrls;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    Table1: TTable;//指定表,如Demo.db
    DBGrid1: TDBGrid;//用于显示记录
Button1: TButton;//按下后TDBGrid
中显示所有"工程师"的记录
Button2: TButton;//按下后TDBGrid
中显示所有"高级工程师"的记录
Button3: TButton;//按下后TDBGrid
中显示全部记录
    Button4: TButton;//按下后退出程序
procedure Table1FilterRecord
(DataSet: TDataSet; var Accept: Boolean);
     procedure AnotherFilterRecord
(DataSet: TDataSet; var Accept: Boolean);
//指定"高级工程师"的事件句柄
procedure OtherFilterRecord(DataSet: TDataSet; 
var Accept: Boolean);//指定"工程师"的事件句柄
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);

  private
    { Private declarations }
  public

    { Public declarations }
  end;


 var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Table1FilterRecord
(DataSet: TDataSet;
  var Accept: Boolean);
begin
accept:=dataset['degree']='总经理';
//初始的过滤条件
end;

procedure TForm1.AnotherFilterRecord
(DataSet: TDataSet;
          var Accept: Boolean);
     begin
       accept:=dataset['degree']='高级工程师';
     end;

 procedure TForm1.OtherFilterRecord
(DataSet: TDataSet;
          var Accept: Boolean);
     begin
       accept:=dataset['degree']='工程师';
     end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  table1.OnFilterRecord:=Otherfilterrecord;
   table1.Filtered:=true;
   refresh;//在Delphi4中Refresh语句可以不用,
  Ttable组件自动响应并刷新记录。

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 table1.Filtered:=false;
  refresh;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
    table1.OnFilterRecord:=Anotherfilterrecord;
    table1.Filtered:=true;
    refresh;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
    close;
end;

end.
---- 此方法的主要思路就是:在运行期把OnFilterRecord事件重新指定一个事件句柄(本例中AnotherFilterRecord和OtherFilterRecord),从而使程序按不同的过滤条件过滤记录。这种方法并不要求Table1的degree字段为索引字段,对数据集不大的数据表,非常实用而简便,对数据集中记录很多的,最好还是用查询或者设置检索范围。

---- 3.设置Filter属性,过滤不同的记录

---- 以上程序过程显得有些复杂,可简单地指定Filter属性来实现,即不用OnFilterRecord事件,删除两个事件句柄AnotherFilterRecord和OtherFilterRecord的定义及相关过程,直接用过滤Filter串,将Filtered属性值设置为True,并把Button1Click和Button2Click事件修改如下:(另注:两个单引号表示串中的一个单引号)

procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Table1.Filtered:=true; 
Form1.Table1.Filter:='[degree]'+'='+'''工程师''';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Form1.Table1.Filter:='[degree]'+'='+'''高级工程师''';
end;

---- 这种方法也不要求Table1的degree字段为索引字段,没有索引支持,当记录数量比较大时,过滤的速度会受影响。Filter属性设置还支持通配符,例如:[degree]='E*',与Filter属性设置有关的还有FilterOption属性,它是一个集合属性,有两个成员:foCaseInsensitive(区分大小写),foNoPartialCompare(*不作为通配符)。

---- 4.使用SQL实现数据过滤(不必用Ttable组件)

---- 通过TQuery组件来使用SQL语句实现记录的过滤,大家可能对这种方法比较熟悉,这里只做简单说明,如上例中的记录筛选用一条很简单的SQL语句就能实现:

	SELECT * FROM "demo.DB" demo
	where demo."degree"="工程师" 
---- 如果在运行期改变查询条件,则要用下面的SQL语句来实现:
       Query1.Close;
	Query1.SQL.Clear;
	Query1.SQL.Add('SELECT * FROM
 "demo.DB" demo');
Query1.SQL.Add('where demo."degree"
="高级工程师"') ;
	Query1.ExecSQL;
----   使用SQL语言可以实现条件很复杂的筛选,当记录数量很大或条件很复杂时,应尽量使用SQL语言来查询。这种通过SQL语句的过滤是一次性的。当调用TQuery的Open方法或Active:=true,TQuery返回查询结果集,之后就失去了对结果集的范围限制。当结果集中的某些记录发生改变,不满足过滤条件时,TQuery不能察觉,必须再次调用TQuery的Open方法才能实现刷新记录,过滤掉不符合条件的记录。

---- 以上几种方法各有其特定的使用场合,各有其优劣,这里只作抛砖引玉,具体还要自己仔细琢磨。另外,还可以通过以下函数或方法进行数据过滤,这里就不作介绍了,只给出其函数或过程的形式:

function FindKey(const KeyValues:
 array of const): Boolean;
procedure FindNearest(const KeyValues:
 array of const);
function GotoKey: Boolean;
procedure GotoNearest;
  function Locate(const KeyFields: string; 
const KeyValues: Variant; Options: 
TLocateOptions): Boolean;
---- Delphi提供了强大的数据库开发功能,关于数据过滤技术的实现,有很多的方法,此处只是一点个人体会,供大家参考。
 
免 费 订 阅

实用技巧分类

Office应用
CAD
C、C++
数据库应用
Delphi
Internet应用
Java
Notes应用
操作系统应用
PowerBuilder
VB
Visual Foxpro
其他类
上周 排行榜
如 何 投 稿 ?

编者的话

在日常的工作生活中, 我们对计算机软硬件技术的应用开发肯定有许多的心得体会, 拿来和众人分享:让别人得到他们想要的,使自己找到苦苦寻觅的; 小的点点滴滴,大的工程系统,这里都需要。投稿 的关键在“技巧”二 字,知他人所不知,这样的稿件本栏最最欢迎! 大家公认的 好文章自然会有好的奖励。希望每个人 在这里都有所收获...

r2.gif (980 bytes)
  中国惠普
  3Com中国
  Motorola中国
  CA中国
  Cabletron
  Sony在中国
  西门子WinCC
  爱普生中国
  中国建设银行
  德州仪器(TI)
  问博医药


中国计算机世界出版服务公司版权所有