martes, 20 de marzo de 2018

CÁLCULO DE DÍAS LABORABLES ENTRE FECHAS


Existen numerosos ejemplos de funciones vba con este fin, pero las que conozco utilizan un bucle para recorrer todas las fechas y evaluar el día de la semana para contabilizarlas o no. Dado que en Access "el primer día" del tipo de datos FechaHora es el 01-01-1900, utilizar un bucle tampoco es demasiado costoso, pero me ha parecido un reto prescindir de él.

Se trata de un método para calcular dentro de una instrucción sql y sin necesidad de emplear vba, los días laborables entre fechas (ambas incluidas).

Para una mayor claridad en el código, utilizo dos parámetros, de nombre suficientemente descriptivo: FirstDate y LastDate. Obviamente pueden substituirse por valores o campos.

WorkDays:

Parameters FirstDate DateTime, LastDate DateTime;
Select DateDiff("d",FirstDate, LastDate, 2) As Days ,
       ((Days -1 - ((7 + 6 - WeekDay(FirstDate, 2)) Mod 7)) \ 7)
       + Abs(DateAdd("d", (7 + 6 - WeekDay(FirstDate, 2)) Mod 7, FirstDate) <= LastDate)         As SaturDays, 
       ((Days -1 - ((7 + 7 - WeekDay(FirstDate, 2)) Mod 7)) \ 7)
       + Abs(DateAdd("d", (7 + 7 - WeekDay(FirstDate, 2)) Mod 7, FirstDate) <= LastDate)         As SunDays,
       Days - SaturDays - SunDays As WorkDays;

De hecho, mas que un procedimiento para calcular días hábiles, lo que obtenemos es el número de días que son sábado (líneas dos y tres) y domingo (líneas cinco y seis), para finalmente descontar ambas cantidades del total de días entre ambas fechas.

He resaltado en amarillo algunos números, es la parte de la lógica que discrimina la clase de día de la semana (6 para el sábado y 7 para el domingo). Si se quiere adaptar el código para obtener el número de fechas que coincidan con cualquier otro día de la semana, solo hay que modificar el número resaltado.

Por otra parte, aclarar que el valor 2 en las funciones de fecha, es para indicar que el primer día de la semana es el lunes (corresponde al valor de la enumeración: VbDayOfWeek.vbMonday).

Ramon Poch. Terrassa a 20/03/2018.