DBGrid排序

来源:互联网 发布:淘宝部分商品退款 编辑:程序博客网 时间:2024/04/28 14:43

给DBGrid加入排序功能

在实际数据库管理系统中,用户对表中数据的操作,最频繁的莫过于浏览查询了,而查询中若能提供为某字段建立的排序功能,则非常有利于用户对“关键数据”的了解。

Windows的用户都知道,在“我的电脑”或“资源管理器”中打开任一文件夹,若以“详细资料”方式查看,系统会显示出该文件夹下的子文件夹和文件相关信息,如:名称、类型 、大小、修改时间,用户只需要单击标题栏中的相应项,则系统自动按该项进行“升序”(或“降序”)的排列显示,这样用户便能轻松查看相应的文件夹或文件对象的内容。

受此启发,考虑能不能在显示数据的Grid表格中完成如此功能呢?答案是肯定的。下面以在Delphi中的实现方法为例,通过具体内容,介绍该功能的实现。

步骤如下:

一、先建立一数据表

该表以Delphi 中最常用的Paradox为类型,取名为Student,反映(在职)学生的基本情况。该表各字段定义如下:

--------------------------------------------

字段名    类型      大小

序号     Short型     / (Key*)

学号     Alpha型     6

出生日期   Date型      /

性别     Alpha型     2

婚否     Logical型    /

英语     Number型     /

高数     Number型     /

PASCAL    Number型     /

备注     Memo型      20

-------------------------------------------

保存后,随意往表中输入3至5条记录内容。

注:①表中必须建立关键索引(为首字段建立)。此处为“序号”字段;
 with table1 do
 begin
 close;
 Exclusive := true;
 DatabaseName := '';
 TableName := '';
 Open;

{建立主索引 }
 AddIndex('','ID',[ixPrimary]);

{建立次索引 }
 AddIndex('NameIndex','ID;Name',[]);

 close;
 end;

②该表中使用了Paradox常用的几种字段类型,但尚未全部包含。

二、建立项目,实现功能

1.新建一项目,并为表单添加相关控件,各控件主要属性如下表:

2.建立各Click的事件代码

Button1(打开表)的Click事件代码如下:

procedure TForm1.Button1Click(Sender: TObject);

begin

Table1.Open; // 打开Table1关联的表Student

end;

Button2(关闭表单)的Click事件代码如下:

procedure TForm1.Button2Click(Sender: TObject);

begin

Application.Terminate;

end;

DBGrid1的TitleClick事件代码如下:

procedure TForm1.DBGrid1TitleClick(Column: TColumn);

//注:本过程参数Column包含的信息量非常多

begin

MySort(DBGrid1,Column);

end; //调用字段排序

其中,MySort(DBGrid1,Column)为自定义的排序过程,具体代码见下述。

3.建立通用处理模块

为使该功能具有“通用性”,将其定义为一过程。

首先,预声明过程及建立两个全局私有变量:

...

Type

...

procedure MySort(DBGrid0:TDBGrid; Column: TColumn);//预声明过程

private

{ Private declarations }

psIndexName:string; //记录当前索引名称

plAscend:boolean; //记录当前索引名称的索引状态

public

{ Public declarations }

end;

...

其次,该过程完整代码如下:

procedure TForm1.MySort(DBGrid0:TDBGrid; Column: TColumn);

var

//本模块使用到的psIndexName, plAscend两个变量见上定义

mode:char; //记录是“升序”还是“降序”

ColName:string; //记录当前字段名

iCol:Integer; //记录当前列号

begin

with DBGrid0.DataSource.DataSet as TTable do //Table0

begin

//检测当前工作表是否已打开

if not Active

then begin

MessageBeep(0);

Application.MessageBox('工作表尚未打开!','停止',MB_OK+MB_ICONSTOP);

Abort

end;

//检测当前字段是否“能排序”。以下字段类型不能排序

case Column.Field.DataType of

ftBoolean,

ftBytes,

ftBlob, //Binary

ftMemo,

ftGraphic,

ftFmtMemo, //Formatted memo

ftParadoxOle: //OLE

begin

MessageBeep(0);

Application.MessageBox(Pchar('项目"'+Column.FieldName+'"'+'不能排序!'),'停止

',MB_OK+MB_ICONSTOP);

Abort

end;

end; //case

mode:='0';

iCol:=Column.Field.FieldNo-1;

try

ColName:=Column.fieldname;

if psIndexName=Column.fieldname

then begin //与原来同列

if plAscend //升序

then begin

mode:='2';

IndexName:=ColName+'2'; //应“降序”

end

else begin

mode:='1';

IndexName:=ColName+'1'; //应“升序”

end;

plAscend:=not plAscend;

end

else begin //新列

IndexName:=ColName+'2';

plAscend:=false;

psIndexName:=ColName;

end;

except

on EDatabaseError do //若未有索引,则重新建立

begin

Messagebeep(0);

//以下新建索引

IndexName:='';

Close;

Exclusive:=true;

if mode='1'

then AddIndex(ColName+'1',ColName,[ixCaseInsensitive],'')//

else //包括'0'

AddIndex(ColName+'2',ColName,[ixDescending,ixCaseInsensitive],'');

Exclusive:=false;

Open;

try //try 1

if mode<>'1'

then begin

mode:='2';//转换

plAscend:=false;

end

else plAscend:=true;

IndexName:=ColName+mode;

psIndexName:=ColName;

except

on EDBEngineError do

IndexName:='';

end //try 2

end

end;

First;

end; //with

DBGrid0.SelectedIndex:=iCol;

end;//End of MySort

本过程已对所有可能的错误进行了相应的检测及处理,代码是比较完整的。因此,把该过程放入你相应的单元中,对每一个DBGrid,只要传递不同的DBGrid及Column参数,就能实现对应数据表的自动排序处理,而事先只为某字段建立一关键索引即可,其它Secondery Indexes的建立均在程序中自动完成,但会为每一个建立了索引的字段生成了一些附加文件(如*.XG?,*YG?等)。当然若有必要,可以在表单关闭前将所有的附加文件删除。

原创粉丝点击