只有在ONTITLECLICK里面写代码了,没其他的办法了。 你只需要写一段SQL就可以搞定了,到时候通过点击不同COLUMN然后,对不同的FIELD进行ORDER BY
加个ORDER BY 也不是什么费力的事
to luoweicaisd(笑三少) 那里有这种控件下,又又dbgrid的功能。 TO CeleronII(抽烟的鱼) 在ONTITLECLICK里写这个事件里怎么写呢。我不想在去访问数据库了。 to cpls(温柔一刀) 现有的sql实在太多了,并且按那个字段排序也不确定。
给DBGrid加入排序功能 广东省农业管理干部学院 陈建兵 在实际数据库管理系统中,用户对表中数据的操作,最频繁的莫过于浏览查询了,而查询中若能提供为某字段建立的排序功能,则非常有利于用户对“关键数据”的了解。 Windows的用户都知道,在“我的电脑”或“资源管理器”中打开任一文件夹,若以“详细资料”方式查看,系统会显示出该文件夹下的子文件夹和文件相关信息,如:名称、类型 、大小、修改时间,用户只需要单击标题栏中的相应项,则系统自动按该项进行“升序”(或“降序”)的排列显示,这样用户便能轻松查看相应的文件夹或文件对象的内容。 受此启发,考虑能不能在显示数据的Grid表格中完成如此功能呢?答案是肯定的。下面以在Delphi中的实现方法为例,通过具体内容,介绍该功能的实现。 步骤如下: 一、先建立一数据表 该表以Delphi 中最常用的Paradox为类型,取名为Student,反映(在职)学生的基本情况。该表各字段定义如下: -------------------------------------------- 字段名 类型 大小 序号 Short型 / (Key*) 学号 Alpha型 6 出生日期 Date型 / 性别 Alpha型 2 婚否 Logical型 / 英语 Number型 / 高数 Number型 / PASCAL Number型 / 备注 Memo型 20 ------------------------------------------- 保存后,随意往表中输入3至5条记录内容。 注:①表中必须建立关键索引(为首字段建立)。此处为“序号”字段; ②该表中使用了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?等)。当然若有必要,可以在表单关闭前将所有的附加文件删除。
to cg1120(代码最优化-§雨后看见彩虹……§) 兄 你的这个好办法可能对我不行,我现在采取的3层模式,数据一旦取到dbgrid后,我就不在去访问数据库了,并且也不能保证显示的字段中就已经有关键索引,有些表没有索引,这些字段都是有操作员灵活选择出来的。还有好办法吗。要不然我可就太惨了。
你只需要写一段SQL就可以搞定了,到时候通过点击不同COLUMN然后,对不同的FIELD进行ORDER BY
TO CeleronII(抽烟的鱼) 在ONTITLECLICK里写这个事件里怎么写呢。我不想在去访问数据库了。
to cpls(温柔一刀) 现有的sql实在太多了,并且按那个字段排序也不确定。
广东省农业管理干部学院 陈建兵
在实际数据库管理系统中,用户对表中数据的操作,最频繁的莫过于浏览查询了,而查询中若能提供为某字段建立的排序功能,则非常有利于用户对“关键数据”的了解。 Windows的用户都知道,在“我的电脑”或“资源管理器”中打开任一文件夹,若以“详细资料”方式查看,系统会显示出该文件夹下的子文件夹和文件相关信息,如:名称、类型 、大小、修改时间,用户只需要单击标题栏中的相应项,则系统自动按该项进行“升序”(或“降序”)的排列显示,这样用户便能轻松查看相应的文件夹或文件对象的内容。 受此启发,考虑能不能在显示数据的Grid表格中完成如此功能呢?答案是肯定的。下面以在Delphi中的实现方法为例,通过具体内容,介绍该功能的实现。 步骤如下: 一、先建立一数据表 该表以Delphi 中最常用的Paradox为类型,取名为Student,反映(在职)学生的基本情况。该表各字段定义如下: -------------------------------------------- 字段名 类型 大小 序号 Short型 / (Key*) 学号 Alpha型 6 出生日期 Date型 / 性别 Alpha型 2 婚否 Logical型 / 英语 Number型 / 高数 Number型 / PASCAL Number型 / 备注 Memo型 20 ------------------------------------------- 保存后,随意往表中输入3至5条记录内容。 注:①表中必须建立关键索引(为首字段建立)。此处为“序号”字段; ②该表中使用了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?等)。当然若有必要,可以在表单关闭前将所有的附加文件删除。
你的这个好办法可能对我不行,我现在采取的3层模式,数据一旦取到dbgrid后,我就不在去访问数据库了,并且也不能保证显示的字段中就已经有关键索引,有些表没有索引,这些字段都是有操作员灵活选择出来的。还有好办法吗。要不然我可就太惨了。