Horas Extras - Cálculo de intervalo e soma superior a 24 horas
Nota importante: para ter acesso aos vídeos e arquivos exemplos deste site, adquira um dos planos apresentados abaixo. Você pode comprar em até 5x no Cartão de Crédito, através do Paypal.
Veja como comprar e saiba mais sobre o material oferecido, clicando aqui.
Você sabia que os valores de Data e Hora são tratados como números, pelo VBA? Como exemplo, usaremos aqui a função Cdbl() que irá converter o valor que está no formato data/hora, para o valor no formato número, correspondente.
Cdbl(#15/05/2012 19:45:20#) :::> retorna 41044,8231481481
No exemplo acima, a parte inteira (41044) corresponde à data 15/05/2012 e a fração (0,8231481481) corresponde às horas 19:45:20.
Se convertermos somente a hora, teremos:
Cdbl(#19:45:20#) :::> retorna 0,8231481481
Se desejarmos converter o número para o formato de hora, basta usarmos a função Cdate()
Cdate(0.8231481481) :::> retorna 19:45:20
Curiosidade: Se aparte inteira do número corresponde a data, qual seria então a data para o valor 1 ? Vamos descobrir ?
Cdate(1) :::> retorna 31/12/1899
Agora, observe que o resultado da subtração, que está no formato de hora, retorna o resultado no formato numérico.
#19:45:00# - #18:50:00# :::> Retorna 0,03819444444444
Para converter o resultado no formato de hora, basta então, usarmos a função Cdate().
Cdate(#19:45:00# - #18:50:00#) :::> Retorna 00:50:00
Com a função Cdate() fica mais fácil o cálculo das horas extras diárias!
Cdate(Hora Término - Hora Início) :::> retorna o total das horas extras do dia
Só que precisamos realizar um ajuste, caso a hora do término, ultrapasse a meia noite! Isto é fácil de saber, pois a hora do término terá um valor menor que a hora de início (hora Término < hora Início).
Exemplo: o trabalho teve início às 23 horas e términou às 2 horas da madrugada do dia seguinte. Logo, concluímos que foram realizadas 3 horas extras. Contudo, a função Cdate(), retorna 21 horas extras.
Cdate(#02:00:00# - #23:00:00#) :::> retorna 21:00:00
Isto acontece porque o Access está considerando que o trabalho teve início às 2 horas da madrugada e terminou às 23 horas do mesmo dia. Temos então que informar ao Access que a hora 2 da madrugada, na verdade, corresponde ao dia seguinte. Para isso, basta acrescentarmos 1 dia à hora do término de trabalho.
Cdate((1 + #02:00:00#) - #23:00:00#) :::> retorna 03:00:00
A função para o cálculo das horas extras do dia ficou assim:
Faça o login aqui para ter acesso ao código.
Soma maior que 24 horas
Veja na função abaixo, o resultado quando a soma de dois horários ultrapassarem a 24 horas.
cdate(#13:00:00# + #18:00:00#) :::> retorna 31/12/1899 07:00:00
- Resultado estranho, não é mesmo?! Não é tão estranho assim! Observe o cálculo:
13 + 18 = 31 horas. Como ultrapassou a 24 horas, o Access adicionou 1 dia à data e subtraiu as 24 horas no cálculo referente às horas, ficando assim:
1 dia (31 horas - 24horas) :::> resultado 31/12/1899 07:00:00
Ora, como temos agora o valor 1 na parte da data, o Access irá retornar a data correspondente, que é Cdate(1) :::> 31/12/1899. Vamos tirar a prova real, usando a função Cdbl() ?
cdbl(#31/12/1899 07:00:00#) :::> resultado 1,29166666666667
A parte inteira 1, corresponde a data 31/12/1899
Bom, independente da data informada na função Cdate(), nunca teremos a soma de horas, superior a 24 horas.
Exemplo, definindo uma data:
Cdate(#15/05/2012 13:00:00# + #18:00:00#) :::> retorna 16/05/2012 07:00:00
Uma solução simples para exibir horas acima de 24 é a de transformar todos os horários para Segundos, e assim realizar a soma dos valores, que estarão no formato numérico do tipo inteiro longo. Para você entender melhor, vamos lidar com os valores.
Vamos supor que um funcionário já tenha 19:45:20 de Horas Extras e tenhamos que somar mais 07:30:10 horas.
Faça o login aqui para ter acesso ao código.
Viu como ficou fácil somar tudo, usando os Segundos, pois fica mais simples trabalhar com números do tipo inteiro longo.
Agora é só pegar o resultado, que esta em Segundos, e transformá-lo no padrão hh:mm:ss com a função format(). Estude como foi feito, na função fncSomaHora(), que está no quadro logo abaixo.
Como extrair os valores do formato hh:mm:ss ?
Isso se torna muito simples se você conhecer a função split(). Com esta função você consegue extrair valores de uma seqüência qualquer, desde que possamos definir um caractere como referência de separação . Por exemplo: Temos uma lista de frutas, separadas por virgula.
Tomate,Laranja,Banana
A virgula então será a referência para a função poder separar os itens
fruta = split("Tomate,Laranja,Banana",",")
Para extrair os valores, basta agora indicar a posição do elemento na seqüencia, que começa do zero
fruta(0) :::> retorna Tomate
fruta(1) :::> retorna Laranja
fruta(2) :::> retorna Banana
Usaremos então a função split(), no formato de hora, indicando os dois pontos (:) como o separador dos elementos.
h = split("19:45:20",":")
h(0) :::> retorna 19
h(1) :::> retorna 45
h(2) :::> retorna 20
Veja a função completa que realiza a soma das horas, com resultados que podem exceder às 24 horas:
Faça o login aqui para ter acesso ao código.
Arquivo Exemplo:
Montei um arquivo exemplo para você poder estudar na prática, as funções aqui propostas.
Veja o formulário de lançamento das horas diárias trabalhadas. Observe que o campo Total de Horas, exibe o valor superior a 24 horas trabalhadas, o que corresponde ao total de horas extras.
Agora, veja no relatório abaixo, os valores resultantes para cada um dos funcionários. Todos os cálculos foram realizados no próprio relatório.
Veja a programação utilizada no relatório acima e as funções aplicadas.
Faça o login aqui para ter acesso ao código.
Para você aprender a programar nos relatórios é FUNDAMENTAL que assista esta minha vídeo-aula.
Para você se aprofundar no cálculo de horas extras.
É importante estar por dentro da legislação trabalhista para realizar o cálculo correto das horas extras. Se a sua empresa é sindicalizada, faça uma consulta ao sindicato sobre estes cálculos, porque poderá haver alteração nas regras, dependendo da categoria.
Para você conhecer mais a fundo, como realizar os cálculos, proponho que baixe o aplicativo Telemax, que ofereço aqui no site, gratuitamente. Observe a imagem abaixo:
Detalhe: Neste projeto do Telemax, converti as horas para minutos, já que não considerei os segundos.
Bom estudo!
Os dez artigos mais visitados
MontaRibbons v.7.0 - Assistente completo para criar ribbons no Access
Vídeo - Controle personalizado de Acesso de Usuários
Vídeo - Aprenda sobre filtragens
Vídeo - Segurança máxima, usando o OPEN
Uma ajuda para quem está começando um negócio ou um projeto
Integrando o Access com Servidor MySQL - Introdução
Desabilitando a faixa(ribbon) superior do Access
Vídeo - Programação de relatórios - Parte 1
Como carregar o seu menu sem que ele vá para lista de suplementos
Adquira o kit UsandoAccess e aprenda em alta velocidade
36 comentários Thiago Genuino 17/06/2023 05:45:27 Bom dia! Avelino, poderia criar um modulo que converta a diferença entre duas datas para segundos por gentileza. Já quebrei a cabeça aqui. Ex: 09/11/2022 11:30:00 e 11/11/2022 10:30 = 1692000 Pois pretendo montar um controle de tempo de equipamento parado, e isso pode ultrapassa as 24 horas. Desde já agrade Nixon 03/03/2023 13:10:02 Avelino boa noite!!!! Utilizei o código do exemplo: Set rs = CurrentDb.OpenRecordset("select * from conPBancoHora WHERE bhorafunc=" & Form_frmPControleBancoHora.txtFunc) Passando a clausula funcionário. Funcionou perfeitamente, no entanto precisava passar mais dados. Ou seja além de informar o funcionário, precisava passar a clausula data inicial e data final para o campo data da consulta. Explicando melhor, preciso que retorne o resultado da consulta por funcionário e entre período informado. nsm2000@gmail.com santos 08/09/2022 15:14:24 Podia mandar-me via e-mail lmrgsantos@gmail.com Uma aplicação simples só para contabilizar as horas 20 funcionários que depois de registados, carregava só as horas de entrada e de saída e no fim imprimia relatório,~ obrigado Guilherme 28/03/2022 16:17:37 Obrigado por mais essa excelente contribuição, Avelino! ANTONIO.TEIXEIRA 17/12/2021 18:43:51 GOSTARIA DE MANUAL DO ACCESS Avelino Sampaio 12/12/2021 13:34:56 Wsenna, Acho que ficaria bem fácil se usarmos a função dateDiff() para retornar com os minutos do intervalo. Exemplo, usando as datas que vc informou: datediff("n",#12/10/2012 10:00#,#12/14/2012 05:30#) :::> 5490 minutos Basta agora converter os minutos para o formato Horas minutos: format(int(5490/60),"00") & ":" & format((5490 - (int(5490/60)*60)),"00") :::> 91:30 Sucesso! WSenna 12/12/2021 10:10:22 Amigão, como sabes, há anos me interessei pela soma de horários que ultrapassassem as 24h imposta pelo Access e hoje utilizo muito o seu modelo com satisfação. Agora, sem querer abusar, tenho um novo problema: Como faria para demonstrar em horas totais um período com início em 10/12/2012 10:00 e témino em 14/12/2012 05:30 ? danilo 05/08/2021 15:31:15 a propriedade dos meus campos não estão como hora abreviada, com essa propriedade, funciona quando tiro não, mas preciso de informar horas superiores a 23:59 no caso 040:00 ou 060:00 como proceder. danilo 05/08/2021 14:45:40 Poderia dar uma força nas mudanças que tentei fazer no seu código? Public Function fncSomaHora(horaAcumulada1 As Variant, horaAcumulada2 As Variant, horaAcumulada3 As Variant, horaAcumulada4 As Variant, horaAcumulada5 As Variant) As Variant Dim ha1, ha2, ha3, ha4, ha5, sha1, sha2, sha3, sha4, sha5 As Integer, sht As Long Dim TotalSegundos As Long, Horas As Long, Minutos As Long, Segundos As Long 'Passa as horas para as Matrizes, aonde podemos extrair os valores pela referência ":" ha1 = Split(IIf(horaAcumulada1 = 0, "00:00", horaAcumulada1), ":") ha2 = Split(IIf(horaAcumulada2 = 0, "00:00", horaAcumulada2), ":") ha3 = Split(IIf(horaAcumulada3 = 0, "00:00", horaAcumulada3), ":") ha4 = Split(IIf(horaAcumulada4 = 0, "00:00", horaAcumulada4), ":") ha5 = Split(IIf(horaAcumulada5 = 0, "00:00", horaAcumulada5), ":") sha1 = 3600 * ha1(0) + 60 * ha1(1) + ha1(2) 'hora acumulada em segundos sha2 = 3600 * ha2(0) + 60 * ha2(0) '+ ha2(2) 'hora acumulada em segundos sha3 = 3600 * ha3(0) + 60 * ha3(0) '+ ha3(2) 'hora acumulada em segundos sha4 = 3600 * ha4(0) + 60 * ha4(0) '+ ha4(2) 'hora acumulada em segundos sha5 = 3600 * ha4(0) + 60 * ha4(0) '+ ha4(2) 'hora acumulada em segundos 'Total de horas extras acumuladas, em segundos TotalSegundos = sha1 + sha2 + sha3 + sha4 'Remonta a hora no formato hh:mm:ss Horas = Int(TotalSegundos / 3600) Minutos = Int((TotalSegundos - (Horas * 3600)) / 60) Segundos = TotalSegundos - (Horas * 3600) - (Minutos * 60) fncSomaHora = Format(Horas, "##000") & ":" & Format(Minutos, "00") & ":" & Format(Segundos, "00") End Function Avelino Sampaio 05/08/2021 07:09:30 Danilo, minha sugestão é que transforme para minutos (se não usar os segundo), faça a soma e depois então retorne para o formato 180:30:00 :::> 180 * 60 + 30 = 10830 130:30:00 :::> 130 * 60 + 30 = 7830 10830 + 7830 = 18660 minutos no total Transformando: format(int(18660/60),"00") & ":" & format((18660 - (int(18660/60)*60)),"00") :::> 311:00 Sucesso! Danilo 04/08/2021 10:13:55 Bom dia, surgiu a necessidade de realizar o cálculo de horas no access, até aqui tudo ok, só que o campo devera conter um número a mais na casa da centena, pois se trata de horas de cursos extensos como pós graduação ex: 180:30:00 130:30:00 ___________ 311:00:00 - pois os trinta minutos são somados contando mais uma hora. como proceder para a realização do cálculo. Avelino Sampaio 01/08/2021 09:12:43 Eduardo, tente assim: DoCmd.RunSQL "INSERT INTO CD_AGENDA ( DataAG, HoraAG ) SELECT #" & format(cDATA,"mm/dd/yyyy") & "# AS Expr1, CD_HORARIOS.Horario FROM CD_HORARIOS WHERE CD_HORARIOS.DiaSemana= " & cDIA & ";" No aguardo EDUARDO ROCHA 31/07/2021 16:32:19 Professor: Estou tentando executar: DoCmd.RunSQL "INSERT INTO CD_AGENDA ( DataAG, HoraAG ) SELECT #" & cDATA & "# AS Expr1, CD_HORARIOS.Horario FROM CD_HORARIOS WHERE CD_HORARIOS.DiaSemana= " & cDIA & ";" mas a variável cDATA embora seja do tipo DATE com o valor 03/07/2012 é gravado 07/03/2012 Pode me me ajudar ? Obrigada. HORA para soma com 3 digitos 13/06/2021 15:10:07 Tenho um problema onde já tenho campos com horas com três digitos ex: 120:30:15 como somar isso? Welson Zeferino 07/05/2021 15:05:35 Muito bom, obrigado! Edson 05/05/2021 14:27:00 Avelino. Voce faz a diferença! Parabens. Avelino Sampaio 05/05/2021 04:28:55 Muito obrigado pelos comentários! MARCIO MELO - RJ 04/05/2021 20:38:58 Rsrs para nossaaaa Alegriaaa, muito bom esse estudo, tudo que precisamos, informações detalhadas de funcionamento das funções, super inovador e criativo. Avelino vc tem uma técnica admirável, sempre me atualizo conforme seus artigos, meus projetos vão ficando cada vez mais profissional, muito obrigado por compartilhar mais esse tabu, desvendada as funções kkk forte abraço... Sou mais Brasil! Roni 04/05/2021 16:25:16 Olá Avelino! Estava com um projeto em mente mas não sabia como começar, pois, tratava-se de calcular horas extras... ...agora já posso dar início ao projeto. Não conhecia essas funções. Obrigado por compartilhar mas este conhecimento. Fernando C 04/05/2021 14:12:52 Olá Avelino, Sempre com ótimo conteúdo, parabéns! Djassy 04/05/2021 12:17:55 Muito bom... Eu gostei.... Marcelo David 04/05/2021 12:01:57 Muito bom, parabéns!!! Marcos 04/05/2021 12:01:52 Muito bom !! Paulo Sergio 04/05/2021 11:40:46 Interessante... é que o Excel tem o formato [h] para acumular mais de 24 horas... No Access, precisamos desses ajustes... ótimo! Wagner Senna 04/05/2021 11:33:45 Grande Avelino. Muito bom este tutorial, linguagem simples e objetiva, não há quem não aprenda. Parabens. Abraços, WSenna Dietrich Rocha 04/05/2021 11:18:35 Como o amigo ali de cima citou: "Show de Bola" Filipe Bacelar 04/05/2021 10:45:04 Mais um excelente artigo. Parabéns amigo Flavio Nascimento 04/05/2021 09:54:02 Parabéns mestre dos mestre.. Show de Bola. Avelino Sampaio 02/05/2021 03:43:00 Saulo, vá na seção BLOG aqui do site e acesse o artigo "Uma ajuda para quem está começando um negócio ou um projeto". Lá tem um controle de hoas extras prontinho para vc. Bom estudo! Saulo Zanella 30/04/2021 17:52:55 Opa, só pra retificar o post anterior, R$16,00 cada hora normal e R$18,00 cada hora extra (das 22h as 5h). Obrigado desde já! Saulo Zanella 30/04/2021 17:51:07 Olá Avelino, tudo bem? Estou fazendo um banco de dados e estou quebrando a cabeça pra uma coisa que é muito fácil pra vc, é claro rss... Estou lançando as horas trabalhadas com hora inicial e hora final e preciso que o sistema me retorne as horas extras no valor de R$16,00/hora no horário normal e R$18,00 das 22h as 5h da manhã. Não estou sabendo como fazer esse cálculo dessas horas diferenciadas. Ah se pudesse me ajudar eu ficaria tão feliz! Márcio Melo - RJ 30/04/2021 11:38:45 Qual seria o melhor método para entrarmos com um horário maior que 24h já que no campo de Data/Hora isso não é possível. Hoje eu faço um artício de um campo desacobrado com mascara 000:00 ou 0000:00 e após atualizar fiz uma função que informa o número correspondente, depois passo esse número para horas com outra função, mostrando em outro campo desacoplado. Estou passando uma planilha de esforço de horas do excell para o access e me debati nessa questão de ter um campo que possa entrar e exibir com horas maior que 24h no excell isso é possível no formato = [hh]:mm. Pensei em trabalhar com campo texto. Sou mais Brasil! Diego 29/01/2021 12:15:34 Olá Avelino, estou tentando utilizar seu código para conseguir visualizar as horas que passam de 24 horas no meu banco. A diferença é que não realizo soma, eu extraio os dados de um Excel onde já possui a soma das horas. Mas quando faço um select e crio uma tabela no access, as horas que excedem 24 horas, começam a aparecer com data na frente. Tentei adaptar seu código pra trazer só a hora acumulada, mas como o campo é Data/Hora está retornando o erro "Tipos Incompatíveis". Segue como estou tentando utilizar o código: Public Function fncSomaHora(horaAcumulada As Variant) As Variant Dim ha, sha As Long Dim TotalSegundos As Long, Horas As Long, Minutos As Long, Segundos As Long 'Passa as horas para as Matrizes, aonde podemos extrair os valores pela referência ":" ha = Split(IIf(horaAcumulada = 0, "00:00:00", horaAcumulada), ":") sha = 3600 * ha(0) + 60 * ha(1) + ha(2) 'hora acumulada em segundos 'Total de horas extras acumuladas, em segundos TotalSegundos = sha 'Remonta a hora no formato hh:mm:ss Horas = Int(TotalSegundos / 3600) Minutos = Int((TotalSegundos - (Horas * 3600)) / 60) Segundos = TotalSegundos - (Horas * 3600) - (Minutos * 60) fncSomaHora = Format(Horas, "##00") & ":" & Format(Minutos, "00") & ":" & Format(Segundos, "00") End Function Poderia me dizer onde pode estar o problema? Obrigado! Marcelo dos Santos 26/01/2021 00:34:59 Boa Noite Avelino Estou com duas tabela com seguinte exemplo tabela1 e tabela2 Com a seguinte estrutura: ID Cod Descrição Valor 1 01 Exemplo1 20,00 2 01 Exemplo1 15,00 3 01 Exemplo1 15,00 4 02 Exemplo2 25,00 5 02 Exemplo2 35,00 6 02 Exemplo2 5,00 eu preciso somar esses dados Agrupados pelo COD e gravar o resultado em uma terceira tabela para que possa gerar o relatorio que me atende Atencipadamente Agradeço pela força Avelino Sampaio 12/02/2020 01:26:17 Cleber, abra um tópico lá no nosso fórum e forneça mais detalhes e em qual função dá o erro. http://www.redeaccess.com.br Aguardamos Cleber Caetano 11/02/2020 13:31:42 Public Function fncIntervalo(Entrada1 As Date, Saida1 As Date, Entrada2 As Date, Saida2 As Date) As Date fncIntervalo = Cdata(IIf(Saida2 < Entrada1, Saida2 + 1, Saida2) - (Entrada2 - Saida1) - Entrada1) End Function Fiz a modificações para ter 4 horarios Entrada ao serviço, Saida para almoço, Retorno do Almoço e Saida. Porem esta me dando um erro de sub ou funcão não definida |