Tratamiento de Días No Laborales, Parte III – Número de Días Laborales Entre Dos Fechas.
Este artículo pertenece a la tercera parte de la serie de cuatro que se dedican a ver como trabajar y realizar cálculos con días laborales y no laborales con Power BI, en este artículo vemos como contar los días laborales entre un par de fechas.
— TABLA DE CONTENIDO DE ESTE ARTÍCULO
1. Número de días entre un par de fechas
a. Conteo de días con resta
b. Conteo de días con CONVERT
c. Conteo de días con INT
2. Número de días laborales entre un par de fechas
a. La ide básica
b. Número de días laborales con DATESBETWEEN y CALCULATE
Bienvenido a un nuevo artículo de la serie donde estamos explorando acerca de cómo trabajar con días laborales y no laborales en Power BI Desktop.
Si no has leído la primera parte de esta serie, te recomiendo muchísimo que le des una oportunidad, no porque sea un requisito obligatorio, porque la verdad, si ya tienes una tabla que te liste todos los días no laborales (porque de eso se trata el primer artículo), entonces, puedes proceder con las medidas del presente post.
A pesar de ello, es altamente recomendable por los trucos de Power Query que allí residen, unas utilidades que es bueno que tengas en tu kit de herramientas.
Por otro lado, si no has leído la segunda parte de esta serie, también te recomiendo que le des una lectura consiente no sólo porque se crea la medida para determinar los ingresos por día laboral, sino porque también es un buen ejercicio para practicar expresiones DAX, además, el presente artículo utiliza información del mismo.
Número de Días Entre un Par de Fechas
La verdad sea dicha, determinar el número de días entre un par de fechas es fácil, puesto que sólo basta con hacer la diferencia aritmética.
Conteo de Días con sólo resta
Por ejemplo, si queremos determinar el número de días que transcurrido desde la fecha de pedido hasta que el cliente recibe su producto:
DiasTranscurridos =
Pedidos[Fecha de Llegada] – Pedidos[Fecha de Envio]
Claro, el formato que retorna la columna calculada anterior es de tipo fecha, puesto que los dos formatos en los campos involucrados son de este tipo.
Por lo anterior, visualmente no es muy útil para nuestro objetivo.
Conteo de días con CONVERT
Para retornar la diferencia entre un par de fechas como un número entero podemos apoyarnos de la función CONVERT.
DiasTranscurridos =
CONVERT ( Pedidos[Fecha de Llegada] – Pedidos[Fecha de Envio]; INTEGER )
Véase el resultado:
Conteo de Días con INT
El inconveniente con la función CONVERT es que es reciente en el lenguaje DAX, de la versión de SSAS, Azure AS y Power BI de septiembre del 2019 en adelante.
Por lo que en Excel no es posible utilizarla, a pesar de ello con la función INT conseguimos el mismo resultado y de una manera más compacta:
DiasTranscurridos =
INT ( Pedidos[Fecha de Llegada] – Pedidos[Fecha de Envio] )
Otra opción puede ser con la función DATEIFF que entre otras también es una función de antaño del lenguaje DAX, así:
DiasTranscurridos =
DATEDIFF ( Pedidos[Fecha de Pedido]; Pedidos[Fecha de Llegada]; DAY ) – 1
Intuitivamente, las expresiones DAX de columnas calculadas previas tienen en consideración todas las fechas en el intervalo.
Número de días laborales entre un par de fechas
Si lo anterior hubiera sido todo, miel sobre hojuelas.
Sin embargo,
— ¿Cómo contar el número de días entre un par de fechas omitiendo fines de semana y días festivos?
Para solucionar este caso, tenemos una gran ventaja, y es que: de la parte dos de esta serie de artículo dedicada días laborales, creamos una columna calculada que nos indica si un día es laboral o no; Con 0 para día no laboral y 1 para día laboral:
La Idea Básica
La primera reflexión es que al final es un simple conteo de las filas en la tabla de calendario entre un par de fechas, es decir:
:=
COUNTROWS ( Calendario )
No obstante, sólo debe incluir fechas laborales. Esto lo que quiere decir es que se debe modificar el contexto de filtro de la tabla de Calendario para que realice el conteo restringido a el par de fechas.
Número de Días Laborales Entre Dos Fechascon CALCULATE y DATESBETWEEN
Puede sonar extraño hablar del contexto de filtro en una columna calculada, pero si interiorizamos que el contexto de filtro siempre existe y que para una columna calculada al principio este vacío, todo cobrará sentido.
Podemos verlo así:
Esto desemboca a que podemos utilizar la función CALCULATE para inyectar un nuevo filtro a ese contexto de filtro vacío, que por una de sus propiedades sabemos que dichos filtros se aplicaran automáticamente a las tablas correspondiente en el modelo, por lo tanto, la expresión COUNTROWS ( Calendario ) se determinaría ese contexto de filtro modificado.
El asunto ahora es:
—¿Cómo generamos una tabla de una única columna con todas las fechas entre: Fecha de Pedido y Fecha de Llegada?
Para hacer el análisis, centrémonos en la primera fila de la tabla Pedidos:
Claro, como es una columna calculada y existe un contexto de fila, entonces, las fechas especificas viene dadas simplemente por la referencia a cada campo.
Ahora bien, La función DATESBETWEEN genera una tabla con todas las fechas entre unos extremos señalados en sus parámetros, esto quiere decir que la tabla que necesitamos generar para un parámetro de filtro de la función CALCUALATE es como sigue:
=
DATESBETWEEN (
Calendario[Fecha];
Pedidos[Fecha de Pedido];
Pedidos[Fecha de Llegada] – 1
)
El objetivo a abarzar es inyectar esa tabla a el contexto de filtro vacío que sabemos que existe en una columna calculada:
Por lo tanto, nuestra columna calculada va quedando así:
=
CALCULATE (
COUNTROWS ( Calendario );
DATESBETWEEN (
Calendario[Fecha];
Pedidos[Fecha de Pedido];
Pedidos[Fecha de Llegada] – 1
)
)
Evidentemente, es lo mismo que la simple resta documentado en este artículo más arriba.
No obstante, al tener CALCULATE disponible es viable inyectar otro filtro (tabla) pero que indique solamente día laboral.
Visualmente, sería esto:
La creación de esta última tabla (la tabla con la manito) es muy sencilla porque al ser un único campo con una constante podemos emplear la syntax sugar, por que sería: Calendario[Día Laboral] = 1
Por consiguiente, nuestra columna calculada va quedando:
=
CALCULATE (
COUNTROWS ( Calendario );
DATESBETWEEN (
Calendario[Fecha];
Pedidos[Fecha de Pedido];
Pedidos[Fecha de Llegada] – 1
);
Calendario[Día Laboral] = 1
)
Adicional, a los filtros que añadimos explícitamente, también se agregan una serie de filtros implícitos por la operación de transición de contextos, esto es así por la existencia de un contexto de fila generado en primer lugar y un CALCULATE, es decir, nuestro contexto de filtro realmente luciría:
Por lo tanto, para evitar comportamientos anómalos por filtros que se pueden añadir por transición de contextos, debemos aplicar ALL a toda la tabla Pedidos para anular ese comportamiento, por lo que nuestra expresión DAX finalmente queda:
=
CALCULATE (
COUNTROWS ( Calendario );
DATESBETWEEN (
Calendario[Fecha];
Pedidos[Fecha de Pedido];
Pedidos[Fecha de Llegada] – 1
);
Calendario[Día Laboral] = 1;
ALL ( Pedidos )
)
Realmente no es necesario el argumento modificador de CALCULATE, puesto que los filtros de la transición de contexto afectan a Pedidos y no a la tabla de Calendario que es el objeto de conteo del primer parámetro de CALCULATE.
Sin embargo, añadir el modificador es muy buen factor de seguridad en general, porque si el conteo se realiza sobre Pedidos ya estará solucionado, igualmente si el conteo se realiza en una tabla diferente que no sea Calendario ni tampoco Pedidos pero que esté relacionada con esta última.
Mejor dicho, utiliza el ALL y listo !
Finalmente, esta expresión es básica, puesto que con columna calculada se entiende más fácil, no obstante, se debe tener cuidado si se crea en una tabla con demasiados registros, dado que puede repercutir significativamente en el rendimiento del modelo.
Bibliografía
- SQLBI: https://www.sqlbi.com/articles/counting-working-days-in-dax/
- EXCEL FREE BLOG: https://www.excelfreeblog.com/?s=d%C3%ADas+laborales
.
Eso es todo por hoy
Por favor, regálame tus comentarios, no me gusta sentirme sólo en estos artículos 😉 Además tu retroalimentación me ayuda muchísimo. Estaré leyendo y respondiendo todos los comentarios.
— ¿Seguimos profundizando en esta temática en Power BI?
Estamos charlando en la sección de comentarios
— Miguel Caballero