Power BI · Capítulo 5 · Lección de conceptos · 7 min de lectura

El contexto de filtro y lo que cambia CALCULATE

Por qué la misma medida da un número distinto en cada celda: cada celda le pasa un conjunto de filtros, los filtros viajan por las relaciones y CALCULATE es la única forma de cambiar ese conjunto.

La idea

Una medida DAX es una sola fórmula, pero un informe le hace muchas preguntas. Una matriz con seis filas de categoría, un total y dos segmentadores evalúa Sales siete veces, y cada vez la medida ve filas distintas de los datos. El conjunto de filtros bajo el que corre una sola evaluación es su contexto de filtro.

Tú nunca le pasas los filtros. Lo hace la celda: sus encabezados de fila y de columna, cada segmentador de la página, el panel Filtros y cualquier resaltado cruzado aportan algo. CALCULATE es la única función que permite a una medida cambiar ese conjunto a propósito.

Por qué existe

Imagina el mismo informe sin contexto de filtro. Necesitarías una medida de ventas de Lighting, una de ventas de Furniture, una de ventas web de Lighting en 2025, y así para cada combinación en la que un lector pueda hacer clic. Las hojas de cálculo funcionan así: cada SUMIFS escribe sus propias condiciones.

Power BI le da la vuelta. Defines una vez lo que significa un número (Sales suma line_total) y el informe decide de qué filas se trata. Por eso una misma medida funciona en una tarjeta, una matriz y un gráfico sin cambios, y por eso los segmentadores "simplemente funcionan".

El precio es que las filas detrás de un número no se ven. Cuando una cifra parece incorrecta, la fórmula rara vez es el problema. El problema es el contexto de filtro, y solo puedes arreglarlo si puedes imaginarlo.

Cómo funciona por dentro

Evaluar una celda sigue siempre el mismo orden.

  1. Reunir los filtros. Todo lo que rodea la celda agrega un filtro sobre una columna: el encabezado de fila sobre products[category], el segmentador de Year sobre 'Date'[Year], el segmentador de Channel sobre orders[channel]. Los filtros sobre columnas distintas se combinan con AND.
  2. Poner cada filtro en su propia tabla, la que es dueña de la columna.
  3. Dejar que los filtros fluyan por las relaciones, del lado uno al lado muchos, hasta llegar a la tabla que lee la medida. En el modelo de Harbor & Pine todos los caminos terminan en order_items.
  4. Evaluar la medida sobre las filas que sobrevivieron a todos los filtros.

Figura 1

Cómo llegan a order_items los filtros de una celda

'Date'

  • Date
  • Year
  • Month

Year = 2025

orders

  • order_id
  • order_date
  • channel
  • status

channel = "web"

status = "completed"

customers

  • customer_id
  • segment
  • state

products

  • product_id
  • category

category = "Lighting"

order_items

  • order_id
  • product_id
  • line_total

Paso 1 de 6 El modelo de Harbor & Pine. Cada línea va de un lado uno (1) a un lado muchos (*). order_items guarda los números; Sales suma su line_total.

  1. El modelo de Harbor & Pine. Cada línea va de un lado uno (1) a un lado muchos (*). order_items guarda los números; Sales suma su line_total.
  2. La fila de Lighting en la matriz pone un filtro sobre products[category]. Ese filtro baja por la relación hasta order_items: solo quedan las líneas de Lighting.
  3. El segmentador de Year filtra 'Date'. Ese filtro llega primero a orders y luego a order_items: dos saltos.
  4. El segmentador de Channel cae sobre orders y sigue el mismo camino hacia abajo. Los tres filtros se encuentran ahora en order_items y se combinan con AND.
  5. Los filtros solo fluyen de uno a muchos. El filtro de categoría no sube de vuelta a orders, así que COUNTROWS(orders) seguiría contando pedidos de todas las categorías.
  6. CALCULATE(..., orders[status] = "completed") agrega un filtro más antes de que se haga la suma. Fluye hacia abajo como los demás.

El paso 3 explica muchos números "equivocados". Con relaciones de una sola dirección, un filtro nunca fluye de muchos a uno. Un filtro de categoría reduce order_items pero deja orders intacta, y por eso "pedidos por categoría" necesita DISTINCTCOUNT(order_items[order_id]) y no COUNTROWS(orders).

Aquí está la misma celda como filas reales. Los filtros quitan filas una tras otra; la suma solo se hace al final.

Figura 2

Una celda, filtro por filtro: Lighting, 2025, web

Líneas de pedido (marzo de 2025), con su categoría, canal y estado
order_item_idcategorychannelstatusline_total
19660Lightingwebcompleted54.99
19663Lightingwebcompleted189.00
19749Lightingwebcancelled189.00
19675Lightingappcompleted219.96
19679Furniturewebcompleted746.30
19792Textilesmarketplacecompleted23.99
19662Lightingwebcompleted31.99
La celda de Lighting
Sales
$275.98

Paso 1 de 5 Siete líneas de pedido reales. Antes de cualquier filtro, una medida las vería todas.

  1. Siete líneas de pedido reales. Antes de cualquier filtro, una medida las vería todas.
  2. Encabezado de fila: category = "Lighting". Furniture y Textiles quedan fuera.
  3. Segmentador de Channel: channel = "web". La línea de app también queda fuera. Los filtros sobre columnas distintas siempre se acumulan.
  4. CALCULATE agrega status = "completed". La línea cancelada se elimina.
  5. SUM(order_items[line_total]) se ejecuta sobre lo que queda: 54.99 + 189.00 + 31.99.

