Se você já precisou somar horas no Report Viewer, muito provavelmente você teve que fazer alguma gambiarra. Se tentarmos somar campos do tipo DateTime ou TimeStamp, o resultado não será o esperado. Dessa forma, temos que fazer esse tipo de somatório de horas no Report Viewer “na mão“.
No vídeo de hoje eu mostro para você o jeito menos “gambiarrado” de se implementar esse tipo de somatório, onde convertemos toda a informação em segundos, somamos e depois formatamos o resultado adequadamente. Veja só o resultado no vídeo de hoje:
Como armazenamos informações de horas?
Quando temos que armazenar informações relacionadas a horas, eu consigo visualizar três alternativas:
– Campos DateTime: considerando somente a parte das horas, minutos e segundos, ignorando o conteúdo da data em si
– Campos TimeSpan: na minha opinião é a melhor estrutura para armazenar um intervalo de tempo, afinal, é justamente para isso que essa classe foi criada
– Campos decimais: o horário é convertido em horas decimais, onde, por exemplo, o valor 2.5 corresponderia a duas horas e meia
Tendo como base essa realidade, eu preparei um relatório extremamente simples com informações de horas nesses três formatos:
A estratégia de sumarização de horas
Para fazermos o somatório de horas no Report Viewer, nós seguiremos uma estratégia muito simples. Primeiro nós converteremos as informações de horas em segundos. Depois, nós adicionaremos esse total de segundos em um DateTime com base “zero horas“. Com isso nós teremos a quantidade de horas, minutos e segundos, porém, nós perderemos a informação de dias, caso o total passe de 24 horas.
O cálculo da quantidade de dias pode ser feito dividindo a mesma somatória de segundos que utilizamos no passo anterior pela quantidade de segundos presentes em um dia (86400 segundos). Se pegarmos a parte inteira dessa divisão, teremos a quantidade de dias!
Somando horas decimais
Vamos começar com o somatório de horas decimais. Nesse caso, como temos que converter a informação para segundos, nós multiplicaremos tudo por 3600 (que é a quantidade de segundos presentes em uma hora). Em seguida, nós adicionamos esse total de segundos em um DateTime “zero hora” através da função “DateAdd“. Por fim, nós calculamos a quantidade de dias dividindo a somatória de segundos por 86400 e considerando somente a parte inteira através da função “Floor“.
Veja só como é que fica a expressão:
=Floor(Sum(Fields!HorasDecimal.Value) * 3600 / 86400) & ":" & Format(DateAdd("s", Sum(Fields!HorasDecimal.Value * 3600), "00:00:00"), "HH:mm:ss")
Somando TimeStamps
Para somarmos horas que estejam armazenadas em TimeStamps, o processo é um pouco mais simples, uma vez que nós temos a propriedade “TotalSeconds” que já retorna a quantidade total de segundos do TimeStamp. Apesar dessa propriedade não aparecer no IntelliSense, ela está disponível em tempo de execução e conseguimos utilizá-la sem problema algum. Nesse caso, a expressão fica assim:
=Floor(Sum(Fields!HorasTimeSpan.Value.TotalSeconds) / 86400) & ":" & Format(DateAdd("s", Sum(Fields!HorasTimeSpan.Value.TotalSeconds), "00:00:00"), "HH:mm:ss")
Somando DateTimes
O somatório de informações do tipo DateTime é muito parecido com o somatório de TimeStamps, uma vez que a classe DateTime possui a propriedade “TimeOfDay” que é justamente um TimeStamp representando a parte das horas, minutos e segundos do DateTime:
=Floor(Sum(Fields!HorasDateTime.Value.TimeOfDay.TotalSeconds) / 86400) & ":" & Format(DateAdd("s", Sum(Fields!HorasDateTime.Value.TimeOfDay.TotalSeconds), "00:00:00"), "HH:mm:ss")
E com isso temos o somatório de horas no Report Viewer tanto com DateTime quanto TimeStamp e valores decimais:
Baixe o projeto de exemplo
Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.
Concluindo
Apesar do Report Viewer não ter suporte nativo ao somatório de horas, você viu neste vídeo que esse tipo de sumarização é totalmente implementável utilizando algumas conversões e cálculos. Se convertermos todas as informações para segundos e depois adicionarmos o total em um DateTime “zero hora“, nós teremos o resultado esperado, independentemente da estrutura de dados que você estiver utilizando para armazenar as horas, seja DateTime, TimeStamp ou valores decimais.
E você, já precisou somar horas no Report Viewer? Como é que você acabou saindo dessa situação? Você utilizou exatamente essas fórmulas ou acabou fazendo de alguma outra maneira diferente? Conte-nos mais detalhes na caixa de comentários logo abaixo!
Até a próxima!
André Lima
The post Somatório de horas no Report Viewer appeared first on André Alves de Lima.