Reaproveitando código em delphi com dbgrids

18/07/2008

1

Olá a todos, tenho um procedimento que faz a ordenação ao clicar no título de uma dbgrid. Gostaria de reaproveitar este código em outras dbgrids criando procedimentos. Passo como parâmetro a grid e o clientdataset. Quase consegui da seguinte forma:

Variaveis do formulario:

var
FrmClientes: TFrmClientes;
grid : TDBGrid;
cds: TClientDataSet;
Indice: string;
FlagDesc: Boolean;
OldColumn : TColumn;

Declaração do cabeçalho do procedimento:

procedure OrdenarGris (cds: TClientDataSet; grid: TDBGrid);

Corpo do procedimento:

procedure TFrmClientes.OrdenarGris(cds: TClientDataSet; grid: TDBGrid);
begin
with cds do
begin
//Random para mudar o nome do indice, se colocar o indice fixo não funciona
Indice := ´Indice´ + IntToStr(Random(9999));
// Verifica se o campo anterior estáva em modo Ascendente ou Descendente
FlagDesc := (IndexDefs.Count > 0) and (ixDescending in IndexDefs[0].Options);
// Se a coluna do dbgrid força a Ascendente
if (IndexDefs.Count > 0) and (IndexDefs[0].Fields <> Column.FieldName) then
FlagDesc := True;
IndexDefs.Clear; // Limpa o indice anterior
case FlagDesc of
True: IndexDefs.Add(Indice, Column.FieldName, []);
False: IndexDefs.Add(Indice, Column.FieldName, [ixDescending]);
end;
IndexName := Indice;
if Assigned(OldColumn) then
OldColumn.Title.Color := grid.FixedColor;
Column.Title.Color := clred;
OldColumn := Column;
end; //fim do with
end;

Chamada do procedimento

procedure TFrmClientes.DBGrid1TitleClick(Column: TColumn);
begin
OrdenarGris(DMClientes.CdsListaVendasClientes, DBGrid1);
end;

Mas dá erro ao compilar, seguem abaixo os erros:

Build
[Error] UClientes.pas(875): Undeclared identifier: ´Column´
[Error] UClientes.pas(879): Not enough actual parameters
[Error] UClientes.pas(882): Undeclared identifier: ´IndexName´
[Error] UClientes.pas(885): Missing operator or semicolon
[Error] UClientes.pas(888): ´.´ expected but ´;´ found
[Fatal Error] Ideal.dpr(159): Could not compile used unit ´UClientes.pas´

Alguém pode me ajudar?


Responder

Posts

18/07/2008

Marco Salles

Ordenação usando clientDataSet ao clicar no titulo de uma Grid , é so indexar o ClientDataSet

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
SeuDataSet.IndexFieldNames:=column.FieldName;
end;



Responder

18/07/2008

Marco Salles

e se eu entendi bem a sua necessidade , voce pode reaproveitar o codigo
usando por exemplo RTTI

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
with (Column.Field.dataset as TclientDataset) do
  IndexFieldNames:=Column.FieldName;
end;



Responder

18/07/2008

Frostlost

Na realidade meu código ordena a grid em ordem ascendente e descendente, mas ainda não consegui utilizar o campo column até porque ele é um parâmetro específico de outro procedimento que é o TitleClick do DBGrid. Ainda não consegui fazer.

Obrigado

[quote:4792b5a1d5=´Marco Salles´]e se eu entendi bem a sua necessidade , voce pode reaproveitar o codigo
usando por exemplo RTTI

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
with (Column.Field.dataset as TclientDataset) do
  IndexFieldNames:=Column.FieldName;
end;
[/quote:4792b5a1d5]


Responder

18/07/2008

Marco Salles

Na realidade meu código ordena a grid em ordem ascendente e descendente,


é do jeito que lhe fora passado , a ordenação é so ascendente .
Mas aqui memso no Forum há codigos para a ordenação inversa
Eu mesmo se não me falha a memória , ja participei deste tipo de
dúvida

mas ainda não consegui utilizar o campo column até porque ele é um parâmetro específico de outro procedimento que é o TitleClick do DBGrid. Ainda não consegui fazer.


mas isto ha meu ver não é nenhum problema

Voce pode ter um procedure Generica em OutroForm e no evento OnTitle
do DbGrid voce passa o parâmetro especifico

Por exemplo em uma Unit Qualquer

procedure QueOrdenaAgrid(collum:Tcoluum);
begin
//faço assim Falo Assado
end;

e no Evento OnTitleClick(Column: TColumn); da sua Grid voce Chama
esta Procedure

procedure TForm1.DBGrid1TitleClick(Column: TColumn); 
begin 
QueOrdenaAgrid(columm);
end;


