Fórum Selecionar cor do DbGrid Por Grupo #290596

03/08/2005

0

Faco uma pesquisa onde ordeno uma consulta Pelo codigo de operação ..
esse codigo é un numeto inteiro e podemos ter vários registros com um mesmo codigo

Exemplo de resultado apos a consulta
descricao operacao
blablabla 10
blablabla 10
blablabla 9
blablabla 8
blablabla 8
blablabla 8
blablabla 8
blablabla 7
blablabla 7
blablabla 6
etc....
O que eu gostaria de fazer é agrupar este resultado em cores no dbgrid...
Assim o dbgrid ficara com aspecto Zebrado ...so que em enves do teste
order(RebNo) Tradicional gostaria de fazer um teste levando em consideração o Valor da operacao

Alguma idéia .. Obrigado...


Marco Salles

Marco Salles

Responder

Posts

03/08/2005

Marco Salles

Faço uma pesquisa onde ordeno uma consulta Pelo codigo de operação ..
esse codigo é un numero inteiro e podemos ter vários registros com um mesmo codigo

Exemplo de resultado apos a consulta ::::

descrição operação
blablabla 10
blablabla 10
blablabla 9
blablabla 8
blablabla 8
blablabla 8
blablabla 8
blablabla 7
blablabla 7
blablabla 6
etc....
O que eu gostaria de fazer , é agrupar este resultado em cores no dbgrid...

[b:86934de4d3]Assim o dbgrid ficara com aspecto Zebrado ...so que em envês do teste
order(RebNo) Tradicional gostaria de fazer um teste levando em consideração o Valor da operacao ..
Assim por exemplo , todos os registros de opreação 10 Ficassem com a mesma cor , depois vem os registros com Operação 9 que ficaria de cor diferente , depois os registros de operação 8 que ficaria com a mesma cor dos registros de operação 10, e assim sucessivamente...[/b:86934de4d3]

Alguma idéia .. Obrigado...


Responder

Gostei + 0

03/08/2005

Marco Salles

Poxa gente , libera esse código aí.... Trava não :cry: :cry:

Eu libero tantas coisas aqui no forum :cry: :cry: :cry: :cry: :cry:


Responder

Gostei + 0

04/08/2005

Massuda

Ao invés de testar o RecNo, teste o valor do campo ´operacao´.

No momento do teste, dentro do OnDrawColumnCell do DBGrid, a tabela/query estará posicionada no registro que está sendo desenhado, por isso basta testar diretamente o valor do campo que contem o seu critério de qual cor usar.


Responder

Gostei + 0

04/08/2005

Marco Salles

Ao invés de testar o RecNo, teste o valor do campo ´operacao´. No momento do teste, dentro do OnDrawColumnCell do DBGrid, a tabela/query estará posicionada no registro que está sendo desenhado, por isso basta testar diretamente o valor do campo que contem o seu critério de qual cor usar.


[b:3b0b00ca57]ai que esta o problema massuda .. eu não tenho este valor [/b:3b0b00ca57].. ele pode ser qualquer coisa 1,2,3,4,5,6,7,8,9,1000,1005 etc

podem existir uma quantidade de rgistro com a operação igual ao valor 1 , outras quantidades de registros com a operação igual a 2 , e assim segue....

O que eu quero e que toda vez que mudar o valor da operação , o dbgrid mude de cor..
[b:3b0b00ca57]Atenção , não é um dbgrid com várias cores , e sim um dbGrid com duas cores que ficam se alternando entre os diversos valores de
que o campo Operação adquire[/b:3b0b00ca57]
Obrigado...


Responder

Gostei + 0

05/08/2005

Marco Salles

:cry: :cry: :cry: :cry:


Responder

Gostei + 0

05/08/2005

Massuda

[quote:dd3e8edade=´Marco Salles´]...não é um dbgrid com várias cores , e sim um dbGrid com duas cores que ficam se alternando entre os diversos valores de que o campo Operação adquire...[/quote:dd3e8edade]Seria preciso mais algumas informações... sua query está ordenada e agrupada pelo campo operação? O valor do campo operação é sequencial ou é saltado?

Imaginando que o valor de campo é sequencial e que a query está agrupada (via GROUP BY operacao) e ordenada, poderia fazer algo bem simples...
if Odd(seuDataSet.FieldByName(´operacao´).AsInteger) then
  {usa uma cor}
else
  {usa outra cor};
Se o campo operação não for sequencial, acho que teria que usar uma query auxiliar (similar a que você está usando para preencher o dbgrid) para obter os valores distintos do campo operação e usar esse resultado para determinar qual cor utilizar.


Responder

Gostei + 0

05/08/2005

Marco Salles

Beleza massuda ...

