不用Query!

解决方案 »

  1.   

    在Delphi中轻松实现自动排序在实际数据库管理系统中,用户对表中数据的操作,最频繁的莫过于浏览查询了,而查询中若能提供为某字段建立的排序功能,则非常有利于用户对“关键数据”的了解。 
    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?等)。当然若有必要,可以在表单关闭前将所有的附加文件删除。 
    利用这种方法来实现数据表的自动排序,非常灵活实用。该思想当然也适用于其它编程语言。 
    软件环境:中文Win98/中文Delphi5.0。 
      

  2.   

    Table1在DBGrid中,我要让它程序一开始就显示为降序!如果用Query那就太简单了!
      

  3.   

    其实query在查询方面功能要比table强得多,为什么非要用table,如果你一定要用table,我想可以用临时表,排好序以后再送入dbgrid.
      

  4.   

    用ADO怎么做,能具体说一下吗?如果有程序更好!