DBGRID 标题点击排序
我从网上找到DBGRID 标题点击排序的方法,无法理解lastcolumn是什么意思?
如何才能不再提示 '没有[Error] SpecPrint1.pas(169): Undeclared identifier: 'lastcolumn '}
[解决办法]
procedure Tf_Department.DBGrid1TitleClick(Column: TColumn);
var i:integer;
begin
if (pos( '▲ ', Column.Title.Caption)=0) and (pos( ' ', Column.Title.Caption)=0) then //说明前面没有排过序
begin
ADOQ.Sort:=Column.FieldName+ ' ASC '; //asc一定要大写
Column.Title.Caption:= ' '+column.Title.Caption ;
end else
if (pos( '▲ ', Column.Title.Caption)=0) then //说明目前是降序
begin
ADOQ.Sort:=Column.FieldName+ ' ASC '; // ↑占用了2个位,所以从第3位开始读真实字段
Column.Title.Caption:= '▲ '+copy(Column.Title.Caption,3,length(Column.Title.Caption)-2);
end else
if (pos( ' ', Column.Title.Caption)=0) then //说明目前是升序
begin
ADOQ.Sort:=Column.FieldName+ ' DESC ';
Column.Title.Caption:= ' '+copy(Column.Title.Caption,3,length(Column.Title.Caption)-2) ;
end;
try
ADOQ.Active:=true;
for i:=0 to DBGrid1.FieldCount-1 do
begin
if (i <> Column.Index) then
begin
if (pos( '▲ ', dbgrid1.Columns[i].Title.Caption) <> 0) or (pos( ' ', dbgrid1.Columns[i].Title.Caption) <> 0) then
dbgrid1.Columns[i].Title.Caption:=copy(dbgrid1.Columns[i].Title.Caption,3,length(dbgrid1.Columns[i].Title.Caption)-2);
end;
end;
/////////////////////////////////////////
except
showmessage( '排序生常! ');
end;
end;
[解决办法]
对于DBGrid排序,我写了一个通用的程序,依靠点击Grid表头排序,支持多字段排序,支持正序反序.
但是要求DBGrid连接的控件是ClientDataSet或者ADOQuery/ADOTable/ADODataSet,原理是将数据下载在本地,使用Dataset的Index系列属性实现排序,排序效率比Order by 高的多.
可以把这个程序加入到DBGrid的OnTitleClick事件中
function DBGridTitleClick(Gx:TDBGrid;Column:TColumn):Boolean;
var fdn,disp,flag,ins1:string;
Fdns,descs:string;
tmp:string;
pos1:integer;
Cx:TClientDataSet;
function GetIndexName:string;
var s1:string;
begin
s1:= 'I '+DateTimeToStr(Now)+IntToStr(Random(999));
s1:=AnsiReplaceText(s1, ' ', ' ');
s1:=AnsiReplaceText(s1, '_ ', ' ');
s1:=AnsiReplaceText(s1, ': ', ' ');
Result:=s1;
end;
begin
Result:=False;
tmp:=Gx.Hint;
pos1:=pos( '$ ',tmp);
if pos1> 0 then
begin
fdns:=copy(tmp,1,pos1-1);
delete(tmp,1,pos1);
descs:=tmp;
end;
if not Assigned(Gx.DataSource) then exit;
if not Assigned(Gx.DataSource.DataSet) then exit;
if Uppercase(Gx.DataSource.DataSet.ClassName) <> Uppercase( 'TClientDataSet ') then exit;
Cx:=(Gx.DataSource.DataSet as TClientDataSet);
if not Assigned(Column) then exit;
if not Cx.Active then
begin
ShowMessage( '数据集没有打开 ');
exit;
end;
if Gx.DataSource.DataSet.RecordCount=0 then exit;
if Cx.IndexDefs.Count> 0 then fdns:=Cx.IndexDefs.Items[Cx.IndexDefs.Count-1].Fields;
if Cx.IndexDefs.Count> 0 then descs:=Cx.IndexDefs.Items[Cx.IndexDefs.Count-1].DescFields;
fdn:=Cx.Fields[Column.Index].FieldName;
disp:=Cx.Fields[Column.Index].DisplayLabel;
if pos( '↓ ',disp)> 0 then
begin
flag:= '↑ ';//如果正续排列
if pos(fdn,fdns)=0 then fdns:=fdns+ '; '+fdn;//如果没有正序,则添加
if pos(fdn,descs)=0 then descs:=descs+ '; '+fdn;//增加反序
end
else if pos( '↑ ',disp)> 0 then
begin
flag:= ' ';//如果无序
fdns:=AnsiReplaceText(fdns,fdn, ' ');
descs:=AnsiReplaceText(descs,fdn, ' ');
end
else
begin
flag:= '↓ ';//如果反序
if pos(fdn,fdns)=0 then fdns:=fdns+ '; '+fdn;//增加索引
if pos(fdn,descs)=0 then descs:=AnsiReplaceText(descs,fdn, ' ');//去除反续
end;
fdns:=AnsiReplaceText(fdns, ' ', ' ');
while pos( ';; ',fdns)> 0 do fdns:=AnsiReplaceText(fdns, ';; ', '; ');
if copy(fdns,1,1)= '; ' then delete(fdns,1,1);
if copy(fdns,length(fdns),1)= '; ' then delete(fdns,length(fdns),1);
descs:=AnsiReplaceText(descs, ' ', ' ');
while pos( ';; ',descs)> 0 do descs:=AnsiReplaceText(descs, '; ', '; ');
if copy(descs,1,1)= '; ' then delete(descs,1,1);
if copy(descs,length(descs),1)= '; ' then delete(descs,length(descs),1);
disp:=flag+fdn;
Cx.DisableControls;
ins1:=GetIndexName;
while Cx.IndexDefs.Count> 0 do Cx.DeleteIndex(Cx.IndexDefs.Items[0].Name);
Cx.IndexName:= ' ';
Cx.AddIndex(ins1,fdns,[ixCaseInsensitive],descs, ' ',0);
Cx.IndexName:=ins1;
Cx.Fields[Column.Index].DisplayLabel:=flag+fdn;
Cx.First;
Cx.EnableControls;
Gx.Hint:=fdns+ '$ '+descs;
pos1:=cx.IndexDefs.Count;
Result:=True;
end;