Artigo: 210604 - Última revisão: quinta-feira, 15 de Março de 2007 - Revisão: 5.3

Funções para calcular e apresentar valores de data/hora no Access

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Moderado: requer conhecimentos básicos sobre macros, codificação e interoperabilidade.

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Dado que um valor de date/hora é guardado como um número de precisão dupla, poderá receber resultados com formatação incorrecta quando tentar manipular os valores de date/hora de uma expressão. Este artigo demonstra como criar expressões e personalizar funções para apresentar datas específicas e para calcular intervalos de tempo.

A Microsoft fornece exemplos de programação apenas a título informativo, sem garantia expressa ou implícita, incluindo, sem limitação, as garantias implícitas de comercialização e/ou adequação a um fim específico. Este artigo pressupõe que o utilizador conhece a linguagem de programação apresentada e as ferramentas utilizadas para criar e depurar procedimentos. Os técnicos de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento, mas não modificarão estes exemplos para proporcionarem funcionalidades adicionais nem criarão procedimentos adaptados às necessidades específicas do utilizador.

Mais Informação

Apresentar datas específicas

Para apresentar datas específicas, pode utilizar a função DateSerial() para manipular as partes relativas ao dia, mês e ano de uma data. Por exemplo, pode utilizar as seguintes expressões na propriedade OrigemDoControlo de uma caixa de texto ou na janela Immediate para devolver datas específicas:
  • O mês actual:
    DateSerial(Year(Date()), Month(Date()), 1)
  • O mês seguinte:
    DateSerial(Year(Date()), Month(Date()) + 1, 1)
  • O último dia do mês actual:
    DateSerial(Year(Date()), Month(Date()) + 1, 0)
  • O último dia do mês seguinte:
    DateSerial(Year(Date()), Month(Date()) + 2, 0)
  • O primeiro dia do mês anterior:
    DateSerial(Year(Date()), Month(Date())-1,1)
  • O último dia do mês anterior:
    DateSerial(Year(Date()), Month(Date()),0)
  • O primeiro dia do trimestre actual:
    DateSerial(Year(Date()), Int((Month(Date()) - 1) / 3) * 3 + 1, 1)
  • O último dia do trimestre actual:
    DateSerial(Year(Date()), Int((Month(Date()) - 1) / 3) * 3 + 4, 0)
  • O primeiro dia da semana actual (pressupondo domingo = dia 1):
    Date() - WeekDay(Date()) + 1
  • O último dia da semana actual:
    Date() - WeekDay(Date()) + 7
  • O primeiro dia da semana actual (utilizando definições da caixa de diálogo Opções):
    Date() - WeekDay(Date(), 0) + 1
  • O último dia da semana actual:
    Date() - WeekDay(Date(), 0) + 7
