Array
(
)

DbExpress campos agregados

Marco Salles
   - 19 mar 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

isto com Sql é tranquilo , mas com ousar esta propriedade que as biografias comentam .. Como fazer isto passo a passo

Quem disse que seria fácil


Marco Salles
   - 19 mar 2006

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


-
Citação:
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


Citação:
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...


Marco Salles
   - 20 mar 2006

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]

O Que eu quero é fazer o DbGrid2 ase apresentar da mesma maneira como o DbGrid3 , pelo menos e esta teoria que se passa quando se estuda CAmpos Agregados no DBEXPRESS , Ou nun é :?: :?: :?:


Emerson
   - 20 mar 2006

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


Marco Salles
   - 20 mar 2006


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


Tudo que o amigo sugeriu eu fiz


Citação:
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;





Emerson
   - 20 mar 2006

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


Marco Salles
   - 20 mar 2006


Citação:
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


Citação:
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


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


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


Martins
   - 20 mar 2006


Citação:
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.


Marco Salles
   - 20 mar 2006


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


O Objetivo foi alcançado sim Martins , apenas com um filtro

O Cara tava conseguindo isso :


Citação:
-Status----Valor--
----A-----1.253,25
----C-----6.358,22


e ele queria isso


Citação:
-Status----Valor--
----A-----1.253,25


Portanto apenas aplicou o filtro

Eu quero isso


Citação:
-Status----Valor--
----A-----1.253,25
----C-----6.358,22


e to conseguindo assim


Citação:
-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


A unica diferença é que meu Status e o Codigo Do clinte.....


Martins
   - 20 mar 2006

Ok Marco, agora a tarde, tentarei aqui tb, e veremos qual será o resultado, espero q seja positivo.

boa sorte


Emerson
   - 20 mar 2006

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,
#Código

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
ClientDataSet.Filter := ´Status = ´A´;
ClientDataSet.Filtered := True;

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. não está retornando o valor que você espera, mas está correto.

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?


Emerson
   - 20 mar 2006

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


Marco Salles
   - 21 mar 2006

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

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


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


Mas tem uma maneira de melhorar isto...

O problema de :


Citação:
´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 OnGetText do Campo Aggregado 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:


Citação:
----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


Veja que é ua pequena melhora...

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

#Código

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))]);

end;


O que eu queria com isso é entender oo que significa

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


Você ou algumem poderia interpretar essa instrução para que eu possa melhor compreese-la

Muito obrigado...


Emerson
   - 21 mar 2006

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.


Marco Salles
   - 21 mar 2006

Brigadão emerson.en.. Muito bom mesmo


Citação:
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:
[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.

Outra coisa , nção consegui testar

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

Simplesmente não compila .. Da erro de ;

Incompatibilidade de tipos : TGroupPosInds and TGroupPosInd

:?: :?: :?:

: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..


Emerson
   - 21 mar 2006

creio que seria assim:
#Código

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