CALCULATE y contexto de filtro
La función más poderosa de DAX.
CALCULATE es la función más importante y poderosa de DAX. Si solo pudieras aprender una función avanzada, debería ser esta. CALCULATE te permite modificar el contexto de filtro para crear métricas que serían imposibles de otra manera.
¿Qué es el contexto de filtro?
Antes de entender CALCULATE, necesitas dominar el concepto de contexto de filtro.
El contexto en acción
Cuando colocas una medida en un visual, Power BI automáticamente aplica filtros:
Medida: Total Ventas = SUM(Ventas[Monto])
| Ubicación | Filtros aplicados | Resultado |
|---|---|---|
| Tarjeta sola | Ninguno | Total general |
| Gráfico de barras por País | País actual | Total por país |
| Matriz País x Categoría | País Y Categoría | Total del cruce |
| Con slicer "2024" activo | Año = 2024 | Total de 2024 |
El contexto de filtro es el conjunto de todos los filtros activos que afectan el cálculo.
Fuentes del contexto de filtro
- Slicers: Filtros que el usuario selecciona
- Filtros de visual: Configurados en el panel de filtros
- Filtros de página: Aplican a toda la página
- Filtros de reporte: Aplican a todo el reporte
- Segmentación en visuales: Ejes X, filas, columnas de matrices
- Relaciones: Filtros que viajan por las relaciones del modelo
Introducción a CALCULATE
CALCULATE hace dos cosas:
- Evalúa una expresión (generalmente una medida)
- Modifica el contexto de filtro antes de evaluar
Sintaxis básica
CALCULATE(
expresión,
filtro1,
filtro2,
...
)
Tu primera fórmula con CALCULATE
// Sin CALCULATE: responde a todos los filtros
Total Ventas = SUM(Ventas[Monto])
// Con CALCULATE: fuerza un filtro específico
Ventas Mexico =
CALCULATE(
SUM(Ventas[Monto]),
Ventas[País] = "México"
)
Ventas Mexico siempre mostrará las ventas de México, sin importar qué filtros estén activos en otros campos.
Cómo funciona internamente
Ventas Mexico =
CALCULATE(
SUM(Ventas[Monto]), -- 1. Esta expresión se evaluará
Ventas[País] = "México" -- 2. Después de aplicar este filtro
)
Pasos internos:
- CALCULATE toma el contexto de filtro actual
- Aplica/modifica el filtro: País = "México"
- Evalúa SUM(Ventas[Monto]) con el nuevo contexto
- Devuelve el resultado
Casos de uso prácticos de CALCULATE
Caso 1: Métricas fijas
Métricas que ignoran ciertos filtros:
// Ventas solo de productos Premium, sin importar los slicers
Ventas Premium =
CALCULATE(
SUM(Ventas[Monto]),
Productos[Categoría] = "Premium"
)
// Ventas solo del canal Online
Ventas Online =
CALCULATE(
SUM(Ventas[Monto]),
Ventas[Canal] = "Online"
)
// Ventas solo de clientes nuevos
Ventas Nuevos Clientes =
CALCULATE(
SUM(Ventas[Monto]),
Clientes[Tipo] = "Nuevo"
)
Caso 2: Múltiples filtros
Puedes combinar varios filtros (se aplican con lógica AND):
// Ventas de México en 2024 del canal Online
Ventas Específicas =
CALCULATE(
SUM(Ventas[Monto]),
Ventas[País] = "México",
Calendario[Año] = 2024,
Ventas[Canal] = "Online"
)
Caso 3: Comparativos con el total
Una de las aplicaciones más poderosas:
// Total general (ignorando filtros de categoría)
Total General =
CALCULATE(
SUM(Ventas[Monto]),
ALL(Productos[Categoría])
)
// Porcentaje del total
% del Total =
DIVIDE(
SUM(Ventas[Monto]),
CALCULATE(SUM(Ventas[Monto]), ALL(Productos[Categoría])),
0
)
La función ALL: Ignorar filtros
ALL es el complemento perfecto de CALCULATE. Remueve filtros de columnas o tablas.
Sintaxis
ALL(Tabla) -- Remueve todos los filtros de la tabla
ALL(Tabla[Columna]) -- Remueve filtros solo de esa columna
ALL(Tabla[Col1], Tabla[Col2]) -- Remueve de múltiples columnas
Ejemplos de ALL
// Total ignorando TODOS los filtros
Gran Total =
CALCULATE(
SUM(Ventas[Monto]),
ALL(Ventas)
)
// Total ignorando solo el filtro de categoría
Total sin Filtro Categoría =
CALCULATE(
SUM(Ventas[Monto]),
ALL(Productos[Categoría])
)
// Total ignorando filtros de fecha
Total sin Filtro Fecha =
CALCULATE(
SUM(Ventas[Monto]),
ALL(Calendario)
)
Patrón: Porcentaje del total
// Porcentaje que representa cada categoría del total
% Participación =
VAR VentasActuales = SUM(Ventas[Monto])
VAR VentasTotales = CALCULATE(SUM(Ventas[Monto]), ALL(Productos[Categoría]))
RETURN
DIVIDE(VentasActuales, VentasTotales, 0)
| Categoría | Ventas | % Participación |
|---|---|---|
| Electrónicos | $500,000 | 50% |
| Accesorios | $300,000 | 30% |
| Software | $200,000 | 20% |
| Total | $1,000,000 | 100% |
Variantes de ALL
| Función | Comportamiento |
|---|---|
ALL(Tabla) |
Remueve todos los filtros de la tabla |
ALLEXCEPT(Tabla, Col1, Col2) |
Remueve todos excepto las columnas especificadas |
ALLSELECTED() |
Remueve filtros internos del visual, mantiene slicers |
REMOVEFILTERS() |
Alias moderno de ALL (más legible) |
ALLEXCEPT: Mantener algunos filtros
// Porcentaje dentro del país (mantener filtro de país)
% dentro del País =
VAR VentasActuales = SUM(Ventas[Monto])
VAR VentasPaís =
CALCULATE(
SUM(Ventas[Monto]),
ALLEXCEPT(Ventas, Ventas[País])
)
RETURN
DIVIDE(VentasActuales, VentasPaís, 0)
La función FILTER: Filtros complejos
Mientras que los filtros simples en CALCULATE usan =, para condiciones más complejas necesitas FILTER.
Sintaxis
FILTER(Tabla, Condición)
Cuándo usar FILTER
| Necesidad | Sintaxis |
|---|---|
| Igualdad simple | Tabla[Columna] = "Valor" |
| Mayor/menor que | FILTER(Tabla, Tabla[Columna] > 100) |
| Condiciones múltiples OR | `FILTER(Tabla, Tabla[Col1] = "A" |
| Condiciones con cálculos | FILTER(Tabla, Tabla[Precio] > AVERAGE(Tabla[Precio])) |
Ejemplos de FILTER
// Ventas donde el monto es mayor a $1,000
Ventas Grandes =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(Ventas, Ventas[Monto] > 1000)
)
// Ventas de productos con precio > promedio
Ventas Premium =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(
Productos,
Productos[Precio] > AVERAGE(Productos[Precio])
)
)
// Ventas de México O Colombia
Ventas LATAM =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(
Ventas,
Ventas[País] = "México" || Ventas[País] = "Colombia"
)
)
Cuidado con el rendimiento
FILTER itera sobre cada fila, lo cual puede ser lento con tablas grandes.
// Menos eficiente (FILTER itera toda la tabla)
Ventas Mexico =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(Ventas, Ventas[País] = "México")
)
// Más eficiente (filtro directo)
Ventas Mexico =
CALCULATE(
SUM(Ventas[Monto]),
Ventas[País] = "México"
)
Regla: Usa filtros directos cuando puedas. Reserva FILTER para condiciones que lo requieran.
Patrones avanzados con CALCULATE
Patrón 1: Ranking de ventas
// Clientes con ventas mayores al promedio
Clientes Top =
VAR PromedioVentas = AVERAGEX(ALL(Clientes), [Total Ventas])
RETURN
CALCULATE(
DISTINCTCOUNT(Ventas[ClienteID]),
FILTER(
ALL(Clientes),
[Total Ventas] > PromedioVentas
)
)
Patrón 2: Ventas acumuladas
// Ventas acumuladas hasta la fecha actual
Ventas Acumuladas =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(
ALL(Calendario[Fecha]),
Calendario[Fecha] <= MAX(Calendario[Fecha])
)
)
Patrón 3: Contribución al padre
// % del total de la categoría padre
% Contribución =
VAR VentasProducto = SUM(Ventas[Monto])
VAR VentasCategoria =
CALCULATE(
SUM(Ventas[Monto]),
ALLEXCEPT(Productos, Productos[Categoría])
)
RETURN
DIVIDE(VentasProducto, VentasCategoria, 0)
Patrón 4: Comparativo con valor fijo
// Meta mensual de ventas
Meta Mensual = 100000
// Diferencia vs meta
Diferencia vs Meta = [Total Ventas] - [Meta Mensual]
// % de cumplimiento
% Cumplimiento = DIVIDE([Total Ventas], [Meta Mensual], 0)
Patrón 5: Ventas del período anterior (sin Time Intelligence)
// Ventas del mes anterior
Ventas Mes Anterior =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(
ALL(Calendario),
Calendario[AñoMes] = MAX(Calendario[AñoMes]) - 1
)
)
Variables en DAX: Código más limpio
Las variables hacen tu código más legible y eficiente.
Sintaxis
NombreMedida =
VAR NombreVariable = expresión
VAR OtraVariable = otra_expresión
RETURN
resultado_usando_variables
Ejemplo sin variables (difícil de leer)
% Crecimiento =
DIVIDE(
SUM(Ventas[Monto]) - CALCULATE(SUM(Ventas[Monto]), FILTER(ALL(Calendario), Calendario[Año] = MAX(Calendario[Año]) - 1)),
CALCULATE(SUM(Ventas[Monto]), FILTER(ALL(Calendario), Calendario[Año] = MAX(Calendario[Año]) - 1)),
0
)
Mismo ejemplo con variables (claro y eficiente)
% Crecimiento =
VAR VentasActuales = SUM(Ventas[Monto])
VAR VentasAñoAnterior =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(ALL(Calendario), Calendario[Año] = MAX(Calendario[Año]) - 1)
)
VAR Diferencia = VentasActuales - VentasAñoAnterior
RETURN
DIVIDE(Diferencia, VentasAñoAnterior, 0)
Beneficios de usar variables
- Legibilidad: El código se explica solo
- Rendimiento: La expresión se evalúa una sola vez
- Debugging: Puedes devolver cada variable para probar
- Mantenimiento: Fácil de modificar
REMOVEFILTERS: La versión moderna de ALL
Microsoft introdujo REMOVEFILTERS como alias más legible de ALL dentro de CALCULATE.
// Equivalentes
Total General = CALCULATE(SUM(Ventas[Monto]), ALL(Ventas))
Total General = CALCULATE(SUM(Ventas[Monto]), REMOVEFILTERS(Ventas))
// REMOVEFILTERS es más intuitivo para su propósito
% del Total =
DIVIDE(
SUM(Ventas[Monto]),
CALCULATE(SUM(Ventas[Monto]), REMOVEFILTERS(Productos[Categoría])),
0
)
Errores comunes con CALCULATE
Error 1: Olvidar que CALCULATE modifica el contexto
// Problema: esperabas el total filtrado, pero obtuviste algo diferente
Total Confuso =
CALCULATE(
SUM(Ventas[Monto]),
Ventas[País] = "México",
ALL(Ventas[País]) // Este ALL anula el filtro anterior
)
// El orden de los filtros en CALCULATE importa
Error 2: Usar CALCULATE sin necesidad
// Innecesario
Total = CALCULATE(SUM(Ventas[Monto]))
// Correcto (si no modificas el contexto, no necesitas CALCULATE)
Total = SUM(Ventas[Monto])
Error 3: FILTER en lugar de filtro directo
// Innecesariamente complejo y lento
Ventas 2024 =
CALCULATE(
SUM(Ventas[Monto]),
FILTER(Calendario, Calendario[Año] = 2024)
)
// Más simple y eficiente
Ventas 2024 =
CALCULATE(
SUM(Ventas[Monto]),
Calendario[Año] = 2024
)
Error 4: Confundir contexto de fila y filtro
// En una columna calculada, hay contexto de fila
// En una medida, hay contexto de filtro
// Columna calculada (tiene contexto de fila)
Margen = Ventas[Precio] - Ventas[Costo]
// Medida (tiene contexto de filtro)
Total Margen = SUM(Ventas[Precio]) - SUM(Ventas[Costo])
Resumen de funciones de contexto
| Función | Propósito | Ejemplo |
|---|---|---|
CALCULATE |
Modifica contexto de filtro | CALCULATE(SUM(...), Filtro) |
ALL |
Remueve filtros | ALL(Tabla) o ALL(Tabla[Col]) |
ALLEXCEPT |
Remueve todos excepto | ALLEXCEPT(Tabla, Tabla[Col]) |
ALLSELECTED |
Mantiene filtros de slicer | ALLSELECTED(Tabla) |
REMOVEFILTERS |
Alias de ALL | REMOVEFILTERS(Tabla[Col]) |
FILTER |
Filtro con condición compleja | FILTER(Tabla, Condición) |
KEEPFILTERS |
Añade sin reemplazar | KEEPFILTERS(Tabla[Col] = "X") |
Ejercicio práctico
Crea las siguientes medidas para un dashboard de ventas:
- Total Ventas: Suma simple de montos
- Ventas Online: Solo del canal "Online"
- Ventas Tienda: Solo del canal "Tienda"
- % Canal Online: Ventas Online / Total (ignorando filtro de canal)
- Gran Total: Total ignorando todos los filtros
- % del Gran Total: Ventas actuales / Gran Total
- Ventas Productos Premium: Solo productos con precio > $500
Puntos clave de esta lección
- CALCULATE modifica el contexto de filtro antes de evaluar una expresión
- ALL remueve filtros de tablas o columnas
- FILTER permite condiciones complejas (>, <, OR, etc.)
- Usa filtros directos cuando sea posible (mejor rendimiento)
- Las variables hacen el código más limpio y eficiente
- REMOVEFILTERS es un alias más legible de ALL
- Siempre piensa en qué contexto de filtro necesitas para tu cálculo
Próxima lección
En la siguiente lección dominarás las funciones de Time Intelligence: TOTALYTD, TOTALMTD, SAMEPERIODLASTYEAR y más. Podrás crear comparativos temporales profesionales como ventas año anterior y crecimiento interanual.
Quiz de comprensión
¿Qué hace la función CALCULATE?
¿Cuál es la diferencia entre
ALL(Tabla)yALL(Tabla[Columna])?Escribe una medida DAX que calcule las ventas solo cuando País = "Colombia".
¿Cuándo deberías usar FILTER en lugar de un filtro directo en CALCULATE?
¿Qué hace ALLEXCEPT y cuándo lo usarías?
Escribe una medida que calcule el porcentaje de participación de cada categoría sobre el total de ventas.
Completaste esta leccion?
Marca esta leccion como completada. Tu progreso se guardara en tu navegador.