Usando Relaciones Virtuales en Power BI

Es posible que a lo largo de nuestra experiencia en el desarrollo de reportes y tableros con la herramienta Power BI Desktop nos encontremos con escenarios de modelamiento complejos en los cuales no podamos relacionar una o más tablas por medio de relaciones físicas, Esto debido a que creamos dependencias circulares lo cual no es permito en la herramienta o simplemente la complejidad del modelo no nos permite hacerlo.

En este Post encontrara tres alternativas de solución a estos escenarios por medio de las cuales podremos hacer medidas que tengan en cuenta en su contexto relaciones virtuales entre tablas usando lenguaje DAX.

Ilustraremos las soluciones mediante un escenario de ventas en el que existen las tablas Productos, Tiempo y Ventas sin tener relaciones físicas entre ellas como se ilustra en la siguiente figura:

alt

1. Mediante la función CONTAINS

Haciendo uso de la función CONTAINS dentro de la función CALCULATE podemos crear una medida que realiza la sumatoria de ventas teniendo en cuenta un contexto de filtrado en el que los valores de IDProducto de la tabla Productos estén contenidos en el campo IDProducto de la tabla Ventas, llevando la siguiente sintaxis en DAX:

Contains = CALCULATE(SUM(Ventas[Valor_Venta]), FILTER(ALL(Ventas[ID_Producto]), CONTAINS(VALUES(Productos[ID_Producto]), Productos[ID_Producto], Ventas[ID_Producto])))

A la Medida le podemos añadir otro filtro para que tenga en cuenta también un contexto de filtrado en el que la fecha de la Venta de la tabla Ventas este contenida dentro de la fecha de la tabla fecha quedando la sintaxis de la siguiente manera:

Contains = CALCULATE(SUM(Ventas[Valor_Venta]), FILTER(ALL(Ventas[ID_Producto]), CONTAINS(VALUES(Productos[ID_Producto]), Productos[ID_Producto], Ventas[ID_Producto])),FILTER(ALL(Ventas[Fecha]),CONTAINS(VALUES(Tiempo[Date]),Tiempo[Date],Ventas[Fecha])))

De manera que podremos identificar por ejemplo las ventas (Tabla Ventas) que se realizaron por categoría (Tabla Productos) a lo largo del tiempo (Tabla Fecha) como se aprecia en la siguiente figura:

alt

2. Mediante la función INTERSECT

Haciendo uso de la función INTERSECT dentro de la función CALCULATE podemos crear una medida que realiza la sumatoria de ventas teniendo en cuenta un contexto de filtrado en el que los valores de IDProducto de la tabla Productos hace intersección con los IDProducto de la tabla de Ventas, llevando la siguiente sintaxis en DAX:

Intersect = CALCULATE(SUM(Ventas[Valor_Venta]), INTERSECT(ALL(Ventas[ID_Producto]),VALUES(Productos[ID_Producto])))

A la Medida le podemos añadir otro filtro para que tenga en cuenta también un contexto de filtrado en el que la fecha de la Venta de la tabla Ventas hace intersección con la fecha de la tabla fecha quedando la sintaxis de la siguiente manera:

Intersect = CALCULATE(SUM(Ventas[Valor_Venta]), INTERSECT(ALL(Ventas[ID_Producto]),VALUES(Productos[ID_Producto])), INTERSECT(ALL(Ventas[Fecha]),VALUES(Tiempo[Date])))

De la misma manera que con la función CONTAINS podremos identificar por ejemplo las ventas (Tabla Ventas) que se realizaron por categoría (Tabla Productos) a lo largo del tiempo (Tabla Fecha) obteniendo el mismo resultado como se aprecia en la siguiente figura:

alt

3. Mediante la función TREATAS

Haciendo uso de la función TREATAS dentro de la función CALCULATE podemos crear una medida que realiza la sumatoria de ventas teniendo en cuenta un contexto de filtrado en él se tratan únicamente los valores de IDProducto de la tabla Productos que coinciden con los IDProducto de la tabla de Ventas, llevando la siguiente sintaxis en DAX:

Treatas = CALCULATE(SUM(Ventas[Valor_Venta]), TREATAS(VALUES(Productos[ID_Producto]),Ventas[ID_Producto]))

A la Medida le podemos añadir otro filtro para que se traten también en el contexto de filtrado la fecha de la Venta de la tabla Ventas que coinciden con la fecha de la tabla fecha quedando la sintaxis de la siguiente manera:

Treatas = CALCULATE(SUM(Ventas[Valor_Venta]), TREATAS(VALUES(Productos[ID_Producto]),Ventas[ID_Producto]), TREATAS(VALUES(Tiempo[Date]),Ventas[Fecha]))

De igual manera que con la función CONTAINS y la función INTERSECT podremos identificar por ejemplo las ventas (Tabla Ventas) que se realizaron por categoría (Tabla Productos) a lo largo del tiempo (Tabla Fecha) obteniendo el mismo resultado como se aprecia en la siguiente figura:

alt

Finalmente usando cualquiera de las 3 funciones para crear medidas que lleven en su contexto relaciones virtuales permite que la medida sea filtrada por los atributos de las tablas relacionadas ya sea usando filtros a nivel de visualización, filtros a nivel de página, filtros a nivel reporte, filtros de obtención de detalles, filtros en objetos visuales como slicers y filtros cruzados entre objetos visuales.