dbgrid中按任意feild排序(200分)

  • 主题发起人 主题发起人 wfl
  • 开始时间 开始时间
W

wfl

Unregistered / Unconfirmed
GUEST, unregistred user!
delphi 中在dbgrid如何點擊任意field欄位,則按此field排序?
請大師指點!多謝!
 
不太容易实现,不过,我想简单的方法是可以多设几个索引,点击的时候先判断点的是哪
一列,然后设置相应的索引并刷新就行了
 
用第三方控件
ehlib
例子: 注:bz 为一boolean类型变量
procedure Tform1.DBGridEhTitleBtnClick(Sender: TObject; ACol: Integer;
Column: TColumnEh);
begin
If bz then
begin
TADOQuery(DBGridEh.DataSource.DataSet).Sort := Column.FieldName+' ASC';
Column.Title.SortMarker := smUpEh;
bz := False;
end
else
begin
TADOQuery(DBGridEh.DataSource.DataSet).Sort := Column.FieldName+' DESC';
Column.Title.SortMarker := smDownEh;
bz := True;
end
end;
 
可以借鉴第三方控件
 
使用 Query 不久行了吗?
 
DBGrid.CellClick 事件:

F := Column.FieldName;
DBGrid.Columns.BeginUpdate;
Query1.SQL.Text := 'Select * from TableName order by ' + F;
Query1.Open;
DBGrid.Columns.EndUpdate;
 
下面是我自己写的一个排序dbgrid的源码

增加了一个OrderSQLLine属性,默认值是-1
将此grid与一个query相连,
query的sql语句的排序行不要填写内容,并将行号赋给OrderSQLLine
例如:
query.sql[0]:='select * ';
query.sql[1]:='from mytable';
query.sql[2]:='where xxxx=1';
query.sql[3]:=''; //这一行为空,按grid题头时将自动填充
将grid.OrderSQLLine设置为3。如果是-1, 表示不作排序处理。

控件还包括多选功能,如果用户设置了多行选择功能,那么可以按Shift键多选
(dbgrid按Ctrl逐个选取),不过还存在一些问题,就是当用户点击scrollbar时选取不准
在此向各位DFW请教。

//////////////////////////////////////
unit AdmyDBGrid;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, DBGrids, Db, DBTables;

type
TAdmyDBGrid = class(TDBGrid)
private
{ Private declarations }
FOrderSQLLine:integer;
FOrderColumnIndex:integer;
FOrderSql:string;
x0,y0:integer;
protected
{ Protected declarations }
procedure TitleClick(Column: TColumn); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
public
{ Public declarations }
property OrderSql:string read FOrderSql;
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property OrderSQLLine:integer read FOrderSQLLine write FOrderSQLLine;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('AdmyCom', [TADMYDBGrid]);
end;

constructor TAdmyDBGrid.Create(AOwner: TComponent);
begin
inherited create(AOwner);
FOrderSQLLine:=-1;
FOrderColumnIndex:=-1;
x0:=-1;
y0:=-1;
end;

procedure TAdmyDBGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
function RowtoY(Arow,Rh:integer):integer;
begin
Result:=CellRect(0,0).bottom+1+(Arow-1)*Rh;
end;
var RowHeight,CurRow,c1,c2:integer;
begin
if(not DataSource.DataSet.active)
or(not(dgMultiSelect in Options))
or(not(ssShift in Shift))
or(x0=-1)or(y0=-1)then
begin
inherited MouseDown(Button,Shift,X,Y);
x0:=MouseCoord(x,y).x;
y0:=MouseCoord(x,y).y;
end else begin
RowHeight:=CellRect(0,1).bottom-CellRect(0,1).top+1; //加上隔线高度
if MouseCoord(x,y).y<y0 then begin
c1:=MouseCoord(x,y).y;
c2:=y0;
end else begin
c1:=y0;
c2:=MouseCoord(x,y).y;
end;

SelectedRows.Clear;
for CurRow:=c1 to c2 do
inherited MouseDown(Button,Shift+[ssCtrl]-[ssShift],X,RowtoY(CurRow,RowHeight));
end;
end;

procedure TAdmyDBGrid.TitleClick(Column: TColumn);
var query:tquery;
FieldValue:variant;
OrderFieldName,BakSQL:string;
CurColumnIndex:integer;
begin
inherited TitleClick(Column);

if not assigned(column.Field) then exit;
OrderFieldName:=column.FieldName;

if not (column.Field.FieldKind=fkData) then exit;

if not (column.Field.DataSet is tquery) then exit;
query:=(column.Field.DataSet as tquery);

if not query.Active then exit;
if(FOrderSQLLine<0)or(FOrderSQLLine>query.sql.Count-1)then exit;

FieldValue:=column.Field.Value;
CurColumnIndex:=column.Index;
if FOrderColumnIndex=column.Index then FOrderColumnIndex:=-1
else FOrderColumnIndex:=column.Index;

query.close;
TRY
BakSQL:=query.sql[FOrderSQLLine];
if FOrderColumnIndex=-1 then
query.sql[FOrderSQLLine]:=' order by '+OrderFieldName+' desc '
else
query.sql[FOrderSQLLine]:=' order by '+OrderFieldName;

// query.sql.savetofile('tmp.sql');
query.open;
query.locate(OrderFieldName,FieldValue,[]);
SelectedIndex:=CurColumnIndex;
EXCEPT //恢复原语句
query.sql[FOrderSQLLine]:=BakSQL;
query.open;
query.locate(OrderFieldName,FieldValue,[]);
END;
end;

end.
 
用dxDBGrid吧, DevExpress的ExpressQuantumGrid--dxGrid, 不写代码即完成你的功能,
或者用ehlib, 要写点代码, 设置点属性。

用AdoTable的可用Sort 排序,也不用重新访问数据库
 
procedure TfrmQuery.DBGrid1TitleClick(Column: TColumn);
begin
if Column.Grid.DataSource.DataSet.Active=TRUE then
begin
if Column.Grid.Tag=0 then
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort:=Column.FieldName+' ASC';
Column.Grid.Tag:=1;
end
else
begin
TADODataSet(Column.Grid.DataSource.DataSet).Sort:=Column.FieldName+' DESC';
Column.Grid.Tag:=0;
end;
end;
end;
这个过程很简单又很实用,可以到处调用,很爽的.
 
多人接受答案了。
 
后退
顶部