Grupos de Cálculo (Calculation Groups)
SELECTEDMEASURE, ISSELECTEDMEASURE y compañía — haz que tus medidas sean dinámicas y reutilizables
El problema que resuelven los Grupos de Cálculo
Imagina que tienes 20 medidas en tu modelo: Total Ventas, Total Margen, Total Unidades, Total Costes... Y ahora tu jefe te pide que todas tengan también su versión YTD, su comparativa con año anterior, su % de variación y su media móvil. Eso son 20 × 4 = 80 medidas. ¡Locura! 😱
Los Grupos de Cálculo resuelven exactamente eso: defines la lógica de transformación UNA SOLA VEZ (YTD, año anterior, variación...) y se aplica automáticamente a cualquier medida que el usuario seleccione. De 80 medidas a 20 + 4 items de cálculo.
¿Qué son técnicamente?
Los Grupos de Cálculo son tablas especiales del modelo que contienen "Calculation Items" (ítems de cálculo). Cada ítem aplica una transformación DAX a la medida activa del contexto. Se crean en Tabular Editor (no en Power BI Desktop directamente — aunque desde 2023 hay soporte limitado).
Usos más frecuentes:
- Comparativas temporales: YTD, vs Año Anterior, variación %, media móvil
- Conversión de moneda dinámica
- Formateo condicional basado en la medida seleccionada
- Escenarios What-If aplicados a múltiples medidas
Los Grupos de Cálculo requieren Tabular Editor (herramienta gratuita externa) para crearlos en la mayoría de los entornos. En Power BI Desktop existe soporte desde 2023 pero todavía con limitaciones. Recomendamos Tabular Editor 2 (gratis) o Tabular Editor 3 (de pago) para trabajar con ellos.
¿Cómo se crea un Grupo de Cálculo?
Pasos para crear un Grupo de Cálculo con Tabular Editor:
- Abre Tabular Editor desde Power BI Desktop:
External Tools > Tabular Editor - Click derecho en "Tables" → Add > Calculation Group
- Dale un nombre (ej: "Time Intelligence")
- Dentro, crea "Calculation Items" (uno por transformación)
- Cada Calculation Item tiene una expresión DAX que usa
SELECTEDMEASURE() - Guarda y vuelve a Power BI — verás la nueva tabla en tu modelo
- Añade la tabla de Grupo de Cálculo a un slicer para que el usuario elija la transformación
Una vez creado el Grupo de Cálculo, el usuario del informe verá un slicer con las opciones 'Actual', 'YTD', 'Vs Año Anterior', etc. Al seleccionar una, TODAS las medidas del informe se transforman automáticamente. Magia. 🪄
SELECTEDMEASURE — La función central
Ejemplo — Calculation Item "YTD":
// Este Calculation Item se aplica a cualquier medida cuando el usuario elige "YTD"
// La expresión del ítem "Year-To-Date" sería:
CALCULATE(
SELECTEDMEASURE(), -- representa la medida activa (Total Ventas, Margen, etc.)
DATESYTD('Calendario'[Fecha])
)
// Si el usuario tiene seleccionada "Total Ventas" → calcula Total Ventas YTD
// Si tiene "Total Margen" → calcula Total Margen YTD
// ¡Una sola expresión para todas las medidas!
Ejemplo — Calculation Item "Vs Año Anterior":
CALCULATE(
SELECTEDMEASURE(),
SAMEPERIODLASTYEAR('Calendario'[Fecha])
)
Ejemplo — Calculation Item "Variación % vs Año Anterior":
VAR MedidaActual = SELECTEDMEASURE()
VAR MedidaAnterior =
CALCULATE(
SELECTEDMEASURE(),
SAMEPERIODLASTYEAR('Calendario'[Fecha])
)
RETURN
DIVIDE(MedidaActual - MedidaAnterior, MedidaAnterior, BLANK())
ISSELECTEDMEASURE — Lógica condicional
Caso de uso típico: algunas transformaciones no tienen sentido para ciertas medidas. Por ejemplo, el "% de variación" no tiene sentido para una medida de ratio que ya es un porcentaje.
Ejemplo — Evitar calcular % variación para medidas que ya son porcentajes:
// Calculation Item "Variación % vs Año Anterior":
VAR EsRatio =
ISSELECTEDMEASURE(
[Margen %], -- si la medida activa es Margen %...
[Tasa Conversión], -- ...o Tasa de Conversión...
[% Devoluciones] -- ...o % Devoluciones
)
VAR MedidaActual = SELECTEDMEASURE()
VAR MedidaAnterior =
CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendario'[Fecha]))
RETURN
IF(
EsRatio,
MedidaActual - MedidaAnterior, -- para ratios: diferencia absoluta
DIVIDE(MedidaActual - MedidaAnterior, MedidaAnterior, BLANK()) -- para importes: %
)
SELECTEDMEASURENAME — Metadatos
Ejemplo — Título dinámico en una card KPI:
// Medida para el título del visual:
Título KPI Dinámico =
SELECTEDMEASURENAME() & " — " &
SELECTEDVALUE('Time Intelligence'[Nombre], "Actual")
// Si el usuario tiene seleccionado "Total Ventas" y "YTD":
// → "Total Ventas — YTD"
Ejemplo — Lógica basada en el nombre:
// Aplicar formato diferente si el nombre contiene "%"
Calc Item con Formato =
IF(
CONTAINSSTRING(SELECTEDMEASURENAME(), "%"),
SELECTEDMEASURE(), -- los % ya están bien formateados
SELECTEDMEASURE() * 1000 -- convertir unidades a miles
)
SELECTEDMEASUREFORMATSTRING — Formatos dinámicos
Ejemplo — Heredar el formato de la medida original:
// En la propiedad "Format String Expression" del Calculation Item YTD:
SELECTEDMEASUREFORMATSTRING()
// Así si [Total Ventas] usa "#,##0 €", el YTD también usará "#,##0 €"
// Si [Margen %] usa "0.0%", el YTD de Margen también usará "0.0%"
Ejemplo — Formato condicional:
// Para el ítem "Variación %": siempre mostrar como porcentaje
IF(
CONTAINSSTRING(SELECTEDMEASUREFORMATSTRING(), "%"),
SELECTEDMEASUREFORMATSTRING(), -- si ya es %, mantener
"+0.0%;-0.0%;0.0%" -- sino, formato de variación con signo
)
NAMEOF — Referencia segura a objetos
Ejemplo — Referencia segura a nombres de medidas:
// ❌ Sin NAMEOF — si cambias el nombre de la medida, esto falla silenciosamente
IF(SELECTEDMEASURENAME() = "Total Ventas", ...)
// ✅ Con NAMEOF — si cambias el nombre de la medida, DAX te avisará del error
IF(SELECTEDMEASURENAME() = NAMEOF([Total Ventas]), ...)
// También funciona con columnas
NAMEOF('Productos'[Categoría]) -- devuelve "Categoría"
Los 3 Grupos de Cálculo que todo modelo debería tener
Patrón 1 — Grupo "Time Intelligence" (el más común)
Ítems típicos:
- "Actual" →
SELECTEDMEASURE() - "YTD" →
CALCULATE(SELECTEDMEASURE(), DATESYTD('Calendario'[Fecha])) - "QTD" →
CALCULATE(SELECTEDMEASURE(), DATESQTD('Calendario'[Fecha])) - "MTD" →
CALCULATE(SELECTEDMEASURE(), DATESMTD('Calendario'[Fecha])) - "vs Año Anterior" →
CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendario'[Fecha])) - "Variación % YoY" → Cálculo de % de variación
- "Media Móvil 12M" → Media de los últimos 12 meses
El usuario ve un slicer con estas opciones. Al elegir "YTD", todas las medidas del informe muestran su versión Year-To-Date automáticamente. ✨
Patrón 2 — Grupo "Conversión de Moneda"
Ítems típicos: "EUR", "USD", "GBP"
// Ítem "USD":
SELECTEDMEASURE() * LOOKUPVALUE(
'TasasCambio'[Tasa],
'TasasCambio'[Moneda], "USD"
)
// El usuario selecciona "USD" en el slicer → todas las medidas se convierten a dólares
Patrón 3 — Grupo "Escenarios"
Ítems típicos: "Real", "Presupuesto", "Forecast"
// Ítem "Presupuesto":
CALCULATE(
SELECTEDMEASURE(),
'Hechos'[Tipo] = "Budget"
)
// Permite que una sola medida muestre el escenario seleccionado por el usuario
Crea el Grupo "Time Intelligence" PRIMERO — es el más útil y el que más mantenimiento te ahorrará. Un modelo con 50 medidas + Time Intelligence Group puede reemplazar fácilmente 200+ medidas hardcodeadas.
Limitaciones y consideraciones
- Solo un Grupo de Cálculo activo a la vez por visual en Power BI (puedes tener varios en el modelo, pero su interacción es compleja)
- Interacción compleja cuando hay múltiples Grupos de Cálculo en el mismo informe — requiere entender la precedencia
- Requieren Tabular Editor para su creación en la mayoría de entornos (aunque el soporte nativo va mejorando)
- Precedencia de ítems importante cuando hay múltiples Grupos aplicados simultáneamente
- No todos los visuals de Power BI respetan los Grupos de Cálculo por igual — algunos tienen comportamientos inesperados
- Rendimiento: pueden afectar al rendimiento si los Calculation Items son muy complejos o anidados
- Curva de aprendizaje: requiere entender bien el contexto de evaluación DAX para usarlos eficientemente
¡Ahora ya conoces las funciones DAX más avanzadas y menos conocidas! Los Grupos de Cálculo son una de esas herramientas que, una vez que las usas, no puedes creer que hayas vivido sin ellas. El siguiente paso en tu journey DAX es revisar las funciones de Manipulación de Tablas para sacar partido máximo de SUMMARIZECOLUMNS, TREATAS y GENERATE.