voce não esta conseguindo pq esta usando Propriedades que talves não seje inerentes ao objeto

Fiz uma alteraçoes no seu codigo do jeito que funciona , alternando entre Ascendente e Descedente ... So digo uma coisa ..Tudo que voce fez da
para fazer somente com un Unico parãmetro passado : O parametro
Column: TColumn

var
Indice: string;
FlagDesc: Boolean;



procedure TForm1.OrdenarGris(cds:TclientDataset;OldColumn:TColumn; grid: TDBGrid);
begin
with cds do
begin
//Random para mudar o nome do indice, se colocar o indice fixo não funciona 
Indice := ´Indice´ + IntToStr(Random(9999));
// Verifica se o campo anterior estáva em modo Ascendente ou Descendente
FlagDesc := (IndexDefs.Count > 0) and (ixDescending in IndexDefs[0].Options);
// Se a coluna do dbgrid força a Ascendente
if (IndexDefs.Count > 0) and (IndexDefs[0].Fields <> OldColumn.FieldName) then
FlagDesc := True;
IndexDefs.Clear; // Limpa o indice anterior
case FlagDesc of
True: IndexDefs.Add(Indice,OldColumn.FieldName, []);
False: IndexDefs.Add(Indice,OldColumn.FieldName, [ixDescending]);
end;
IndexName := Indice;
if Assigned(OldColumn) then
OldColumn.Title.Color := grid.FixedColor;
OldColumn.Title.Color := clred;
end; //fim do with
end;


procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
 OrdenarGris(cds,Column,dbgrid1)
end;



Responder

18/07/2008

Frostlost

Legal deu certo, inclusive dei mais uma implementada no codigo separando tudo em dois procedimentos, um que ordena e outro que troca a cor.


//declaração das variáveis

var
  FrmClientes: TFrmClientes;
  Indice: string;
  FlagDesc: Boolean;

//cabeçalho dos procedimentos podendo ser público ou privado

    procedure OrdenarGris(cds:TclientDataset;OldColumn:TColumn; grid: TDBGrid);
    procedure PintarTituloGrid(grid: TDBGrid; column: TColumn);

//corpo dos procedimentos

procedure TFrmClientes.OrdenarGris(cds: TclientDataset; OldColumn: TColumn;
  grid: TDBGrid);
begin
  with cds do
  begin
    //Random para mudar o nome do indice, se colocar o indice fixo não funciona
    Indice := ´Indice´ + IntToStr(Random(9999));
    // Verifica se o campo anterior estáva em modo Ascendente ou Descendente
    FlagDesc := (IndexDefs.Count > 0) and (ixDescending in IndexDefs[0].Options);
   // Se a coluna do dbgrid força a Ascendente
    if (IndexDefs.Count > 0) and (IndexDefs[0].Fields <> OldColumn.FieldName) then
      FlagDesc := True;
    IndexDefs.Clear; // Limpa o indice anterior
    case FlagDesc of
      True: IndexDefs.Add(Indice,OldColumn.FieldName, []);
      False: IndexDefs.Add(Indice,OldColumn.FieldName, [ixDescending]);
    end;
    IndexName := Indice;
    end; //fim do with
end;

procedure TFrmClientes.PintarTituloGrid(grid: TDBGrid; column: TColumn);
var i: integer;
begin
   for i:=0 to grid.Columns.count-1 do
   begin
     grid.Columns[i].Title.Color := grid.FixedColor;
   end;
  Column.Title.color := ClRed;
end;

//chamada dos procedimentos

procedure TFrmClientes.DBGrid1TitleClick(Column: TColumn);
begin
  OrdenarGris(dmclientes.CdsListaVendasClientes,Column,dbgrid1);
  PintarTituloGrid(dbgrid1,Column);
end;



Abraços a todos e esperamos ter ajudado a todos a reaproveitar código e manipular cor do título e ordenação de grid.

Claudio Stein Junior


[quote:56740e3d4f=´Marco Salles´]
Na realidade meu código ordena a grid em ordem ascendente e descendente,


é do jeito que lhe fora passado , a ordenação é so ascendente .
Mas aqui memso no Forum há codigos para a ordenação inversa
Eu mesmo se não me falha a memória , ja participei deste tipo de
dúvida

mas ainda não consegui utilizar o campo column até porque ele é um parâmetro específico de outro procedimento que é o TitleClick do DBGrid. Ainda não consegui fazer.


mas isto ha meu ver não é nenhum problema

Voce pode ter um procedure Generica em OutroForm e no evento OnTitle
do DbGrid voce passa o parâmetro especifico

Por exemplo em uma Unit Qualquer

procedure QueOrdenaAgrid(collum:Tcoluum);
begin
//faço assim Falo Assado
end;

