Lección 18 de 36DAX Esencial

CALCULATE y contexto de filtro

La función más poderosa de DAX.

25 minutos

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

  1. Slicers: Filtros que el usuario selecciona
  2. Filtros de visual: Configurados en el panel de filtros
  3. Filtros de página: Aplican a toda la página
  4. Filtros de reporte: Aplican a todo el reporte
  5. Segmentación en visuales: Ejes X, filas, columnas de matrices
  6. Relaciones: Filtros que viajan por las relaciones del modelo

Introducción a CALCULATE

CALCULATE hace dos cosas:

  1. Evalúa una expresión (generalmente una medida)
  2. 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:

  1. CALCULATE toma el contexto de filtro actual
  2. Aplica/modifica el filtro: País = "México"
  3. Evalúa SUM(Ventas[Monto]) con el nuevo contexto
  4. 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

  1. Legibilidad: El código se explica solo
  2. Rendimiento: La expresión se evalúa una sola vez
  3. Debugging: Puedes devolver cada variable para probar
  4. 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:

  1. Total Ventas: Suma simple de montos
  2. Ventas Online: Solo del canal "Online"
  3. Ventas Tienda: Solo del canal "Tienda"
  4. % Canal Online: Ventas Online / Total (ignorando filtro de canal)
  5. Gran Total: Total ignorando todos los filtros
  6. % del Gran Total: Ventas actuales / Gran Total
  7. 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

  1. ¿Qué hace la función CALCULATE?

  2. ¿Cuál es la diferencia entre ALL(Tabla) y ALL(Tabla[Columna])?

  3. Escribe una medida DAX que calcule las ventas solo cuando País = "Colombia".

  4. ¿Cuándo deberías usar FILTER en lugar de un filtro directo en CALCULATE?

  5. ¿Qué hace ALLEXCEPT y cuándo lo usarías?

  6. 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.