Seria preciso mais algumas informações...


com o maior prazer...

sua query está ordenada e agrupada pelo campo operação?


ela esta ordenada em forma decrescente.. Mas não esta agrupada

O valor do campo operação é sequencial ou é saltado?


o valor da operação é saltado... Ele pode ser todo par como também pode ser todo Impar Como pode ter para ou Impar

Se o campo operação não for sequencial, acho que teria que usar uma query auxiliar (similar a que você está usando para preencher o dbgrid) para obter os valores distintos do campo operação e usar esse resultado para determinar qual cor utilizar


Mas acho que a dificuldade de atingir este objetivo com uma query auxiliar é a mesma dificuldade de atingir este objetivo com a própria query , visto que esta query é editável :( :( :(


Responder

Gostei + 0

05/08/2005

Massuda

[quote:0f85225863=´Marco Salles´]Mas acho que a dificuldade de atingir este objetivo com uma query auxiliar é a mesma dificuldade de atingir este objetivo com a própria query...[/quote:0f85225863]Não entendi qual a dificuldade... essa query auxiliar não seria visível. Por exemplo, imagine que ela retorne...

{ 1, 2, 4, 123, 12023, 230490 }

...quando um item tem operacao=1 uso a cor A, operacao=2 uso a cor B, operacao=4 uso a cor A, etc, onde a cor é escolhida com base na posição da operacao dentro da query auxiliar.

[quote:0f85225863=´Marco Salles´]...visto que esta query é editável[/quote:0f85225863]Nesse caso, cada vez que o valor de operacao for alterado será preciso recalcular as cores usadas no dbgrid, já que o usuário poderia usar um valor de operacao que não estava em uso anteriormente ou deixar de usar um valor que estava em uso.


Responder

Gostei + 0

05/08/2005

Marco Salles

quando um item tem operacao=1 uso a cor A, operacao=2 uso a cor B, operacao=4 uso a cor A, etc,


Mas com eu vou comparar algo que eu não sei em termos de projeto :?: :?:

Em termos de projeto eu não sei se vai existir um campo operação com o valor igual a 1 Por exemplo

Na realidade eiu esto seguindo uma linha de raciocíneo assim

Para Registros com mesmo valor de operação , a cor é uma , quando se muda o valor da operação , se alterna a cor

eu to conseguindo algo parecido com o codigo abaixo , mas da dando uma imperfeição na hora de desenhar a Grid :cry: :cry: :cry:
Não esta colorindo ela de maneira Perfeita :( :( :(

procedure TFormMovimentoCheques.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); var NovoCodigooperacao:String; begin NovoCodigoOperacao:=Query1.FieldByName(´Operacao´).AsString; if NovoCodigoOperacao=CodigoAtualOperacao then DBGrid1.Canvas.Brush.Color:=clInfoBk else begin if (PrimeiraVez)and(NovoCodigoOperacao<>CodigoAtualOperacao) Then begin DBGrid1.Canvas.Brush.Color:=clInactiveCaptionText; CodigoAtualOperacao:=NovoCodigoOperacao; PrimeiraVez:=False; end else if (NovoCodigoOperacao<>CodigoAtualOperacao) Then begin DBGrid1.Canvas.Brush.Color:=clInfoBk; PrimeiraVez:=True; CodigoAtualOperacao:=NovoCodigoOperacao; end; end; DBGrid1.Canvas.FillRect(Rect); DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.Top,Column.Field.AsString); end;


Ta aparecendo assim



[URL=http://imageshack.us][img:80fd5b774f]http://img138.imageshack.us/img138/2930/imagemmassuda15dq.jpg[/img:80fd5b774f][/URL]

quando o correto seria assim :::

[URL=http://imageshack.us][img:80fd5b774f]http://img138.imageshack.us/img138/9079/imagemmassuda21jc.jpg[/img:80fd5b774f][/URL]


Responder

Gostei + 0

05/08/2005

Massuda

[quote:2fc7b50edf=´Marco Salles´]Mas com eu vou comparar algo que eu não sei em termos de projeto?[/quote:2fc7b50edf]No exemplo que dei, as cores foram atribuídas com base na posição do valor da operacao dentro da query auxiliar; essa query auxiliar lista os valores distintos do campo operacao respeitando os mesmos critérios da query que você está usando para popular o dbgrid. Por exemplo, se o grid está sendo populado com esta query...
SELECT * FROM suaTabela WHERE Data >= :DataInicial AND Data <= :DataFinal
...a query auxiliar seria...
SELECT DISTINCT operacao FROM suaTabela WHERE Data >= :DataInicial AND Data <= :DataFinal
(Sei que não é legal usar DISTINCT, mas tem jeitos mais complicados de escrever esta query sem usar DISTINCT, mas não manjo o suficiente de SQL para fazer isso).

Note que não estou assumindo que um determinado valor de operacao existe... estou assumindo que todos os valores de operacao que interessam estão na query auxiliar.

Infelizmente, cada vez que os valores forem alterados pelo usuário, você tem que executar novamente a query auxiliar e refazer o desenho do grid.


Responder

Gostei + 0

05/08/2005

Marco Salles

Muito obrigadissimo massuda pela sua disposição e coloboração , sempre atento e conhecedor do assunto.. Mas antes de ler o seu Ultimo post eu acho que consegui fazer o que pretendia , apenas com lógiga... Ficou assim

procedure TFormMovimentoCheques.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
 NovoCodigooperacao:String;
begin
  NovoCodigoOperacao:=Query1.FieldByName(´Operacao´).AsString;
if (NovoCodigoOperacao=CodigoAtualOperacao)and(PrimeiraVez) then
  begin
     DBGrid1.Canvas.Brush.Color:=clInfoBk;
     PrimeiraVez:=True;
  end
else
  begin
      if PrimeiraVez Then
        begin
          DBGrid1.Canvas.Brush.Color:=clInactiveCaptionText;
          CodigoAtualOperacao:=NovoCodigoOperacao;
          PrimeiraVez:=False;
        end
      else
         if (NovoCodigoOperacao<>CodigoAtualOperacao) Then
            begin
              DBGrid1.Canvas.Brush.Color:=clInfoBk;
              CodigoAtualOperacao:=NovoCodigoOperacao;
              PrimeiraVez:=True;
           end
         else
           begin
             DBGrid1.Canvas.Brush.Color:=clInactiveCaptionText;
             CodigoAtualOperacao:=NovoCodigoOperacao;
             PrimeiraVez:=False;
          end;
    end;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.Top,Column.Field.AsString);
end;


[b:62348e9003]eu ainda não testei o codigo exaustivamente , mas talvez venha a ter problema com a inicialização das Variáveis CodigoAtualOperacao e PrimeiraVez[/b:62348e9003]
Estou fazendo assim : Antes da consulta eu atribuo os valores de
CodigoAtualOperacao:=´0´; 
PrimeiraVez:=True;


[b:62348e9003]Mas no final do processo estas variáveis podem ser quisquer valores e alem do mais , quando o desenho da grade começar novamente , posso ter alguma cintilação...[/b:62348e9003]

Eu não sei se voce esta me entendendo , mas suponha que no final do processo a variável primeiraVez seje diferente do valor Inicial , e o processo OnDrawColumnCell é reiniciado , Logo o Grid pode assumir Cores alternadas.. Quero dizer , ora algums registros possuem a cor A , ora esses mesmo registros irão possuir a cor B.. Entende :?: :?:

Então eu queria saber o seguinte , apos a grid ser toda desenhada , no final eu nomamente atribuir estes valores para essas variáveis.
Tipo isso:
Fim do desenho
CodigoAtualOperacao:=´0´; 
PrimeiraVez:=True;



Existe evento para isto No Delphi massuda ??? Ou alguma idéia de quando este evento OnDrawColumnCell Termine

Obrigado....

P:S este evento OnDrawColumnCell eu ate hoje não consegue depura-lo.. então fica dificil saber como as coisa estão se comportando.. Parece que ele depos de começado não termina nunca :cry: :cry: :cry:

Obrigadão :P :P :P :P


Responder

Gostei + 0

05/08/2005

Massuda

[quote:2ca6582698=´Marco Salles´]...este evento OnDrawColumnCell eu ate hoje não consegue depura-lo.. então fica dificil saber como as coisa estão se comportando.. Parece que ele depos de começado não termina nunca...[/quote:2ca6582698]O evento é gerado sempre que o DBGrid precisa ser desenhado.

Se você por um breakpoint no seu código de desenho no OnDrawColumnCell, quando chega no breakpoint, você vai para a IDE do Delphi; quando você dá F9 na IDE para voltar a executar, seu programa precisa ser exibido novamente, gerando novamente o evento OnDrawColumnCell. Por isso ele parece ´não ter fim´.

Não parei para olhar atentamente seu código, mas tem um detalhe que você precisa prestar atenção: o evento OnDrawCell é gerado de modo que não é possível assumir em qual ordem o evento será gerado. Por exemplo, se você cobrir parcialmente o DBGrid com (por exemplo) a Calculadora do Windows e mover a Calculadora de baixo para cima sobre o DBGrid, o evento poderá ser gerado do final para o início do seu dataset (ou pode ser gerado apenas uma vez, do início para o fim do dataset... depende das configurações do Windows).


Responder

Gostei + 0

05/08/2005

Marco Salles

Não parei para olhar atentamente seu código, mas tem um detalhe que você precisa prestar atenção: o evento OnDrawCell é gerado de modo que não é possível assumir em qual ordem o evento será gerado. Por exemplo, se você cobrir parcialmente o DBGrid com (por exemplo) a Calculadora do Windows e mover a Calculadora de baixo para cima sobre o DBGrid, o evento poderá ser gerado do final para o início do seu dataset (ou pode ser gerado apenas uma vez, do início para o fim do dataset... depende das configurações do Windows).


É de fato ele fica ´manchado´ apos mover a calculadora sobre a Grid..
Como se pode notar pela figura abaixo

[URL=http://imageshack.us][img:1302b6db12]http://img326.imageshack.us/img326/159/imagemmassuda32yg.jpg[/img:1302b6db12][/URL]

Mas acho que este problema , como voce descreveu não é um Problema so Meu..A crdito que muitas pessoas que desenvolvem código usando este evento irá ocorrer este problema

Para resolver este inconveniente Pensei tive esta idéia :

Quando a aplicação recebe o foco novamente eu dou o seguinte comando
DbGrid1.Visible:=FALSE;
DbGrid1.Visible:=True


[b:1302b6db12]Fiz isto num botão e deu certo , mas acho que o local ideal seria , toda a vez que a aplicação recebe-se o foco... [/b:1302b6db12]

Mas qual o evento que eu poderia colocar este código amigo massuda :?: :?: :?: Tentei usar um componente TApplication mas não soube detectar o evento adequado :cry: :cry: :cry:

Uma outra coisa que talvez voce pude-sse me ajudar é o seguinte.. O Campo valor e Currency e sem usar o evento DBGrid1DrawColumnCell ele é desenhado na grid com a unidade monetaria e Formatado.. Mas com ose pode notar , no desenho acima ele aparece sem o valor da unidade monetária e totalemte desformata-do...
[color=darkblue:1302b6db12][b:1302b6db12](59,85 ; 80,8 ; 246,6 ; 227,48 ; 42 ; 39 )[/b:1302b6db12][/color:1302b6db12]

Como corrigir isto massuda :?: :?: :?: :?:


Responder

Gostei + 0

05/08/2005

Massuda

[quote:b04ff25ef5=´Marco Salles´]... O Campo valor e Currency e sem usar o evento DBGrid1DrawColumnCell ele é desenhado na grid com a unidade monetaria e Formatado.. Mas com ose pode notar , no desenho acima ele aparece sem o valor da unidade monetária e totalemte desformata-do...[/quote:b04ff25ef5]Veja meu post [url=http://forum.clubedelphi.net/viewtopic.php?t=65685]neste tópico[/url].


Responder

Gostei + 0

05/08/2005

Marco Salles

Realmente massuda , voce te razão ... As própias biogravias dos livors do delphi recomenda o uso do método DefaultDrawDataCell.. e alem disso recomenda-se configurar a propriedade defaultDrawing em false.. [b:96b6be94cf]Diz que se deixar a Propriedade defaultDrawing em true , a grade apresentará a saida padrão antes que o método seje chamado[/b:96b6be94cf]

[b:96b6be94cf]Porém na prática eu nunca observei diferenças entre deixar esta propriedade defaultDrawing em false ou deixa-la em True [/b:96b6be94cf]:cry:
[color=darkblue:96b6be94cf][b:96b6be94cf]Voce sabe alguma coisa a respeito disso[/b:96b6be94cf][/color:96b6be94cf] :?: :?: :?:

Alem disso , com aqui no forum todos usam o código ,
DBGrid1.Canvas.FillRect(Rect); DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.Top,Column.Field.AsString);

e eu não tinha ná prática observado nada que contraria-se o seu uso , eu ja tinha descartado a chamada a este método

Nos primeiros tópicos no inicio de minha participação aqui no forum eu sugeri o uso dessa chamada.. como se pode verificar no tópico abaixo
datado de Sex Fev 27, 2004
http://forum.devmedia.com.br/viewtopic.php?t=37160&highlight=defaultdrawdatacell&sid=42047c6d85c9e8992abdb2e638013433
[b:96b6be94cf]Mas como eu disse , por falta de algum efeito prático eu descartei a utilização dessa chamada.. [/b:96b6be94cf]

Mas voltando a atenção para o outro problema:::::

Massuda por acaso voce não tem nenhuma idéia para eu ficar livre desse efeito manchado que se obtem quando se movimenta a calculadora em cima da Grid por exemplo... Nen minha idéia inicial de esconder e apresentar a Grid quando a applicação vier para frente voce acha viável

Obrigado pela força..


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar