SOMA REGISTROS NO CRYSTAL/VB6

ALANTB 15/07/2015 09:41:55
#448858
Galera, estou engatinhando com esse relatório (vb6/access2007,cr8.5), mas não posso deixar de lado. Em posts anteriores com a ajuda dos colegas consegui fazer a seleção por datas, entretanto tenho um campo (PONTOS) que deve me retornar um número que representa o somatório dos valores relativos aos registros correspondentes do intervalo de datas. Está assim:
Exemplo: no form de relatório: período de 01/01/2012 até 01/01/2014, Classe = 1 (classe A) retorna isto:
Matricula Nome Idade Classe dataClasse pontos Classificação
----------------------------------------------------------------------------------------------------------
32751 Alan 43 A 01/10/2012 1400 1
32751 Alan 43 A 01/10/2012 1365 2
32751 Alan 43 A 01/10/2012 1365 3
Ele me retorna os 3 valores, um cada linha, sendo que preciso que retorne o total da pontuação em uma linha só, pois são mais de 900 funcionários no cadastro. Se cada um for exibido em mais de uma linha resultará em um relatório muito extenso. O certo seria assim:
Matricula Nome Idade Classe dataClasse pontos Classificação
----------------------------------------------------------------------------------------------------------
32751 Alan 43 A 01/10/2012 4130 1

Detalhe: para esse form de relatório tenho dois relatórios montados no crystal. Um não tem o campo data na Consulta do Access e puxa os dados de todos exibindo a soma de pontos de cada funcionário em uma linha como necessito. Mas, no outro na Consulta tem o campo data (dataAno) para que seja feita a seleção por data, mas não faz a soma referente a seleção e carrega o relatório em mais de uma linha conforme mostrado acima. Na consulta os campos estão “Agrupados” e o campo Pontos está “Soma”. Já tentei inclusive formatar o campo Pontos no crystal com a propriedade SUM, mas continua retornando em mais de uma linha. O que mais posso verificar para corrigir isso???

Alan


ALVAROVB2009 15/07/2015 09:49:59
#448860
Resposta escolhida
No seu select terá que usar o group by, com isso vc conseguiram fazer uma soma desses pontos para exibir
Algo assim
SELECT matricula, SUM(pontos) FROM suatabela GROUP BY matricula
ALANTB 15/07/2015 11:29:27
#448866
ALVAROVB2009, a consulta SQL que esta [Ô]linqada[Ô] com o relatório já faz isso que está na query acima. Veja a exibição do MODO SQL da consulta:

SELECT tbFormulario.codMatricula, tbFunc.Nome, tbFunc.dataNasc, tbContrato.codClasse, tbClasse.desClasse, tbContrato.dataClasse, Sum(tbFormulario.nroPontosTotal) AS nroPontosTotal, tbFormulario.dataAno
FROM tbFunc INNER JOIN ((tbClasse INNER JOIN tbContrato ON tbClasse.codClasse = tbContrato.codClasse) INNER JOIN tbFormulario ON tbContrato.codMatricula = tbFormulario.codMatricula) ON tbFunc.codFunc = tbContrato.codFunc
GROUP BY tbFormulario.codMatricula, tbFunc.Nome, tbFunc.dataNasc, tbContrato.codClasse, tbClasse.desClasse, tbContrato.dataClasse, tbFormulario.dataAno
ORDER BY Sum(tbFormulario.nroPontosTotal) DESC;

E essa é a Sub que chama o relatório:

Sub ImprimeClasse()

Dim dtini, dtfim As Date
dtini = Format(txtDe.Text, [Ô]dd, MM, yyyy[Ô])
dtfim = Format(txtAte.Text, [Ô]dd, MM, yyyy[Ô])

CrystalReport1.Reset
CrystalReport1.DataFiles(0) = App.Path & [Ô]\promove.mdb[Ô]
CrystalReport1.ReportFileName = App.Path & [Ô]ptClassificacaoData.rpt[Ô]

CrystalReport1.SelectionFormula = [Ô]({ConsultaTotalCriterios.dataAno} >= datevalue([Ô] & Year(dtini) & [Ô], [Ô] & Month(dtini) & [Ô], [Ô] & Day(dtini) & [Ô])) And [Ô] & _
[Ô]({ConsultaTotalCriterios.dataAno} <= datevalue([Ô] & Year(dtfim) & [Ô], [Ô] & Month(dtfim) & [Ô], [Ô] & Day(dtfim) & [Ô])) And [Ô] & _
[Ô]({ConsultaTotalCriterios.codClasse}= [Ô] & txtCodClasse.Text & [Ô])[Ô]

CrystalReport1.DiscardSavedData = False
CrystalReport1.WindowState = crptMaximized
CrystalReport1.WindowShowZoomCtl = True
CrystalReport1.DiscardSavedData = False
CrystalReport1.WindowShowNavigationCtls = True
CrystalReport1.WindowShowCloseBtn = True
CrystalReport1.WindowShowPrintSetupBtn = True
CrystalReport1.WindowShowPrintBtn = True
CrystalReport1.Action = 1

End Sub
ALVAROVB2009 15/07/2015 12:02:15
#448870
Blz aparentemente a query esta certa

Vamos fazer igual ao Jack Estripador, por partes

Primeiro essa query traz o resultado esperado no banco???
Se caso ela trazer, o problema esta interpretação no Crystal, para resolver, não deixe o crystal fazer a conta, já mande para ele carregando os dados prontos através do recordset
Segue o exemplo
CrystalReport1t.DiscardSavedData = true [ô]tem que descartar a query do crystal
CrystalReport1.Database.SetDataSource Rs [ô]carrega o crystal com o recordset preenchido, no meu caso o RS é meu recordset carregado com os dados

Dessa forma deve carregar os dados perfeitamente
ALANTB 15/07/2015 13:59:15
#448886
Pois é ALVAROVB2009, ao executar a Consulta direto no Access realmente ela retorna os registros de forma detalhada, ou seja, um funcionário aparece mais de uma vez com o seus registros salvos no bd. Como exemplifiquei acima. Achei que o crystal ajeitasse isso e exibisse um por um os funcionários com a soma de pontos do intervalo de datas digitado. O que tá me trancando é exatamente o campo data (dataAno). Quando esta incluido na consulta do Access exibe todos os dados sem soma, mas quando não está carrega os funcionários com a soma, mas não consigo fazer a seleção por período de data, que é o que está me interessando mais no momento...Se isso for interpretação entre o Access e o Crystal, como contornar isso? Tem como fazer essa seleção totalmente via código. De acordo com os dados acima como ficaria??

ALAN
ALVAROVB2009 15/07/2015 15:21:38
#448891
Seu problema é essa exibição da data, pois pelo que entendi ela tem data diferente, sendo assim a soma é feita por data

Já que vc precisa de uma somatória geral por nome, é necessária mesma a exibição dessa data??

Porque senão for o problema fica resolvido, coloca o periodo de busca dentro do where e como falei, carrega td no recordset e transporta para o Crystal

SELECT tbFormulario.codMatricula, tbFunc.Nome, tbFunc.dataNasc, tbContrato.codClasse, tbClasse.desClasse, tbContrato.dataClasse, Sum(tbFormulario.nroPontosTotal) AS nroPontosTotal, tbFormulario.dataAno
FROM tbFunc INNER JOIN ((tbClasse INNER JOIN tbContrato ON tbClasse.codClasse = tbContrato.codClasse) INNER JOIN tbFormulario ON tbContrato.codMatricula = tbFormulario.codMatricula) ON tbFunc.codFunc = tbContrato.codFunc

Where dataAno => #[Ô] & format(datainicial,[Ô]MM/YYYY[Ô]) & [Ô]# and datano <= #[Ô] & format(datafinal,[Ô]MM/YYYY[Ô]) & [Ô]# [Ô]

GROUP BY tbFormulario.codMatricula, tbFunc.Nome, tbFunc.dataNasc, tbContrato.codClasse, tbClasse.desClasse, tbContrato.dataClasse, tbFormulario.dataAno
ORDER BY Sum(tbFormulario.nroPontosTotal) DESC

ficaria algo assim

Só mais uma pergunta, o seu campo dataAno é do tipo data né ??
ALANTB 15/07/2015 17:10:53
#448893
ALVAROVB2009, o campo dataAno é do tipo DATA/HORA. Mais um esclarecimento. No meu sistema tem um form (frmFormulario) com um SSTab que exibe os campos de um formulário que tem de ser preenchido em vários setores para avaliação de funcionários para posterior promoção de classe de serviço de acordo com a pontuação de cada classe. De cada classe os 10 mais pontuados são promovidos de classe antes do tempo. Na tabela onde é armazenado as informações dos formulários (tbFormulario), um funcionário pode ter vários formulários gravados que representam a sua avaliação anual: 2012,2013,2014,2015,2016,...E serão gravados assim sucessivamente. Mas para separar os 10 de cada classe, seleciona-se 3 formulários, ou seja, imprimir todos funcionários da classe A, por exemplo, de 01/01/2012 ate 01/01/2014. O relatório tem os campos conforme informei na criação do post, o campo CLASSIFICAÇÃO determina a ordem de pontuação e o campo PONTOS deve buscar a pontuação total dos 3 formulários somados de acordo com a seleção de datas.
ALVAROVB2009 15/07/2015 18:19:15
#448895
Alan realmente nesse caso para somar fica dificil, porque dando uma olhada melhor no seu exemplo e no estamos conversando, estou vendo vc tem também um campo classificação e o Group by ele soma até achar um campo com valor diferente

Com a query que estavamos falando, se no exemplo que vc postou, senão tivesse o campo classificação, ele iria fazer a soma corretamente, pois todos os dados são iguais, até o campo classificação

Uma idéia que eu até ja usei foi criar uma tabela temporária, onde vc iria abastecer ela com os dados que vc quer e vincula o crystal nessa tabela, depois da impressão vc deleta os dados
Lembrando que de tempos em tempos teria que compactar o bando pois ele iria ficar grande, porque o Access tem um problema de apenas crescer, mesmo apagando a tabela, só que isso seria de menos, poria colocar uma rotina no fechamento do sistema para fazer essa compactação
ALANTB 16/07/2015 07:58:34
#448913
ALVAROVB2009, Classificação não é um campo no BD. Essa classificação no relatório é um [Ô]SPECIAL FIELD[Ô] inserido direto no relatório. De acordo com a quantidade de registros que puxa do BD ele vai numerando a partir do 1 para que seja fácil visualizar os 10 primeiros. Sendo assim, continuo quebrando a cabeça para resolver essa....!!!
ALVAROVB2009 16/07/2015 11:09:56
#448925
Alan já que precisa exibir uma data , qual seria essa data?

Porque assim, o group esta somando os pontos por data, e como vc quer uma somatória geral e apresentar apenas 1 data, usando a idéia que eu dei a você de criar uma tabela temporária, vc iria guardar nessa tabela os dados do usuário, a somatória e a data desejada, para depois exibir ela no Crystal
ALANTB 16/07/2015 14:06:26
#448929
ALVAROVB2009, a data em questão se refere ao período de seleção para emissão do relatório. Ela poderá ser exibida no cabeçalho do relatório para informar que os dados exibidos no relatório se referem à aquele período de tempo. Digamos que em 2016 a comissão responsável pelas promoções irá emitir um relatório para promover os 10 funcionários com maior pontuação em cada classe (A,B,C,D e E). Esses funcionários tem formulários com avaliações de vários anos : 2011,2012,2013,2014,2010,...Como a promoção está sendo feita em 2016 a comissão precisa da soma da pontuação dos 3 últimos formulários cadastrados (sempre será dos 3 últimos anos), no caso 2013,2014 e 2015. Portanto é soma desses 3 que deverá aparecer somado para cada funcionário, para posterior promoção de classe.
Em último caso ,se, houver uma maneira de usar a data apenas para fazer a seleção e omitindo-a, mas de uma forma que carregue os dados e pontuações corretamente, dá para ir usando até achar outra maneira melhor...
Página 1 de 2 [12 registro(s)]
Tópico encerrado , respostas não são mais permitidas