e no Evento OnTitleClick(Column: TColumn); da sua Grid voce Chama
esta Procedure

procedure TForm1.DBGrid1TitleClick(Column: TColumn); 
begin 
QueOrdenaAgrid(columm);
end;


voce não esta conseguindo pq esta usando Propriedades que talves não seje inerentes ao objeto

Fiz uma alteraçoes no seu codigo do jeito que funciona , alternando entre Ascendente e Descedente ... So digo uma coisa ..Tudo que voce fez da
para fazer somente com un Unico parãmetro passado : O parametro
Column: TColumn

var
Indice: string;
FlagDesc: Boolean;



procedure TForm1.OrdenarGris(cds:TclientDataset;OldColumn:TColumn; grid: TDBGrid);
begin
with cds do
begin
//Random para mudar o nome do indice, se colocar o indice fixo não funciona 
Indice := ´Indice´ + IntToStr(Random(9999));
// Verifica se o campo anterior estáva em modo Ascendente ou Descendente
FlagDesc := (IndexDefs.Count > 0) and (ixDescending in IndexDefs[0].Options);
// Se a coluna do dbgrid força a Ascendente
if (IndexDefs.Count > 0) and (IndexDefs[0].Fields <> OldColumn.FieldName) then
FlagDesc := True;
IndexDefs.Clear; // Limpa o indice anterior
case FlagDesc of
True: IndexDefs.Add(Indice,OldColumn.FieldName, []);
False: IndexDefs.Add(Indice,OldColumn.FieldName, [ixDescending]);
end;
IndexName := Indice;
if Assigned(OldColumn) then
OldColumn.Title.Color := grid.FixedColor;
OldColumn.Title.Color := clred;
end; //fim do with
end;


procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
 OrdenarGris(cds,Column,dbgrid1)
end;
[/quote:56740e3d4f]


Responder

18/07/2008

Marco Salles

Legal deu certo, inclusive dei mais uma implementada no codigo separando tudo em dois procedimentos, um que ordena e outro que troca a cor. 


beleza .... Mas lembra que eu lhe disse que :

Tudo que voce fez [b:12b3df20d9]da para fazer somente com un Unico parãmetro passado : O parametro Column: TColumn[/b:12b3df20d9]


pois é ... o codigo fica mais limpo , mais com cara de POO
e recomendável usar os parametros passados do evento..

veja bem

 Indice: string;
  FlagDesc: Boolean;

//cabeçalho dos procedimentos podendo ser público ou privado

    procedure OrdenarGris(oldColumn:Tcolumn);
    procedure PintarTituloGrid(column: TColumn);



procedure TForm1.OrdenarGris(oldColumn:Tcolumn);
begin
with (OldColumn.Field.DataSet as TclientDataSet) do
  begin
    //Random para mudar o nome do indice, se colocar o indice fixo não funciona
    Indice := ´Indice´ + IntToStr(Random(9999));
    // Verifica se o campo anterior estáva em modo Ascendente ou Descendente
    FlagDesc := (IndexDefs.Count > 0) and (ixDescending in IndexDefs[0].Options);
   // Se a coluna do dbgrid força a Ascendente
    if (IndexDefs.Count > 0) and (IndexDefs[0].Fields <> OldColumn.FieldName) then
      FlagDesc := True;
    IndexDefs.Clear; // Limpa o indice anterior
    case FlagDesc of
      True: IndexDefs.Add(Indice,OldColumn.FieldName, []);
      False: IndexDefs.Add(Indice,OldColumn.FieldName, [ixDescending]);
    end;
    IndexName := Indice;
    end; //fim do with
end;


procedure TForm1.PintarTituloGrid(column: TColumn);
var i: integer;
begin
 with (column.Grid as TdbGrid) do
   for i:=0 to Columns.count-1 do
      Columns[i].Title.Color :=FixedColor;
   Column.Title.color := ClRed;
end;


procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
OrdenarGris(Column);
  PintarTituloGrid(dbgrid1,Column);
end;



Responder

19/07/2008

Frostlost

Tudo funcionou muito bem!!!

Abraços a todos


Responder

19/07/2008

Frostlost

Uma última correção na chamada de um dos procedimentos foi passado um parâmetro a mais.

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
  OrdenarGris(Column);
  PintarTituloGrid(Column);
end;


abraços e agora tudo certo.

Claudio Stein Junior


Responder

19/07/2008

Marco Salles

Uma última correção na chamada de um dos procedimentos foi passado um parâmetro a mais. Código: procedure TForm1.DBGrid1TitleClick(Column: TColumn); begin OrdenarGris(Column); PintarTituloGrid(Column); end; abraços e agora tudo certo.


Descuido meu ... O maudito Copiar e Colar ...


Responder