DbExpress campos agregados

19/03/2006

Muito pouco o assunto sobre Aggregate dbexpress.. Fis uma busca aqui no site e so encontrei 4 postagens

Pois bem , tenho uma tabela com esses dados :

[URL=http://imageshack.us][img:b681d7df60]http://img152.imageshack.us/img152/6840/imagemdbexpressaggregate14qj.png[/img:b681d7df60][/URL]

Eu gostaria de agrupar esta tabela pelo campo Cod_Cliente e indexa-la, mas não usando um Sql com o servidor e sim usando a propriedade do ClienteDataSet que permite criar indices em cima de campo Calculado

Eu entendo como agrupamento , pelo menos em Sql algo que me retornasse somente o codigo dos clientes com o Valot total
Cod_Client Valor
.......1..........X
.......2..........Y
......3...........Z

[b:b681d7df60]isto com Sql é tranquilo , mas com ousar esta propriedade que as biografias comentam .. Como fazer isto passo a passo [/b:b681d7df60]

Quem disse que seria fácil :cry: :cry:


Marco Salles

Respostas

19/03/2006

Marco Salles

O que eu quero é sumarizar

nesse tópico

http://forum.clubedelphi.net/viewtopic.php?t=49219&highlight=agregados+dbexpress

o amigo consegui sumarizar os campos que continha ´A´ e os campos que continha ´C´ de modo que ficou


-
Status----Valor-- ----A-----1.253,25 ----C-----6.358,22


No meu caso eu quero é sumarizar do mesmo modo , so que em vez de Staus é codigo do cliente... Aparentemente é so fazer o que ele fez , so trocando os campos

Tentei fazer da seguinte forma, também com campos agregados: Criei um índice no ClientDataSet: idxStatus e alterei o GrouppingLevel de 0 para 1 Adicionei um Agregate na propriedade Agregates do ClientDataSet e alterei o GrouppingLevel para 1 também Criei um AgregateField no FieldsEditor e configurei da seguinte forma: Active: True; Expression: SUM(CHQ_VALOR); GrouppingLevel: 1; IndexName: idxStatus;


So que eu não estou conseguindo ou esta faltando alguma informação importante que o amigo nao passou;;;

Não é fácil não...


Responder Citar

20/03/2006

Marco Salles

Para ficar mais claro , segue um aplicativo com tres dbgrids..
O Do lado esquerdo e a minha tabela inicial (Que contem totodos so dados) , o do meio é o que eu estou conseguindo usando Campos Agregados com Indices , e o terceiro DbGrid é o que se consegue facilmente usando um Sql No Banco...

[URL=http://imageshack.us][img:03a5f15f22]http://img80.imageshack.us/img80/2341/imagemdbexpressaggregate22jt.png[/img:03a5f15f22][/URL]

[b:03a5f15f22]O Que eu quero é fazer o DbGrid2 ase apresentar da mesma maneira como o DbGrid3[/b:03a5f15f22] ,[color=darkblue:03a5f15f22][b:03a5f15f22] pelo menos e esta teoria que se passa quando se estuda CAmpos Agregados no DBEXPRESS , Ou nun é [/b:03a5f15f22][/color:03a5f15f22] :?: :?: :?:


Responder Citar

20/03/2006

Emerson

você fez
ClientDataSet.IndexName := idxStatus;
?
ou seja: você ativou o índice?


Responder Citar

20/03/2006

Marco Salles

você fez ClientDataSet.IndexName := idxStatus; ? ou seja: você ativou o índice?


[b:ad66efa0c6]Tudo que o amigo sugeriu eu fiz[/b:ad66efa0c6]

Adicionei um Agregate na propriedade Agregates do ClientDataSet e alterei o GrouppingLevel para 1 também Criei um AgregateField no FieldsEditor e configurei da seguinte forma: Active: True; Expression: SUM(CHQ_VALOR); GrouppingLevel: 1; IndexName: idxStatus;


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


Responder Citar

20/03/2006

Emerson

creio que a grid ´do meio´ está correta. o campo agregado pelo índice deveria retornar isso mesmo. é um campo agregado, e não agrupado.


Responder Citar

20/03/2006

Marco Salles

creio que a grid ´do meio´ está correta. o campo agregado pelo índice deveria retornar isso mesmo. é um campo agregado, e não agrupado.


bem , eu tb estive pensando sobre isso ... Mas no caso do amigo do tópico

Diz que esta sumarizando assim Porém não funcionou como esperado. Está sumarizando corretamente, mas está sumarizando agrupado por todos os Status, isto é: -Status----Valor-- ----A-----1.253,25 ----C-----6.358,22


Ele diz ainda que a tabela

pois tenho um cliente com quase 1.000.000 de cheques cadastrados no BD e, acredite, ele não quer apagar nenhum... rs


[b:a819ea1015]Bem , da para entender que ele consegui , mas o unico problema dele é que ele não queria os dados com o Status C , porem isto ja é outra conversa[/b:a819ea1015]


Responder Citar

20/03/2006

Martins

creio que a grid ´do meio´ está correta. o campo agregado pelo índice deveria retornar isso mesmo. é um campo agregado, e não agrupado.


Também penso q sim, já o terceiro grid me parece está agrupado por uma instrução SQL.

Li o tópico postado pelo Marco, parece q não deram continuidade, não se sabe se o objetivo foi mesmo alcançado.

Hj não posso nem testar nada aqui.


Responder Citar

20/03/2006

Marco Salles

Li o tópico postado pelo Marco, parece q não deram continuidade, não se sabe se o objetivo foi mesmo alcançado.


[b:878ba2c7f6]O Objetivo foi alcançado sim Martins , apenas com um filtro[/b:878ba2c7f6]

O Cara tava conseguindo isso :

-Status----Valor-- ----A-----1.253,25 ----C-----6.358,22


e ele queria isso

-Status----Valor-- ----A-----1.253,25


[b:878ba2c7f6]Portanto apenas aplicou o filtro[/b:878ba2c7f6]

Eu quero isso

-Status----Valor-- ----A-----1.253,25 ----C-----6.358,22


e to conseguindo assim

-Status----Valor-- ----A-----1.253,25 ----A-----1.253,25 ----A-----1.253,25 ----A-----1.253,25 ----C-----6.358,22 ----C-----6.358,22 ----C-----6.358,22 ----C-----6.358,22 ----C-----6.358,22


[b:878ba2c7f6]A unica diferença é que meu Status e o Codigo Do clinte.....[/b:878ba2c7f6]


Responder Citar

20/03/2006

Martins

Ok [b:204d3b1295]Marco[/b:204d3b1295], agora a tarde, tentarei aqui tb, e veremos qual será o resultado, espero q seja positivo.

boa sorte


Responder Citar

20/03/2006

Emerson

pelo que eu entendi, Marco, no tópico citado há uma ligação mestre/detalhe, onde o usuário posiciona no cliente e são exibidos os cheques emitidos por esse cliente.

então, com campos agregados, ele obtém ´o maior cheque (MAX), o menor cheque (MIN), a médias dos cheques (AVG) e a quantidade de cheques emitidos (COUNT)´ por aquele cliente.

ele exibe todos os cheques no detalhe, mas queria saber o total de cheques em aberto. para isso ele criou aquele índice. mas como o índice era por status, obviamente ele traria o valor acumulado de cada status, como no exemplo dele,
Num.Cheque  Status      Valor
1           A        1.253,25
2           C        6.358,22
3           A        1.253,25
4           C        6.358,22
5           C        6.358,22
(repete o valor por conta de ser o mesmo status e, obviamente, o campo ´valor´ não era exibido numa grade, mas sim numa área de totais, juntamente com os demais totalizadores), por isso ele disse que ´o que ocorre também é que se eu navegar pela tabela, irá me apresentar sempre o sumário do status corrente (aquele em que estou setado na tabela)´

como ele queria somente o total de cheques em aberto, a filtragem
[i:7e0a66d8e3]ClientDataSet.Filter := ´Status = ´A´;
ClientDataSet.Filtered := True;[/i:7e0a66d8e3]
resolveria em parte, porque o valor viria correto, porém não seriam listados todos os cheques.

o que foi feito:
ao posicionar no cliente, ele fez o filtro, pegou o valor do campo agregado e colocou numa variável; desfez o filtro (para que fossem exibidos todos os cheques) e colocou o valor daquela variável manualmente num label ou algo assim.

bom, creio que tenha sido isso que ocorreu com o nosso colega no outro tópico, portanto, o campo agregado que você está fazendo está correto. [b:7e0a66d8e3]não está retornando o valor que você espera, mas está correto[/b:7e0a66d8e3].

e funcionou no caso dele por serem registros da tabela detalhe, e não da tabela mestre.

creio que a melhor forma de você fazer o que você deseja seja mesmo via sql.

deu pra entender?


Responder Citar

20/03/2006

Emerson

na verdade o fato de ser mestre/detalhe não influencia no resultado, mas sim a aplicação do campo.


Responder Citar

21/03/2006

Marco Salles

emerson , agradeço a sua participação , sempre muito bem vinda.

confesso que dou por encerrado este tópico , e como voce mesmo disse :

não está retornando o valor que você espera, mas está correto.


Mas tem uma maneira de melhorar isto...

O problema de :

´o que ocorre também é que se eu navegar pela tabela, irá me apresentar sempre o sumário do status corrente (aquele em que estou setado na tabela)´


com a utilização do evento [b:c1d81dce79]OnGetText do Campo Aggregado [/b:c1d81dce79]criado , pude melorar o visual .. E ao inves de cada coluna postar o Resultado da soma ,da para postar em uma unica coluna da cada cliente
este resultado < No Caso a Soma >

Tipo isso:

----A----- ----A----- ----A----- ----A-----1.253,25 ******Posto nessa coluna do Grid o Resultado ----C----- ----C----- ----C----- ----C----- ----C-----6.358,22 *****Posto nessa coluna o Resultado da Grid


[b:c1d81dce79]Veja que é ua pequena melhora... [/b:c1d81dce79]

:idea: :idea:
O código usado para tal proeza é :

procedure TForm1.ClientDataSet2SomaGetText(Sender: TField;
  var Text: String; DisplayText: Boolean);
begin
if gblast in ClientDataSet2.GetGroupState(1) then
  text:=format(´O Cliente de Código ¬s comprou ¬s  ´+CurrencyString,
         [ClientDataSet2Cod_Cliente.AsString,
         FormatCurr(´0.00´,strtocurr(sender.AsString))&93;);

end;


O que eu queria com isso é entender oo que significa

[b:c1d81dce79]if gblast in ClientDataSet2.GetGroupState(1) then[/b:c1d81dce79] , dentro desse contexto, porque esse [b:c1d81dce79]If é o coração da instrução [/b:c1d81dce79], e o resto é so [b:c1d81dce79]formatação[/b:c1d81dce79]


[b:c1d81dce79]Você ou algumem poderia interpretar essa instrução para que eu possa melhor compreese-la[/b:c1d81dce79]

Muito obrigado...


Responder Citar

21/03/2006

Emerson

GetGroupState(1) indica onde o registro atual se encontra dentro de um grupo específico de registros. no caso, o agrupamento cujo nível é 1 (aquele nível que você informou na criação do seu índice).

os valores de retorno possíveis são:
[gbMiddle] - O registro atual não é o primeiro e nem o último do grupo
[gbFirst] - O registro atual é o primeiro do grupo, no qual há no mínimo dois registros.
[gbLast] - O registro atual é o último registro do grupo, no qual há no mínimo dois registros.
[gbFirst,gbLast] - O registro atual é o único registro do grupo.


Responder Citar

21/03/2006

Marco Salles

Brigadão emerson.en.. Muito bom mesmo

GetGroupState(1) indica onde o registro atual se encontra dentro de um grupo específico de registros. no caso, o agrupamento cujo nível é 1 (aquele nível que você informou na criação do seu índice). os valores de retorno possíveis são: [gbMiddle] - O registro atual não é o primeiro e nem o último do grupo [gbFirst] - O registro atual é o primeiro do grupo, no qual há no mínimo dois registros. [gbLast] - O registro atual é o último registro do grupo, no qual há no mínimo dois registros. [gbFirst,gbLast] - O registro atual é o único registro do grupo.


Bigadão emerson...é isso mesmo .. So não to entendendo porque quando se tem um registro apenas por grupo a instrução
if gblast in ClientDataSet2.GetGroupState(1) then
retorna true

Pelo que voce diz deveria nesse caso retornar False , mas nos teste retorna True

Não seria assim: :?: :?: :?:

os valores de retorno possíveis são:
[b:70e8cbd396][gbMiddle] - O registro atual não é o primeiro e nem o último do grupo
[gbFirst] - O registro atual sera sempre o primeiro do grupo
[gbLast] - O registro atual sera o último registro do grupo [gbFirst,gbLast] - O registro atual é o único registro do grupo.[/b:70e8cbd396]

Outra coisa , nção consegui testar

if ClientDataSet1.GetGroupState(1) in [gbFirst,gbLast] then

Simplesmente não compila .. Da erro de ;

Incompatibilidade de tipos : [b:70e8cbd396]TGroupPosInds and TGroupPosInd[/b:70e8cbd396]

:?: :?: :?:

:idea: :idea: :idea: :idea:

Claro que para testar eu fiz assim :

if (gbFirst in ClientDataSet1.GetGroupState(1))and
(gbLast in ClientDataSet1.GetGroupState(1)) then

Mas teria outro jeito..


Responder Citar

21/03/2006

Emerson

creio que seria assim:
if ClientDataSet1.GetGroupState(1) = [gbFirst&93; then
  // 1o. registro (nesse caso há mais de um registro)
  {faça algo}
else  
if ClientDataSet1.GetGroupState(1) = &91;gbMiddle&93; then
  // registro no meio (não é o primeiro nem o último)
  {faça algo}
else  
if ClientDataSet1.GetGroupState(1) = &91;gbLast&93; then
  // último registro (nesse caso há mais de um registro)
  {faça algo}
else  
if ClientDataSet1.GetGroupState(1) = &91;gbFirst,gbLast&93; then
  // ÚNICO registro
  {faça algo}



Responder Citar