O procedimento abaixo, ordena qualquer conjunto de ClientDataSet, DBGrid e Coluna, chamado a partir do evento ontitleclick de qualquer dbgrid.
Ele coloca bold no tituo da coluna clicada, e ordena no primeiro clique crescente e no segundo decrescente e assim vai alternando a cada clique na mesma coluna. Este procedimento é o que uso em minhas aplicações comerciais, e pode ser encontrado implementado e funcionando em quase todos os meus exemplos, especialmente o ultimo que postei (primeiro da lista) no meu link de downloads gratuitos (http://cc.codegear.com/Author/795118) que possui uma aplicação só para explicar sobre os recursos do ClientDataSet. procedure TDM.OrdenaCDSGrid(var CDS: TClientDataSet; var DBG: TDBgrid; Column: TColumn); const idxDefault = 'DEFAULT_ORDER'; var strColumn : string; i : integer; bolUsed : boolean; idOptions : TIndexOptions; begin strColumn := idxDefault; if Column.Field.FieldKind in [fkCalculated, fkLookup, fkAggregate] then Exit; if Column.Field.DataType in [ftBlob, ftMemo] then Exit; for i := 0 to DBG.Columns.Count - 1 do begin DBG.Columns[i].Title.Font.Style := []; end; DBG.Columns[Column.Index].Title.Font.Style := [fsBold]; bolUsed := (Column.Field.FieldName = CDS.IndexName); CDS.IndexDefs.Update; for i := 0 to CDS.IndexDefs.Count - 1 do begin if CDS.IndexDefs.Items[i].Name = Column.Field.FieldName then begin strColumn := Column.Field.FieldName; case (CDS.IndexDefs.Items[i].Options = [ixDescending]) of True : idOptions := []; False : idOptions := [ixDescending]; end; end; end; if (strColumn = idxDefault) or (bolUsed) then begin if bolUsed then CDS.DeleteIndex(Column.Field.FieldName); try CDS.AddIndex(Column.Field.FieldName, Column.Field.FieldName, idOptions, '', '', 0); strColumn := Column.Field.FieldName; except if bolUsed then strColumn := idxDefault; end; end; try CDS.IndexName := strColumn; except CDS.IndexName := idxDefault; end; end; abs BL De: delphi-br@yahoogrupos.com.br [mailto:[EMAIL PROTECTED] Em nome de Rubem Nascimento da Rocha Enviada em: quinta-feira, 24 de janeiro de 2008 01:40 Para: delphi-br@yahoogrupos.com.br Assunto: RE: [delphi-br] Rotina genérica para ordenação Prioridade: Alta O DBGrid está ligado a um DataSource, que por sua vez está ligado a um ClientDataSet. Levando em conta este fato, e tb que a classe TColumn possui uma propriedade chamada Grid, da classe TCustomDBGrid, que representa o DBGrid a qual mesma pertence, tem como achar o ClientDataSet usado pelo DBGrid sem precisar fazer essa lambança de criar um novo ClientDataSet. Desse jeito, vais acabar tendo um consumo de memória desnecessário. Exemplo: procedure TfrmBasico_ComGrid.DBGrid1TitleClick(Column: TColumn); var lCds: TClientDataSet; begin if Column.Grid.DataSource.DataSet is TClientDataSet then begin lCds := TClientDataSet(Column.Grid.DataSource.DataSet); if FOldColumn <> Column then begin FOldColumn := Column; lCds.IndexFieldName := Column.FieldName; end; end; end; Basicamente, é isso. No código acima, assume-se que FOldColumn é um campo privado que guarda a coluna pela qual o dataset do grid (e não o próprio grid) era anteriormente ordenado. Como sugestão de melhoria (aí é por sua conta!), poderíamos acrescentar a alternância da ordenação para ascendente ou decrescente caso a coluna clicada seja a mesma que a anteriormente selecionada. Sds. ________________________________ To: [EMAIL PROTECTED] <mailto:NDDV%40yahoogrupos.com.br> From: [EMAIL PROTECTED] <mailto:papaia.forum%40gmail.com> Date: Thu, 24 Jan 2008 00:13:44 -0200 Subject: [delphi-br] Rotina genérica para ordenação Tenho o form genérico (frmBasico_ComGrid) para pesquisa, com um DBGrid, obviamente ligado à um DataSource, que por sua vez está ligado à um ClientDataSet (mas que muda em cada formulário filho: cdsclientes, cdsparcelas, cdscidades, cdsprofissoes, etc). Estou tentando manipular o evento DBGrid1TitleClick, no formulário básico para ordenação pelas colunas, mas preciso saber o nome do CDS que está sendo manipulado no momento da ordenação, então fiz de acordo com o código abaixo. Compila normalmente, mas dá erro em tempo de execução, dizendo que o nome do cds não é válido, e a mensagem de erro mostra o nome do CDS de forma correta, só que entre aspas duplas. OBS: 'dm.' -> é o nome do datamodule. Se alguem puder me orientar onde estou errando, ou apontar outro caminho, antecipadamente meus agradecimentos. procedure TfrmBasico_ComGrid.DBGrid1TitleClick(Column: TColumn); Var cds:TClientDataSet; str:TComponentName; begin CDS := TClientDataSet.Create(Self); str:=DBGrid1.DataSource.DataSet.Name; cds.Name:= 'dm.' + str; if Assigned(OldColumn) then OldColumn.Title.Color:=DBGrid1.FixedColor; cds.IndexFieldNames:=Column.FieldName; Column.Title.Color:=clRed; OldColumn:=Column; end; Atenciosamente waldir silva __________________________________________________________ Veja mapas e encontre as melhores rotas para fugir do trânsito com o Live Search Maps! http://www.livemaps.com.br/index.aspx?tr=true __________ NOD32 2818 (20080123) Information __________ This message was checked by NOD32 antivirus system. part000.txt - is OK part001.htm - is OK http://www.eset.com [As partes desta mensagem que não continham texto foram removidas]