Con el siguiente código se calcula el número de días laborables entre dos fechas. Si se le pasan los argumentos opcionales NombreTablaFestivos y NombreCampoFestivo, tiene también en cuenta los días festivos que estén guardados en un campo con nombre NombreCampoFestivo en la tabla con nombre NombreTablaFestivos.
Public Function DiasLaborables(FechaDesde As Date, FechaHasta As Date, Optional NombreTablaFestivos As String, Optional NombreCampoFestivo As String) As Long
Dim Laborables As Long
On Error GoTo DiasLaborables_Error
Laborables = 1 + (FechaHasta - FechaDesde)
If NombreTablaFestivos <> "" And NombreCampoFestivo <> "" Then
Laborables = Laborables - DCount("*", NombreTablaFestivos, "[" & NombreCampoFestivo & "] Between #" & Format(FechaDesde, "mm/dd/yyyy") & "# AND #" & Format(FechaHasta, "mm/dd/yyyy") & "#")
End If
Laborables = Laborables - DateDiff("ww", FechaDesde, FechaHasta, vbSaturday)
Laborables = Laborables - DateDiff("ww", FechaDesde, FechaHasta, vbSunday)
Laborables = Laborables + (Weekday(FechaDesde, vbSunday) = 1)
Laborables = Laborables + (Weekday(FechaDesde, vbSaturday) = 1)
DiasLaborables = Laborables
On Error GoTo 0
Exit Function
DiasLaborables_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description &") in procedure DiasLaborables"
End Function
La función WeekendDays calcula la suma de sábados y domingos entre dos fechas sin utilizar ni bucles ni funciones de fecha.
Public Function WeekendDays(DateStart As Date, DateEnd As Date) As Long Dim TotalDias As Long, SemanasCompletas As Long, RestoDias As Long, wdResto As Long, wkd As Long TotalDias = 1 + DateEnd - DateStart SemanasCompletas = TotalDias \ 7 RestoDias = TotalDias Mod 7 'Calculamos el día de la semana del primer día del resto 'wdResto = Weekday(DateEnd - (RestoDias - 1), vbMonday) 'Como no quiero usar funciones de fecha, en vez de la línea anterioruso la siguiente wdResto = 1 + ((DateEnd - (RestoDias - 1) + 5) Mod 7) wkd = SemanasCompletas * 2 'Si el resto de días + el día de la semana (empezando en lunes) es mayor que 6, nos ' cabe un sábado y, si además es mayor que 7, nos cabe un domingo. If RestoDias > 0 Then If (RestoDias + wdResto > 6) Then wkd = wkd + 1 If (RestoDias > 1) And (RestoDias + wdResto > 7) And _ (Weekday(DateStart) <> 1) Then wkd = wkd + 1 End If WeekendDays = wkd End Function
Una de las formas más directas de calcular sábados y domingos entre dos fechas es comprobar con DateDif (”ww”…) cuántas semanas hay que empiezan por sábado y cuántas que empiecen por domingo y sumarle uno más si la primera fecha para el cálculo es sábado o domingo.
Public Function WeekendDays2(DateStart As Date, DateEnd As Date) As Long
Dim wkd As Long
wkd = DateDiff("ww", DateStart, DateEnd, vbSaturday) + DateDiff("ww", DateStart, DateEnd, vbSunday)
If Weekday(DateStart, vbSunday) = 1 Then wkd = wkd + 1
If Weekday(DateStart, vbSaturday) = 1 Then wkd = wkd + 1
WeekendDays2 = wkd
End Function
Y para terminar basta calcular los días que hay entre dos fechas y restarle los sábados y domingos, que obtenemos con la función WeekEndDays, y los festivos que tenemos en una tabla y que obtenemos con dCount().
Function WorkingDays(DateStart As Date, DateEnd As Date, Optional TableName As String, Optional FieldName As String) As Long
Dim SQL As String
Dim Holidays As Long
If DateStart < DateEnd Then
On Error Resume Next
Holidays = DCount("*", TableName, "[" & FieldName & "] Between #" & Format(DateStart, "mm/dd/yyyy") & " AND #" & Format(DateEnd, "mm/dd/yyyy") & "#")
Err.Clear
WorkingDays = (DateEnd - DateStart) - (Holidays + WeekendDays(DateStart, DateEnd))
End If
End Function
Fuente: Utilidades Access
25.02.2008 at 22:16
Hola
me parecio excelente el articulo
pero te cuento que a partir de estoy tratando de generar otra funcion
se trata de como hacer (en access) que si le entrego el numero de semana y año, al funcion me devuelva el rango de fechas…por ejemplo, la semana 1 del 2008 va entre el 1/1/08 y el 6/1/08…
me puedes ayudar??? por favor es que en el trabajo estoy metida hace varios dias sin poder solucionarlo…saludos.
Paula.
27.02.2008 at 8:57
Hola paula,
Acabo de posterar en el blog una función con la que creo que se obtienen los resultados a los que hacías referencia en tu comentario.
http://lumbanico.wordpress.com/2008/02/27/intervalo-de-fechas-de-una-semana-del-ano/
Un saludo.
19.06.2008 at 19:50
Hola. Yo lo que estoy tratando de encontrar es la forma de que access me devuelva una fecha (en día hábil) después de sumarle a otra fecha (también hábil) un número de días (que también deberán ser hábiles).
Cuando digo hábiles me refiero a laborables.
La idea es poder calcular vencimientos. Que el programa me permita añadir a una fecha determinada, por ejemplo, 7 días hábiles.
Gracias por la ayuda que puedas prestarme
21.06.2008 at 11:53
Creo que la siguiente función te puede ayudar. Pasándole una fecha y el número de días hábiles que deseas sumarle te devuelve la fecha hábil. Para este cálculo también utilizar una tabla (tblFes) en la que se guardan los días festivos (distintos de domingos y sábados) que los tiene en cuenta para hacer el cálculo.
Function IPublica(d As Date, p As Integer) As Date
On Error GoTo Err_IPublica
Dim a As Integer
Dim f As Date
While a < p
IPublica_1:
If Weekday(d, vbMonday) = 6 Then d = d + 1: GoTo IPublica_1
If Weekday(d, vbMonday) = 7 Then d = d + 1: GoTo IPublica_1
If IsNull(DLookup(”IdFes”, “tblFes”, “FesFecha=#” & Format(d, “mm/dd/yyyy”) & “#”)) = False Then d = d + 1: GoTo IPublica_1
d = d + 1
a = a + 1
Wend
IPublica_2:
If Weekday(d, vbMonday) = 6 Then d = d + 1: GoTo IPublica_2
If Weekday(d, vbMonday) = 7 Then d = d + 1: GoTo IPublica_2
If IsNull(DLookup(”IdFes”, “tblFes”, “FesFecha=#” & Format(d, “mm/dd/yyyy”) & “#”)) = False Then d = d + 1: GoTo IPublica_2
IPublica = d
Exit_IPublica:
Exit Function
Err_IPublica:
MsgBox Err.Description
Resume Exit_IPublica
End Function
21.06.2008 at 15:06
Si, gracias. Parece lo que busco. Pero ahora me doy cuenta de que hace mucho que no uso el access (aclaro que siempre fui bastante intuitivo, es decir no se de programación ni de sql) y ahora no me acuerdo como se hace para incorporar una función como esta. Me refiero a que no se donde debo copiarla para que funcione.
Estoy tratando de encontrar en tu blog si está explicado esto.
Gracias de nuevo.
21.06.2008 at 17:28
El código de la función debes añadirlo a un módulo de la base de datos de access, y llamarla desde algún evento de un formulario de la siguiente forma: IPublica(21/06/2008,10). Así se añadirán 10 días al 21/06/2008.
21.06.2008 at 22:22
Que bueno, me llegó tu respuesta justo cuando estaba explorando los módulos. Poco a poco voy recordando. Muchas gracias por la atención.
Paso al análisis.
1) Cuando cargo la función, me saltan dos errores de compilación, ambos en el renglón de If IsNull. Aparentemente le faltaría (criteria) en “FesFecha=#”.
2) Puedo hacer que me pregunte el número de días en el evento? Vos me ponés 10, pero para mi, ese número será siempre distinto.
Muchas gracias, de nuevo.
24.06.2008 at 19:54
He añadido un nuevo post con ejemplo que espero que solucione tus dudas.
Un saludo.
http://lumbanico.wordpress.com/2008/06/24/diashabiles/