Para obter mais informações sobre como calcular o ano fiscal e o mês fiscal, clique no número de artigo que se segue para visualizar o artigo na base de dados de conhecimento da Microsoft (KB, Microsoft Knowledge Base):
210249  (http://support.microsoft.com/kb/210249/ ) How to get the fiscal year or month of a particular date in Access 2000
ATENÇÃO: se seguir os passos descritos neste exemplo, modificará a base de dados de exemplo Adamastor.mdb. Convém fazer uma cópia de segurança do ficheiro Adamastor.mdb e seguir estes passos numa cópia da base de dados.

Calcular intervalos de tempo

Dado que um valor de horas é guardado como uma fracção de um dia de 24 horas, poderá receber resultados com formatação incorrecta quando tentar adicionar, subtrair, multiplicar ou dividir dados de horas superiores a 24 horas.

Por exemplo, se tentar chegar ao número de horas decorridas entre duas datas subtraindo os valores no Visual Basic, poderá receber um número incorrecto. Para demonstrar isto, escreva o seguinte código na janela Immediate e note que este devolve um valor de 00:00:00 horas em vez do valor correcto de 53:00 horas:
   StartDate=#6/1/93 8:00AM#
   EndDate=#6/3/93 1:00PM#
   ?Format(EndDate-StartDate,"hh:mm")

Para resolver problemas de formatação provocados por valores de horas superiores a 24 horas, pode utilizar as funções Int() e CSng() no Visual Basic para separar um valor de horas calculado em variáveis diferentes para dias, horas, minutos e segundos. Por exemplo, pode incluir o seguinte excerto de código numa função personalizada para criar variáveis de tempo independentes:
 '-------------------------------------------------------------------
 ' This sample code separates a time interval into seven variables for
 ' the following values: days, hours, minutes, seconds, total time in
 ' hours, total time in minutes, and total time in seconds.
 '
 ' The interval argument is flexible; it can be a single value, an
 ' expression, or a field reference.
 '-------------------------------------------------------------------

 Dim totalhours As Long, totalminutes As Long, totalseconds As Long
 Dim days As Long, hours As Long, minutes As Long, seconds As Long
 Dim interval As Variant

 days = Int(CSng(interval))
 totalhours = Int(CSng(interval * 24))
 totalminutes = Int(CSng(interval * 1440))
 totalseconds = Int(CSng(interval * 86400))
 hours = totalhours Mod 24
 minutes = totalminutes Mod 60
 seconds = totalseconds Mod 60

Pode utilizar as variáveis horastotais, minutostotais e segundostotais para apresentar um valor de horas como uma única unidade de tempo. As variáveis dias, horas, minutos e segundos permitem dividir um valor de horas em unidades de tempo. Para apresentar valores de horas em diferentes formatos, pode concatenar estas variáveis como demonstrado nos seguintes exemplos de funções:
  • A função ObterDiasDecorridos() calcula o tempo decorrido entre dois valores de data/hora e apresenta o resultado em dias.
  • A função ObterTempoDecorrido() calcula o tempo decorrido entre valores de horas e apresenta o resultado em dias, horas, minutos e segundos.
  • A função ObterTotalDeCartãoDePonto() soma um campo de valores de horas de uma tabela e apresenta o total em horas e minutos.

Exemplo de função ObterDiasDecorridos()

Para criar a função ObterDiasDecorridos(), siga estes passos:
  1. Abra a base de dados de exemplo Adamastor.mdb.
  2. Crie um módulo e escreva a seguinte linha na secção Declarations, caso ainda não exista:
     Option Explicit
  3. Escreva a seguinte função:
     Function GetElapsedDays (interval)
        Dim days As Long
    
        days = Int(CSng(interval))
        GetElapsedDays = days & " Days "
     End Function
  4. Para testar esta função, crie uma nova consulta com base na tabela Encomendas.
  5. Na grelha QBE, adicione os seguintes campos.
    <Formatting Type="FixedText"><![CDATA[
        Campo: DataDoEnvio
        Mostrar: Verdadeiro
    
        Campo: DataDaEncomenda
        Mostrar: Verdadeiro
    
        Campo: TempoDecorrido: ObterDiasDecorridos([DataDoEnvio]-[DataDaEncomenda])
        Mostrar: Verdadeiro
  6. Execute a consulta. Note que a coluna TempoDecorrido apresenta o número de dias entre o campo DataDoEnvio e o campo DataDaEncomenda de cada registo da tabela Encomendas.

Exemplo de função ObterTempoDecorrido()

Para criar a função ObterTempoDecorrido(), siga estes passos:
  1. Crie uma nova tabela com a seguinte estrutura e guarde-a como RegistoDeTempo.
        Tabela: RegistoDeTempo
        ---------------------------
        Nome do campo: HoraDeInício
        Tipo de dados: Data/hora
        Formato: Data geral
    
        Nome do campo: HoraDeFim
        Tipo de dados: Data/hora
        Formato: Data geral
  2. Visualize a tabela RegistoDeTempo na vista de folha de dados, introduza os seguintes três registos e feche a tabela:
    <Formatting Type="FixedText"><![CDATA[
        HoraDeInício           	HoraDeFim
        --------------------------------------------
        10/05/95 4:57:00            15/05/95 2:38:00
        11/05/95 10:17:31           24/05/95 6:05:00
        18/05/95 9:16:43            19/05/95 5:03:00
  3. Crie um módulo e escreva a seguinte linha na secção Declarations:
     Option Explicit
  4. Introduza a a seguinte função:
     Function GetElapsedTime(interval)
    
     Dim totalhours As Long, totalminutes As Long, totalseconds As _
         Long
     Dim days As Long, hours As Long, Minutes As Long, Seconds As Long
    
     days = Int(CSng(interval))
     totalhours = Int(CSng(interval * 24))
     totalminutes = Int(CSng(interval * 1440))
     totalseconds = Int(CSng(interval * 86400))
     hours = totalhours Mod 24
     Minutes = totalminutes Mod 60
     Seconds = totalseconds Mod 60
    
     GetElapsedTime = days & " Days " & hours & " Hours " & Minutes & _
     " Minutes " & Seconds & " Seconds "
    
     End Function

    NOTA: a função ObterTempoDecorrido requer a passagem de uma data e uma hora.
  5. Para testar esta função, crie um novo relatório com base na tabela RegistoDeTempo utilizando o Assistente de relatórios automáticos.
  6. Visualize o relatório na vista de estrutura.
  7. Adicione uma caixa de texto não ligada à secção de detalhes da tabela RegistoDeTempo e defina as respectivas propriedades da seguinte forma:
    <Formatting Type="FixedText"><![CDATA[
        Caixa de texto
        ---------------
        Nome: TempoDecorrido
        OrigemDoControlo: =ObterTempoDecorrido([HoraDeFim]-[HoraDeInício])
        Largura: 7,5 cm
  8. Pré-visualize o relatório. Note que cada registo apresenta o tempo decorrido total em dias, horas, minutos e segundos.

Exemplo de função ObterTotalDeCartãoDePonto()

Para criar a função ObterTotalDeCartãoDePonto(), siga estes passos:

NOTA: o código de exemplo constante deste artigo utiliza Microsoft Data Access Objects. Para que este código seja executado correctamente, tem de referenciar a biblioteca Microsoft DAO 3.6 Object Library. Para o fazer, clique em References no menu Tools do editor do Visual Basic e certifique-se de que a caixa de verificação de Microsoft DAO 3.6 Object Library está seleccionada.

  1. Crie uma nova tabela com a seguinte estrutura e guarde-a como CartãoDePonto.
        Tabela: CartãoDePonto
        ----------------------------
        Nome do campo: Horas diárias
        Tipo de dados: Data/hora
        Formato: Hora abreviada
  2. Visualize a tabela CartãoDePonto na vista de folha de dados, introduza os seguintes quatro registos e feche a tabela:
    <Formatting Type="FixedText"><![CDATA[
        8:15
        7:37
        8:12
        8:03
  3. Crie um módulo e escreva a seguinte linha na secção Declarations, caso ainda não exista:
     Option Explicit
  4. Escreva a seguinte função:
     Function GetTimeCardTotal ()
    
     Dim db As DAO.Database, rs As DAO.Recordset
     Dim totalhours As Long, totalminutes As Long
     Dim days As Long, hours As Long, minutes As Long
     Dim interval As Variant, j As Integer
    
     Set db = dbengine.workspaces(0).databases(0)
     Set rs = db.OpenRecordset("timecard")
     interval = #12:00:00 AM#
        While Not rs.EOF
           interval = interval + rs![Daily hours]
           rs.MoveNext
        Wend
     totalhours = Int(CSng(interval * 24))
     totalminutes = Int(CSng(interval * 1440))
     hours = totalhours Mod 24
     minutes = totalminutes Mod 60
    
     GetTimeCardTotal = totalhours & " hours and " & minutes & " minutes"
    
     End Function
  5. Para testar esta função, escreva a seguinte linha na janela Immediate e prima ENTER:
     ?GetTimeCardTotal()

    Note que a janela Immediate apresenta 32 horas e 7 minutos.

Referências

Para mais informações sobre como calcular valores de data/hora, clique no número de artigo que se segue para visualizar o artigo na base de dados de conhecimento da Microsoft (KB, Microsoft Knowledge Base):
210276  (http://support.microsoft.com/kb/210276/ ) Storing, calculating, and comparing Date/Time data

A informação contida neste artigo aplica-se a:
  • Microsoft Office Access 2007
  • Microsoft Office Access 2003
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
Palavras-chave: 
kbhowto kbprogramming KB210604