Ordenar ClientDataset (IndexFieldNames) em ordem decrescente

Delphi

18/10/2004

procurei mas não encontrei...

...dá pra indexar o ClienteDataset pela propriedade IndexFieldNames em ordem decrescente?

eu quero ordenar dinamicamente, por isso estou tentando evitar o ORDER BY


Emerson Nascimento

Emerson Nascimento

Curtidas 0

Melhor post

Marcelo Belanga

Marcelo Belanga

12/10/2016

E para quem usa Firedac, a solução ficou ainda mais fácil.

if FDQuery1.IndexFieldNames = Column.FieldName then
FDQuery1.IndexFieldNames := Column.FieldName + ':D'
else
FDQuery1.IndexFieldNames := Column.FieldName;
GOSTEI 4

Mais Respostas

Osocram

Osocram

18/10/2004

no indexname vc coloca o campo no qual vai ser feito a ordenacao... lembre-se q o campo deve ser do tipo fkData

e p mudar p descrescente
adiciona no campo idOption do index a opcao ixDescending


GOSTEI 1
Emerson Nascimento

Emerson Nascimento

18/10/2004

vou explicar o caso:

tenho um clientdataset q recebe instruções dinamicamente, conforme a escolha do usuário. ele escolhe tabela, os campos que deseja mostrar e como quer agrupar. depois, na grade que exibe esses valores, ele pode clicar no título de uma coluna e a ordenação será pelo campo dessa coluna cujo título foi clicado. se por acaso for dado um novo clique num título cujo campo é o indice ativo, será invertida a ordem (assim como acontece no windows explorer).

por que não utilizar o IndexName: não quero ficar criando índices.

utilizo apenas a propriedade [b:49ed744fc1]IndexFieldNames[/b:49ed744fc1]. tem outra forma?


GOSTEI 1
Osocram

Osocram

18/10/2004

if not (Column.Field.DataType in [ftblob, ftMemo]) then
if Column.Field.FieldKind = fkData then begin
CDS.IndexFieldNames := Column.DisplayName;

dae vc faz uma verificacao se for a mesma coluna vc adiciona o ixDescending


GOSTEI 1
Emerson Nascimento

Emerson Nascimento

18/10/2004

desculpe, mas estou meio devagar...
onde coloco o ixDescending?


GOSTEI 0
Ananias Duarte

Ananias Duarte

18/10/2004

Osocram, por favor diga-me:

1) se não intiver usando o ClienteDataSet, como é que faz isso;
2) onde é que é colocado o código que vc citou?
obrigado

emerson.en

Achei legal essa técnica que vc está implementando no DBGrid. Por favor, pode repassá-la para mim. Sou inciante no Delphi(6) e goataria de colocar essa ´facilidade´ em todos os DBGrids do sistema que estou ´tantando´ desenvolver.
abraços


GOSTEI 1
Macario

Macario

18/10/2004

Olá [b:6b00b984d5]emerson.en[/b:6b00b984d5], este tópico foi resolvido?

Eu tambem estou quem esta necessidade.


Grato. :arrow:


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

18/10/2004

foi resolvido sim. precisei criar índices em tempo de execução (não há perda de performance).
eu fiz assim:
ao clicar na grade, vejo se o campo no IndexFieldNames é o mesmo campo cuja coluna foi clicada:
- se não é o mesmo campo, altero o IndexFieldNames para o campo clicado
- se é o mesmo campo (isso indica que a ordenação será invertida)...
   verifico se existe o índice "CAMPO"_INV:
   - se não encontrar esse índice, o crio com a opção ixDescending;
   depois altero a propriedade IndexName para "CAMPO"_INV

caso eu não tenha conseguido me explicar bem, eu posso te passar um exemplo...


GOSTEI 1
Macario

Macario

18/10/2004

Olá [b:e19244c9fd]emerson.en[/b:e19244c9fd].

