(转)欲实现点击DBGrid的Title对查询结果排序,想作一个通用程序,不是一事一议, 
而且点击另一个Title时又要另外排序,目的是想作到象资源管理器那样随心所欲。 
procedure TFHkdata.SortQuery(Column:TColumn); 
var 
  SqlStr,myFieldName,TempStr: string; 
  OrderPos: integer; 
  SavedParams: TParams; 
begin 
  if not (Column.Field.FieldKind in [fkData,fkLookup]) then exit; 
  if Column.Field.FieldKind =fkData then 
    myFieldName := UpperCase(Column.Field.FieldName) 
  else 
    myFieldName := UpperCase(Column.Field.KeyFields); 
  while Pos(myFieldName,';')<>0 do 
    myFieldName := copy(myFieldName,1,Pos(myFieldName,';')-1) 
                  + ',' + copy(myFieldName,Pos(myFieldName,';')+1,100); 
  with TQuery(TDBGrid(Column.Grid).DataSource.DataSet) do 
  begin 
    SqlStr := UpperCase(Sql.Text); 
//  if pos(myFieldName,SqlStr)=0 then exit; 
    if ParamCount>0 then 
    begin 
      SavedParams := TParams.Create; 
      SavedParams.Assign(Params); 
    end; 
    OrderPos := pos('ORDER',SqlStr); 
    if (OrderPos=0) or 
      (pos(myFieldName,copy(SqlStr,OrderPos,100))=0) then 
      TempStr := ' Order By ' + myFieldName + ' Asc' 
    else if pos('ASC',SqlStr)=0 then 
      TempStr := ' Order By ' + myFieldName + ' Asc' 
    else 
      TempStr := ' Order By ' + myFieldName + ' Desc'; 
    if OrderPos<>0 then SqlStr := Copy(SqlStr,1,OrderPos-1); 
    SqlStr := SqlStr + TempStr; 
    Active := False; 
    Sql.Clear; 
    Sql.Text := SqlStr; 
    if ParamCount>0 then 
    begin 
      Params.AssignValues(SavedParams); 
      SavedParams.Free; 
    end; 
    Prepare; 
    Open; 
  end; 
end; 上面的是对query进行排序的过程。 
不过有个问题是如果DBGRID所使用的数据集不是TQuery而是TTable或其他的话可能会出错!如果需要实现这样的功能,建议使用Express Grid套件! 

解决方案 »

  1.   

    DBGrid是通过数据集来显示的,你可以通过Sql语句来排序
      

  2.   

    多建几个索引,响应ontitle事件,调用相应的索引不是更方便吗?
      

  3.   

    用sql排序只能浏览,不能编辑数据!
      

  4.   

    我还用过一个方法:
    开一个很大的数组,然后将query的来的数据全部存在与该数组中,然后使用stringgrid与该数组一起使用,想选什么就在本地这数组中选就ok 拉。但写起来很烦,并且很多漏洞。比如的确数据太多了等等--所以这是个本方法,所一我觉得我是个白痴算拉。
      

  5.   

    不,用SQL(通过Query)可以进行编辑,不过,我不想用SQL语句来排序,那样如果数据很多就会很慢。
      

  6.   

    DBGrid->DataSource->ClientDataSet->DataSetProvider->Query->DataBase然后用Query查出想要的数据,在ClientDataSet的IndexFieldNames里指定想按什么字段排序。更新数据就用ClientDataSet的Applyupdates,如果想多表更新,就要加多一个UpdateSQL指向Query。这是最简单的解决方法,D5下试过没问题,就是放多了两个控件,程序大了一点。 :)
      

  7.   

    要是你用的是ADO那就方便了,
    AdoDataset.sort:=‘field1 ASC’
      

  8.   

    如果用ADO的话用字段排序属性就行了!呵呵!
      

  9.   

    用sql的order by 语句后的查询结果是不能编辑的。
      

  10.   

    可以编辑,不过要用到updateSQL.
      

  11.   

    http://www.csdn.net/expert/topic/176/176628.shtm这问题已经问过好几次了。
      

  12.   

    采用ClientDataSet的方法可以,但是如何设置它为升序或者降序排列呢?