lunes, junio 29, 2009

La función DIA.LAB (WORKDAYS) mejorada

En la nota anterior mencionamos que la función DIA.LAB (WORKDAY) de Excel adolece del mismo problema como su hermana mayor DIAS.LAB (NETWORKDAYS). Si bien ambas aceptan un rango de fechas como feriados, los días sábado y domingo son considerados fin de semana y por lo tanto no laborales.
No hay forma de cambiar esta definición y si nos ha tocado vivir en alguna parte del mundo donde el fin de semana no es el sábado y el domingo (como en gran parte de los países musulmanes e Israel), estas funciones dan resultados inexactos
.
Ayer mostramos dos soluciones a este problema en lo que respecta a DIAS.LAB. Las fórmulas matriciales propuestas por Chip Pearson y la una UDF (función definida por el usuario) del autor de estas líneas.

Hoy veremos cómo resolver el problema opuesto al planteado ayer: dada la fecha inicial y la cantidad de días hábiles necesarios para completar una misión, cuál será la fecha final.

Si vivimos en cualquier país de Occidente y los días de labor corren de lunes a viernes, podemos usar la función DIA.LAB nativa de Excel. Por ejemplo, si queremos saber cuál será la fecha después de cinco días hábiles empezando el 06/04/2009, DIA.LAB nos da estas respuestas



Excel días laborales

La celda C4 da la respuesta sin tomar en cuenta los feriados; la celda C5 es la fecha calculada tomando en cuenta los feriados (en España).

Pero ¿qué pasa si en nuestro proyecto no se trabaja los martes y jueves en lugar de los sábados y domingos?

Para solucionar este problema usaremos una función definida por el usurario (UDF), FechaFinal

Function FechaFinal(fecha_inicial As Date, _
dias_habiles As Long, _
diasIncluidos As Range, _
Optional feriados As Range)

'JLD Excel blog en Castellano
'Desarrollada por Jorge Dunkelman
'Junio 2009

Dim daysCounter As Long, tmpDays As Date, dateCheck

tmpDays = fecha_inicial + 1
daysCounter = 1

On Error GoTo ErrorHandler


If feriados Is Nothing Then
Do
tmpDays = tmpDays + 1
dateCheck = " "
dateCheck = WorksheetFunction.Match(Weekday(tmpDays, vbMonday), diasIncluidos, 0)
If IsNumeric(dateCheck) Then
daysCounter = daysCounter + 1
End If

Loop Until daysCounter = dias_habiles

Else

Do
tmpDays = tmpDays + 1
dateCheck = " "
dateCheck = WorksheetFunction.Match(CLng(tmpDays), feriados, 0)
If Not IsNumeric(dateCheck) Then
dateCheck = " "
dateCheck = WorksheetFunction.Match(Weekday(tmpDays, vbMonday), diasIncluidos, 0)
If IsNumeric(dateCheck) Then
daysCounter = daysCounter + 1
End If
End If
Loop Until daysCounter = dias_habiles
End If

FechaFinal = tmpDays

Exit Function

ErrorHandler:
dateCheck = "A"
Resume Next


End Function


Los argumentos de la función FechaFinal son
Excel días laborales

Fecha_Inicial: la fecha de incio del proyecto escrita con formato de fecha o una referencia a una celda que contiene esta fecha

Dias_Habiles: un número entero que indica la cantidad de días hábiles a contar desde elprimer día del proyecto

Dias_Incluidos: los días de la semana a tomar en cuenta (1 = lunes, 2 = martes, etc.)

Feriados (opcional): un rango que contiene las fechas de los feriados relevantes.

Los resultados de nuestro ejemplo son:
Excel días laborales




Technorati Tags:

5 comentarios:

  1. Excelente blog Jorge,
    desearía conocer si es posible que, cuando definimos una UDF, insertar una descripción de ayuda para cada argumento, al estilo de las funciones estándar de Excel.
    Un saludo y muchas gracias por anticipado

    ResponderBorrar
  2. Gracias por los conceptos. Estaré publicando una nota sobre el tema en breve.

    ResponderBorrar
  3. Excelente publicacion, pero tengo un problema cuando quiero restar dias a la fecha de partida, ¿Como podria modificar la funcion para que me de un resultado satisfactorio?
    Espero su comentario... gracias

    ResponderBorrar
  4. Estimado,
    no me qued clara la consulta. Para calcular una fecha anterior a la fecha indicada, sencillamente se usa un número negativo en el segundo argumento de la función.
    Comentario aparte: estas UDF son innecesarias si usas Excel 2010 o 2013.

    ResponderBorrar

Nota: sólo los miembros de este blog pueden publicar comentarios.