Eliminación de la transición de contexto

En ocasiones necesitaremos evitar que la transición de contexto se produzca. O, si se produce, que sus consecuencias queden inhabilitadas. Supongamos que nos encontramos en el siguiente escenario: necesitamos incluir en la tabla que contiene el listado de categorías una columna calculada conteniendo el porcentaje que las ventas de cada categoría suponen son respecto al total.

La expresión DAX a usar debería obtener las ventas de cada categoría (para lo que resultará conveniente que se ejecute la transición de contexto) y las ventas totales, cálculo para el que no queremos que se ejecute la transición de contexto pues no deseamos que el modelo de datos se esté filtrando para obtener esta cifra. Y, estando en contexto de fila, sabemos que el uso de CALCULATE o la referencia a una medida va a ejecutar la transición de contexto. La expresión DAX a usar para la columna calculada será -escrita parcialmente en seudocódigo- algo como lo siguiente:

Sales Pct = 
VAR __catSales = Ventas de la categoría siendo considerada
VAR __allSales = Ventas totales considerando todas las categorías
RETURN
    DIVIDE(
        __catSales,
        __allSales
    )

Tal y como se ha comentado, las ventas de la categoría “actual” se pueden obtener dejando que se ejecute la transición de contexto. Es decir:

Sales Pct = 
VAR __catSales = [Sales]
VAR __allSales = Ventas totales considerando todas las categorías
RETURN
    DIVIDE(
        __catSales,
        __allSales
    )

La cuestión es cómo obtenemos las ventas totales (variable __allSales). Por supuesto, en este caso podríamos calcularlas evitando hacer uso de la función CALCULATE y sin referencias a medidas con la función SUM y apuntando a la columna Sales[Amount]:

Sales Pct = 
VAR __catSales = [Sales]
VAR __allSales = SUM(Sales[Amount])
RETURN
    DIVIDE(
        __catSales,
        __allSales
    )

pero habrá casos en los que el cálculo sea más complejo y requiera modificar el contexto de filtro en el que se produzca o involucrar medidas.

Pues bien, en un caso como éste, la solución pasa por hacer uso de la función CALCULATE eliminando los filtros que la transición de contexto produzca. Por ejemplo:

Sales Pct = 
VAR __catSales = [Sales]
VAR __allSales =
    CALCULATE(
        [Sales],
        ALL(Sales)
    )
RETURN
    DIVIDE(
        __catSales,
        __allSales
    )

Obsérvese que, en la variable __allSales estamos haciendo uso de la función CALCULATE -lo que va a desencadenar la transición de contexto, filtrando las tablas Subcategory, Products y, finalmente, Sales, pero con la función ALL estamos limpiando los filtros aplicados a esta última antes de realizar el cálculo que nos interesa (el dado por la medida [Sales]).