Então relamente com IndexFieldName não é possivel (tá uma sugestão pra Borland, ou até mesmo pra quem goste de criar seus proprios Procedimentos).


No caso, como você esta tratando quando ja criou um indice?

por exmeplo, foi criado pra coluna1, depois pra coluna2. Voce libera e cria no novo ou vai deixando?

Por favor, poste seu exemplo.


8)


GOSTEI 1
Emerson Nascimento

Emerson Nascimento

18/10/2004

eis minha solução:
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
  indice: string;
  existe: boolean;
  clientdataset_idx: tclientdataset;
begin
  clientdataset_idx := TClientDataset(Column.Grid.DataSource.DataSet);

  if clientdataset_idx.IndexFieldNames = Column.FieldName then
  begin
    indice := AnsiUpperCase(Column.FieldName+´_INV´);

    try
      clientdataset_idx.IndexDefs.Find(indice);
      existe := true;
    except
      existe := false;
    end;

    if not existe then
      with clientdataset_idx.IndexDefs.AddIndexDef do begin
        Name := indice;
        Fields := Column.FieldName;
        Options := [ixDescending];
      end;
    clientdataset_idx.IndexName := indice;
  end
  else
     clientdataset_idx.IndexFieldNames := Column.FieldName;
end;
essa é uma rotina genérica que pode ser associada a todas as grades sem qualquer alteração (desde que as grades estejam ligadas à clientdataset´s)
- note que essa rotina não altera a posição do ponteiro de registros. caso ache necessário, adicione a linha [i:b6a810ba7d]clientdataset_idx.first[/i:b6a810ba7d] ao final da rotina.
- note também que NÃO se deve liberar o clientdataset_idx da memória, pois ele é uma referência ao objeto real. se você liberá-lo, estará destruindo o clientdataset real.
- note ainda que esse(s) índice(s) será(ão) perdido(s) quando o clientdataset for fechado, pois eles estão somente em memória.


GOSTEI 1
Macario

Macario

18/10/2004

Agradeço a ajuda, estou adotando a utlização da rotina.


GOSTEI 1
Paulo Andrade

Paulo Andrade

18/10/2004

Tentei usar e apresentou erro, uso os bancos Access e SQL Server com o mesmo sistema. Após ajuste funcionou dessa forma:

procedure TfFuncionarios.DBGrid1TitleClick(Column: TColumn);
var
  indice: string;
  existe: boolean;
  cds_idx: TADODataSet;
begin
  cds_idx := TADODataSet(Column.Grid.DataSource.DataSet);
  if cds_idx.IndexFieldNames = Column.FieldName then
  begin
    indice := AnsiUpperCase(Column.FieldName+' DESC');

    try
      cds_idx.IndexDefs.Find(indice);
      existe := true;
    except
      existe := false;
    end;
    if not existe then
      with cds_idx.IndexDefs.AddIndexDef do
      begin
        Name := indice;
        Fields := Column.FieldName;
        Options := [ixDescending];
      end;
    cds_idx.IndexFieldNames := indice;
  end else
    cds_idx.IndexFieldNames := Column.FieldName;
  Ordenacao := Column.FieldName;
end;
GOSTEI 1
Emerson Nascimento

Emerson Nascimento

18/10/2004

Paulo Henrique, discordo do "apresentou um erro".

Foi dito claramente que a rotina foi desenvolvida para ClientDatasets. Para os demais datasets, basta efetuar as alterações necessárias como, no seu caso, a troca do TClientDataset pelo TADODataSet.
GOSTEI 1
Paulo Andrade

Paulo Andrade

18/10/2004

Troquei também o ´_INV´´ por ' DESC'.

No meu caso usei TADODataSet mesmo e banco SQL Server.

Paulo Henrique, discordo do "apresentou um erro".

Foi dito claramente que a rotina foi desenvolvida para ClientDatasets. Para os demais datasets, basta efetuar as alterações necessárias como, no seu caso, a troca do TClientDataset pelo TADODataSet.
GOSTEI 1
POSTAR