Qué hace CALCULATE

CALCULATE(expression, filter1, filter2, ...) trabaja en tres pasos:

  1. Toma una copia del contexto de filtro actual (los filtros de la celda).
  2. Aplica cada argumento de filtro a la copia. Si la columna todavía no está filtrada, el filtro se agrega. Si la columna ya está filtrada, el nuevo filtro reemplaza al anterior. ALL, ALLEXCEPT y REMOVEFILTERS, en cambio, quitan filtros.
  3. Evalúa la expresión en la copia modificada. El contexto original no se toca, así que las celdas vecinas y las demás medidas no se ven afectadas.

La regla de "reemplazar" es la que sorprende a la gente, y es justo en la que se apoyan los porcentajes del total: CALCULATE([Sales], REMOVEFILTERS(products[category])) le da a cada fila de categoría el total de todas las categorías para dividir.

Figura 3

La misma matriz, tres medidas: CALCULATE agrega un filtro o reemplaza uno

Matriz: orders[channel] en las filas
channelGross SalesCompleted SalesWeb Sales
app$2,262,479$2,024,728$3,323,593
marketplace$930,273$837,483$3,323,593
web$3,323,593$3,032,073$3,323,593
Total$6,516,344$5,894,283$3,323,593

Paso 1 de 4 Gross Sales = SUM(order_items[line_total]). Cada fila filtra orders[channel], así que cada celda suma las líneas de ese canal.

  1. Gross Sales = SUM(order_items[line_total]). Cada fila filtra orders[channel], así que cada celda suma las líneas de ese canal.
  2. Completed Sales = CALCULATE([Gross Sales], orders[status] = "completed"). Status es una columna nueva, así que el filtro se agrega: cada canal conserva su filtro de fila y pierde sus líneas canceladas, reembolsadas y pendientes.
  3. Web Sales = CALCULATE([Gross Sales], orders[channel] = "web"). Channel ya está filtrado por la fila, así que CALCULATE reemplaza ese filtro. Todas las filas muestran el número de web.
  4. La fila Total son las mismas medidas sin ningún filtro de canal, no una suma de las filas. Con un SUM simple las dos cosas coinciden; con proporciones y conteos distintos, no.

Cuando quieras que un argumento de filtro reduzca el filtro existente en vez de sobrescribirlo, envuélvelo en KEEPFILTERS. Así la fila de web de una medida App Sales quedaría en blanco, porque ningún pedido es web y app a la vez.

El contexto de fila es otra cosa

Una columna calculada, o un iterador como SUMX, recorre una tabla fila por fila. Esa "fila actual" es el contexto de fila, y no es un filtro. Dentro de una columna calculada en products, la expresión SUM(order_items[line_total]) devuelve el total general en cada fila, porque nada está filtrando order_items: el producto actual es solo una fila que se está visitando.

CALCULATE conecta los dos. Envuelta en CALCULATE, la fila actual se convierte en un filtro (esto se llama transición de contexto), así que CALCULATE(SUM(order_items[line_total])) en esa columna le da a cada producto sus propias ventas. Una referencia a una medida como [Sales] lleva un CALCULATE invisible alrededor, y por eso SUMX(products, [Sales]) funciona y SUMX(products, SUM(order_items[line_total])) repite el total.

Ver el contexto de filtro en Power BI Desktop

La matriz de práctica de este sitio te muestra los filtros de cada celda. En Power BI Desktop también puedes leerlos: pasa el cursor sobre una celda para ver su información sobre herramientas, abre el panel Filtros para ver los filtros del objeto visual, de la página y del informe, y usa Optimizar → Analizador de rendimiento → Copiar consulta para ver los filtros exactos que el objeto visual envía al modelo. Formato → Editar interacciones muestra qué segmentadores llegan a qué objetos visuales. Cuando un número te sorprenda, revisa ahí sus filtros antes de tocar la fórmula.

Errores comunes

"La fila Total suma las filas de arriba"

La fila Total es la medida evaluada otra vez, sin el filtro del encabezado de fila. Con una suma simple eso equivale a la suma de las filas. Con un promedio, un conteo distinto o una proporción normalmente no: el total del "valor promedio del pedido" es el promedio sobre todos los pedidos, no la suma de seis promedios.

"Un filtro en cualquier tabla llega a todas las demás tablas"

Los filtros se mueven por las relaciones, del lado uno al lado muchos, y ahí se detienen, salvo que una relación esté configurada en ambas direcciones. Un segmentador sobre products nunca filtra customers. Si un objeto visual ignora un segmentador, mira las flechas en la vista de modelo antes de mirar el DAX.

"El filtro de CALCULATE se suma al filtro de la fila"

Solo cuando están en columnas distintas. En la misma columna gana el argumento y el filtro de la fila se descarta, y así es como aparece "el mismo número en todas las filas". Usa KEEPFILTERS cuando quieras decir "y además".

Ponte a prueba

Una pregunta. Al responderla, la lección queda marcada en el mapa; nunca bloquea un nivel.

Una matriz tiene orders[channel] en sus filas. Agregas App Sales = CALCULATE([Gross Sales], orders[channel] = "app"). ¿Qué muestra la fila de web?

Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.