点击列标题来对DBGrid进行排序

4

嗯,这似乎有点棘手(如果不是不可能的话)。我正在尝试使我的DBGrid通过点击列标题对其数据进行排序。

问题在于我(可悲地)正在使用Delphi 3,我没有使用ADO DataSets,并且查询获取了很多行,因此我无法在点击时重新打开我的TQuery并更改order by子句。

有人实现过这样的功能吗?

8个回答

9

实际上是通过对数据集进行排序来完成的,然后网格反映了这种变化。 可以通过在该列的数据集字段上创建索引轻松完成此操作。 当然,这只能在支持索引排序的数据集上完成,例如TClientDataset


正如所述,DBGrid 的顺序基于 TDataset 中数据的顺序。因此,改变 DBGrid 的顺序的唯一方法是改变 TDataset 的顺序,这取决于您正在使用的实际 TDataset 子类... 因此,您可能需要考虑创建自己的 TDataset 子类,以反映另一个 TDataset 中按所需顺序排列的数据。 - R. Hoek
TFDQuery 还支持索引。 - Soon Santos

4
在TDBGrid的OnTitleClick方法中,您可以执行以下操作...
procedure TfmForm1.DBGrid1TitleClick(Column: TColumn);
var
   i: Integer;
begin
   // apply grid formatting changes here e.g. title styling
   with DBGrid1 do
      for i := 0 to Columns.Count - 1 do
         Columns[i].Title.Font.Style := Columns[i].Title.Font.Style - [fsBold];
   Column.Title.Font.Style := Column.Title.Font.Style + [fsBold];

   with nxQuery1 do // the DBGrid's query component (a [NexusDB] TnxQuery)
   begin
      DisableControls;
      if Active then Close;
      for i := 0 to SQL.Count - 1 do
         if (Pos('order by', LowerCase(SQL[i])) > 0) then
            //NOTE: ' desc' The [space] is important
            if (Pos(' desc',LowerCase(SQL[i])) > 0) then 
               SQL[i] := newOrderBySQL
            else
               SQL[i] := newOrderBySQL +' desc';
      // re-add params here if necessary
      if not Active then Open;
      EnableControls;
   end;
end;

我相信有很多种方法可以进行优化,但这取决于您使用的组件的能力。上面的示例使用了一个查询组件,但如果您使用了一个表格组件,您需要更改使用的索引而不是'order by'子句。

这里处理SQL的方式是非常基本的版本。它不能处理诸如SQL批处理语句之类的事情,可能会导致多个“order by…”子句或注释的SQL语句,即忽略带括号的注释“{…}”或单行注释“//”

敬礼


2
这个问题明确地说:“因此,我无法在单击时重新打开我的TQuery并更改按子句排序。”。发布一个完全做与问题要求的相反的答案如何帮助解决问题? - Ken White

0
在TDBGrid的OnTitleClick方法中,你可以写下这个简单的代码:
procedure TForm1.DBGrid3TitleClick(Column: TColumn);
var
  cFieldName:string;
begin
  cFieldName:= DBGrid3.SelectedField.FieldName;
  AdoDataset1.Sort:=cFieldName;
end;

0

Delphi 3有TClientDataset。而TQuery可以使用在数据库上显式创建的索引,在IndexName属性上对数据进行排序。


并不一定是真的,我的Delphi 4 Pro和Delphi 5 Pro安装中都没有TClientDataSet。也许只有企业版才有? - mghie
嗯,在这些版本中,我只接触过企业版(因为我通常在本地工作)。但是D3 Enterprise肯定有TClientDataset。 - Fabricio Araujo

0

以下是如何实现的一些示例:通过单击列标题在Delphi DBGrid中排序记录

如前所述,如果您使用TClientDataSet(在TDBGridOnTitleClick中使用cds.IndexFieldNames := Column.FieldName),则排序非常容易。但是,如果您无法这样做,您可以重新生成查询(您已经声明您不想这样做),或者获取更高级的数据网格,例如Express Quantum Grid(我认为它允许您进行排序)。


0
如果您正在使用 TFDQueryTDataSourceTDBGrid 的组合,您可以通过以下简单方式进行排序!

procedure TFrmGer.DBGridTitleClick(Column: TColumn);
begin
  OrderByTitle(MyFDQuery, Column);
end;

将其放入助手文件中,以便以后再次使用。
procedure OrderByTitle(AQuery: TFDQuery; Column: TColumn);
begin
  AQuery.IndexFieldNames := Column.DisplayName;
end;

0

例子:(https://www.thoughtco.com/sort-records-in-delphi-dbgrid-4077301)

procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
 pt: TGridcoord;
begin
 pt:= DBGrid1.MouseCoord(x, y);
 if pt.y=0 then
 DBGrid1.Cursor:=crHandPoint
 else
 DBGrid1.Cursor:=crDefault;
end;

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
  cFieldName:string;
begin
  Adotable1.Sort := Column.Field.FieldName;
end;

请解释这个回答如何回答了问题。 - Pierre.Vriens

0

升序和降序模式

  if Pos('DESC',PChar(Q2.Sort))>0 then
    Q2.Sort:=Column.FieldName  + ' ASC'
  else
    Q2.Sort:=Column.FieldName  + ' DESC';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接