Cómo calcular días laborables entre fechas en DAX: paso a paso
Calcular días laborables entre dos fechas en DAX es una necesidad común en informes de proyectos, SLA y operaciones donde los fines de semana y los festivos no cuentan para el plazo. Esta guía explica el motivo de la lógica (filtrar la Date table, excluir días de la semana y festivos) y ofrece ejemplos concretos con el código DAX mínimo que puede pegar en Power BI Desktop. Al seguir los pasos obtendrá medidas reutilizables y fáciles de probar.
Prerequisitos
- Power BI Desktop o Analysis Services con soporte para DAX.
- Una Date table (tabla de fechas) con columna Date y columnas Year, Month, Weekday, etc. Idealmente marcada como Date table en Modelación.
- Una tabla de eventos/actividades con columnas StartDate y EndDate.
- Una tabla de Festivos (HolidayDate) con una columna Date específica para los festivos a excluir.
Estas tablas permiten usar filtros por intervalo y funciones como FILTER, COUNTROWS, EXCEPT o RELATEDTABLE en DAX. Para conjuntos de datos muy grandes (por ejemplo, >100k filas en Activities) considere medir rendimiento: SUMX por fila es funcional pero puede ser más lento que una solución con columnas calculadas o preagregadas.
Paso 1: Preparar la Date table
Es esencial tener una Date table marcada como Date table en Power BI. La Date table facilita crear filtros entre StartDate y EndDate y calcular columnas como Weekday que luego usamos para excluir sábado y domingo. Ejemplos: calendario de 2020 a 2026 cubre 7 años — 2 557 días (aprox.).
// Exemplo mínimo de criação de Date table em DAX (Nova tabela)
Date =
CALENDAR(DATE(2020,1,1), DATE(2026,12,31))
// Adicionar dia da semana (1=Domingo..7=Sábado)
Date =
ADDCOLUMNS(
CALENDAR(DATE(2020,1,1), DATE(2026,12,31)),
"Year", YEAR([Date]),
"Month", MONTH([Date]),
"Weekday", WEEKDAY([Date],1) // 1 = domingo
)
Nota sobre WEEKDAY: WEEKDAY([Date],1) devuelve 1=domingo ... 7=sábado. Si prefiere usar 1=lunes..7=domingo utilice WEEKDAY([Date],2) y entonces excluya {6,7} para sábado/domingo. Confirme la convención para evitar excluir días erróneos.
Paso 2: Crear la tabla de Festivos
Creé una tabla simple con las fechas de los festivos. Puede importarla desde un fichero CSV, mantenerla manualmente o crearla en DAX como ejemplo. Para 2024 incluya festivos fijos y, si es posible, los móviles (Semana Santa) — esto evitará conteos incorrectos. Ejemplo con 3 festivos para prueba:
// Exemplo de tabela de feriados em DAX (Nova tabela)
Holidays =
DATATABLE(
"HolidayDate", DATE,
{
{ DATE(2024,1,1) },
{ DATE(2024,4,25) },
{ DATE(2024,12,25) }
}
)
Para Portugal, 25 de Abril y 1 de Mayo son típicos; incluya también festivos regionales si es necesario. Valide que las fechas están dentro del intervalo de la Date table.
Paso 3: Relacionar tablas
Creé relaciones entre la Date table y la tabla de Festivos (Date[Date] -> Holidays[HolidayDate]) y, si tiene sentido, entre la Date table y la tabla Activities (por ejemplo, usando una relación activa en Date[Date] para permitir navegación por fechas). Estas relaciones permiten que las funciones de filtro en DAX actúen correctamente en el contexto del modelo.
Sin relaciones adecuadas, funciones como RELATEDTABLE o FILTER pueden no encontrar las filas esperadas y las medidas devolverán valores erróneos. Verifique la dirección de la relación (one-to-many) y que la columna Date sea del tipo date.
Paso 4: Medida para contar días laborables entre dos fechas (ejemplo)
La medida abajo muestra la idea: filtramos la Date table por el intervalo StartDate..EndDate, excluimos fines de semana y restamos los festivos usando EXCEPT. El ejemplo es seguro para intervalos que pueden abarcar varios años.
Business Days =
VAR _Start = MIN(Activities[StartDate])
VAR _End = MAX(Activities[EndDate])
RETURN
CALCULATE(
COUNTROWS('Date'),
FILTER(
'Date',
'Date'[Date] >= _Start &&
'Date'[Date] <= _End &&
NOT('Date'[Weekday] IN {1,7}) && // 1=domingo,7=sábado se WEEKDAY(...,1)
NOT( RELATEDTABLE(Holidays) ) // ver nota abaixo
)
)
Nota técnica: RELATEDTABLE(Holidays) no funciona como booleano directo — por eso la alternativa más robusta es usar EXCEPT para eliminar las fechas que aparecen en la tabla Holidays dentro del mismo intervalo. La versión con EXCEPT está justo debajo en el mismo fichero de código y es la recomendada.
Paso 5: Medida alternativa con SUMX (caso de filas independientes)
Si desea calcular días laborables por cada fila de la tabla Activities (por ejemplo, suma de días laborables por proyecto), use SUMX para iterar por fila. Esto es útil cuando cada fila tiene StartDate/EndDate distintos y quiere el total agregado. Ejemplo de rendimiento: para 10 000 filas, SUMX puede tardar segundos; considere optimizar si es necesario.
Business Days Per Activity =
SUMX(
Activities,
VAR _s = Activities[StartDate]
VAR _e = Activities[EndDate]
VAR _d =
EXCEPT(
SELECTCOLUMNS(FILTER('Date', 'Date'[Date] >= _s && 'Date'[Date] <= _e && NOT('Date'[Weekday] IN {1,7})), "D", 'Date'[Date]),
SELECTCOLUMNS(FILTER(Holidays, Holidays[HolidayDate] >= _s && Holidays[HolidayDate] <= _e), "D", Holidays[HolidayDate])
)
RETURN COUNTROWS(_d)
)
Ejemplo concreto: para Activities con StartDate = 2024-04-22 y EndDate = 2024-04-30, días totales = 9, fin de semana (27-28) = 2, festivo (25-04) dentro del intervalo = 1 → Business Days = 9 - 2 - 1 = 6. Pruebe casos como misma fecha, intervalo que comienza y termina en fin de semana e intervalos que incluyen varios festivos seguidos.
Verificar el resultado
Cree un visual de tabla con Activities[StartDate], Activities[EndDate] y la medida Business Days o Business Days Per Activity. Verifique manualmente para algunos registros: cuente días entre fechas, reste sábados/domingos y confirme que las fechas en Holidays son excluidas. Errores comunes: Date table no marcada como Date table, Weekday mal interpretado (confirme base 1 o 2), festivos fuera del intervalo o relación inexistente. Para validar en masa, filtre por un mes y compare con un cálculo en Excel para 50 filas de prueba.
Conclusión
Con estas medidas puede calcular días laborables entre dos fechas en DAX, excluyendo fines de semana y festivos. Para producción: mantenga la tabla de festivos actualizada (incluya festivos móviles), documente la convención de WEEKDAY en el modelo y probe casos límite. Si necesita mayor rendimiento para miles de filas, considere columnas calculadas en lugar de SUMX o preprocesamiento en la capa ETL. Consejo final: cree una medida de control que devuelva los días de fin de semana y los festivos encontrados por intervalo para facilitar la auditoría.