Apresentar datas específicas
Existem aqui no forum excelentes exemplos sobre datas e horas. Encontrei este na internet e achei-o interessante e didático.
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
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:
4. Function GetElapsedDays (interval)
5. Dim days As Long
6.
7. days = Int(CSng(interval))
8. GetElapsedDays = days & " Days "
End Function
9. Para testar esta função, crie uma nova consulta com base na tabela Encomendas.
10. Na grelha QBE, adicione os seguintes campos.
11.12. Campo: DataDoEnvio
13. Mostrar: Verdadeiro
14.
15. Campo: DataDaEncomenda
16. Mostrar: Verdadeiro
17.
18. Campo: TempoDecorrido: ObterDiasDecorridos([DataDoEnvio]-[DataDaEncomenda])
Mostrar: Verdadeiro
19. 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.
2. Tabela: RegistoDeTempo
3. ---------------------------
4. Nome do campo: HoraDeInício
5. Tipo de dados: Data/hora
6. Formato: Data geral
7.
8. Nome do campo: HoraDeFim
9. Tipo de dados: Data/hora
Formato: Data geral
10. Visualize a tabela RegistoDeTempo na vista de folha de dados, introduza os seguintes três registos e feche a tabela:
11.12. HoraDeInício HoraDeFim
13. --------------------------------------------
14. 10/05/95 4:57:00 15/05/95 2:38:00
15. 11/05/95 10:17:31 24/05/95 6:05:00
18/05/95 9:16:43 19/05/95 5:03:00
16. Crie um módulo e escreva a seguinte linha na secção Declarations:
Option Explicit
17. Introduza a a seguinte função:
18. Function GetElapsedTime(interval)
19.
20. Dim totalhours As Long, totalminutes As Long, totalseconds As _
21. Long
22. Dim days As Long, hours As Long, Minutes As Long, Seconds As Long
23.
24. days = Int(CSng(interval))
25. totalhours = Int(CSng(interval * 24))
26. totalminutes = Int(CSng(interval * 1440))
27. totalseconds = Int(CSng(interval * 86400))
28. hours = totalhours Mod 24
29. Minutes = totalminutes Mod 60
30. Seconds = totalseconds Mod 60
31.
32. GetElapsedTime = days & " Days " & hours & " Hours " & Minutes & _
33. " Minutes " & Seconds & " Seconds "
34.
End Function
NOTA: a função ObterTempoDecorrido requer a passagem de uma data e uma hora.
35. Para testar esta função, crie um novo relatório com base na tabela RegistoDeTempo utilizando o Assistente de relatórios automáticos.
36. Visualize o relatório na vista de estrutura.
37. Adicione uma caixa de texto não ligada à secção de detalhes da tabela RegistoDeTempo e defina as respectivas propriedades da seguinte forma:
38.39. Caixa de texto
40. ---------------
41. Nome: TempoDecorrido
42. OrigemDoControlo: =ObterTempoDecorrido([HoraDeFim]-[HoraDeInício])
Largura: 7,5 cm
43. 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.
2. Tabela: CartãoDePonto
3. ----------------------------
4. Nome do campo: Horas diárias
5. Tipo de dados: Data/hora
Formato: Hora abreviada
6. Visualize a tabela CartãoDePonto na vista de folha de dados, introduza os seguintes quatro registos e feche a tabela:
7.8. 8:15
9. 7:37
10. 8:12
8:03
11. Crie um módulo e escreva a seguinte linha na secção Declarations, caso ainda não exista:
Option Explicit
12. Escreva a seguinte função:
13. Function GetTimeCardTotal ()
14.
15. Dim db As DAO.Database, rs As DAO.Recordset
16. Dim totalhours As Long, totalminutes As Long
17. Dim days As Long, hours As Long, minutes As Long
18. Dim interval As Variant, j As Integer
19.
20. Set db = dbengine.workspaces(0).databases(0)
21. Set rs = db.OpenRecordset("timecard")
22. interval = #12:00:00 AM#
23. While Not rs.EOF
24. interval = interval + rs![Daily hours]
25. rs.MoveNext
26. Wend
27. totalhours = Int(CSng(interval * 24))
28. totalminutes = Int(CSng(interval * 1440))
29. hours = totalhours Mod 24
30. minutes = totalminutes Mod 60
31.
32. GetTimeCardTotal = totalhours & " hours and " & minutes & " minutes"
33.
End Function
34. 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.
Existem aqui no forum excelentes exemplos sobre datas e horas. Encontrei este na internet e achei-o interessante e didático.
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
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:
4. Function GetElapsedDays (interval)
5. Dim days As Long
6.
7. days = Int(CSng(interval))
8. GetElapsedDays = days & " Days "
End Function
9. Para testar esta função, crie uma nova consulta com base na tabela Encomendas.
10. Na grelha QBE, adicione os seguintes campos.
11.
13. Mostrar: Verdadeiro
14.
15. Campo: DataDaEncomenda
16. Mostrar: Verdadeiro
17.
18. Campo: TempoDecorrido: ObterDiasDecorridos([DataDoEnvio]-[DataDaEncomenda])
Mostrar: Verdadeiro
19. 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.
2. Tabela: RegistoDeTempo
3. ---------------------------
4. Nome do campo: HoraDeInício
5. Tipo de dados: Data/hora
6. Formato: Data geral
7.
8. Nome do campo: HoraDeFim
9. Tipo de dados: Data/hora
Formato: Data geral
10. Visualize a tabela RegistoDeTempo na vista de folha de dados, introduza os seguintes três registos e feche a tabela:
11.
13. --------------------------------------------
14. 10/05/95 4:57:00 15/05/95 2:38:00
15. 11/05/95 10:17:31 24/05/95 6:05:00
18/05/95 9:16:43 19/05/95 5:03:00
16. Crie um módulo e escreva a seguinte linha na secção Declarations:
Option Explicit
17. Introduza a a seguinte função:
18. Function GetElapsedTime(interval)
19.
20. Dim totalhours As Long, totalminutes As Long, totalseconds As _
21. Long
22. Dim days As Long, hours As Long, Minutes As Long, Seconds As Long
23.
24. days = Int(CSng(interval))
25. totalhours = Int(CSng(interval * 24))
26. totalminutes = Int(CSng(interval * 1440))
27. totalseconds = Int(CSng(interval * 86400))
28. hours = totalhours Mod 24
29. Minutes = totalminutes Mod 60
30. Seconds = totalseconds Mod 60
31.
32. GetElapsedTime = days & " Days " & hours & " Hours " & Minutes & _
33. " Minutes " & Seconds & " Seconds "
34.
End Function
NOTA: a função ObterTempoDecorrido requer a passagem de uma data e uma hora.
35. Para testar esta função, crie um novo relatório com base na tabela RegistoDeTempo utilizando o Assistente de relatórios automáticos.
36. Visualize o relatório na vista de estrutura.
37. Adicione uma caixa de texto não ligada à secção de detalhes da tabela RegistoDeTempo e defina as respectivas propriedades da seguinte forma:
38.
40. ---------------
41. Nome: TempoDecorrido
42. OrigemDoControlo: =ObterTempoDecorrido([HoraDeFim]-[HoraDeInício])
Largura: 7,5 cm
43. 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.
2. Tabela: CartãoDePonto
3. ----------------------------
4. Nome do campo: Horas diárias
5. Tipo de dados: Data/hora
Formato: Hora abreviada
6. Visualize a tabela CartãoDePonto na vista de folha de dados, introduza os seguintes quatro registos e feche a tabela:
7.
9. 7:37
10. 8:12
8:03
11. Crie um módulo e escreva a seguinte linha na secção Declarations, caso ainda não exista:
Option Explicit
12. Escreva a seguinte função:
13. Function GetTimeCardTotal ()
14.
15. Dim db As DAO.Database, rs As DAO.Recordset
16. Dim totalhours As Long, totalminutes As Long
17. Dim days As Long, hours As Long, minutes As Long
18. Dim interval As Variant, j As Integer
19.
20. Set db = dbengine.workspaces(0).databases(0)
21. Set rs = db.OpenRecordset("timecard")
22. interval = #12:00:00 AM#
23. While Not rs.EOF
24. interval = interval + rs![Daily hours]
25. rs.MoveNext
26. Wend
27. totalhours = Int(CSng(interval * 24))
28. totalminutes = Int(CSng(interval * 1440))
29. hours = totalhours Mod 24
30. minutes = totalminutes Mod 60
31.
32. GetTimeCardTotal = totalhours & " hours and " & minutes & " minutes"
33.
End Function
34. 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.