Comparar periodos no paralelos sin USERELATIONSHIP

Vamos a ver cómo comparar periodos NO paralelos en Power BI sin necesidad de duplicar y relacionar tablas de fechas que luego requieren USERELATIONSHIP para gestionarlas. La solución ofrecida permite evitar la creación de múltiples medidas cuando se desea tener la posibilidad de comparar con diferentes periodos, el dia anterior, 7, 15, 30… días atrás.

Y es muy simple.

Este artículo se plantea como continuación de la serie iniciada con el artículo “compara periodos no paralelos en Power BI“. Usaremos el mismo set de datos.

La idea: Elegir un periodo y decir cuántos días queremos irnos atrás en la comparación

Ni más ni menos. Es una idea alternativa para comparar periodos no paralelos. La siguiente imagen ilustra el proceso:

Elige el periodo y cuántos días atrás quieres ir atrás en la comparación

Crear una tabla para los días “atrás” con GENERATESERIES

Necesitaremos una tabla para el slider de días atrás. Ésta sólo contendrá una secuencia de días o enumeración, del 1 al 365, por ejemplo.

Añadiremos una tabla que llamaremos “Dias” y que sólo tendrá una sentencia DAX, GENERATESERIES que espera como parámetros el límite inferior y el superior:

Dias = GENERATESERIES(1;365)

El resultado final una tabla con una columna con valores del 1 al 365.

No vamos a relacionarla en el modelo.

Ahora agregamos un slicer con los valores de esta tabla. Como sólo nos interesa el límite superior de este slicer, pulsando el desplegable de opciones del slicer elegimos la opción de Menor o igual:

Esto deshabilita el límite inferior del slicer y sólo permite cambiar el superior.

La medida comparativa es dinámica: DATEADD y MAX

Vamos a agregar una medida DAX con los valores a comparar. Estos serán los mismos que la medida elegida y que tomará valores del mismo periodo, pero tantos dias atrás como hayamos elegido en el slicer “Dias”.

Para ello vamos a recurrir a la función DATEADD. Te recomiendo leer este post “No, DATEADD no es lo mismo que PARALLELPERIOD“, que detalla y compara distintas funciones para time intelligence, entre ellas, DATEADD.

Esta función permite sumar-restar periodos a una fecha. En este caso queremos la suma del importe de X días atrás: DATEADD coge la fecha actual y le resta (ojo que hay un signo menos delante de MAX) el valor máximo de Dias (parámetro DAY):

Periodo Resta Dias = CALCULATE(SUM(VentaDiariaHoteles[Importe]);DATEADD(Fechas[Date];-MAX(Dias[Value]);DAY)) 

Por último podríamos añadir otra medida que calculase el % de variación entre ambas medidas:

% Variación Periodo = divide(sum(VentaDiariaHoteles[Importe])-[Periodo Resta Dias];[Periodo Resta Dias])

Y ya está. De este modo has proporcionado al usuario una funcionalidad sencilla para hacer comparaciones y probablemente has evitado la creación de múltiples medidas y nuevas relaciones que complican la gestión del modelo si hay que gestionarlas con USERELATIONSHIP.

Está, además, es operativa para cualquier tipo de agrupación de fecha: Dias, meses…

Espero que te haya sido útil.

Te puede interesar...

8 comentarios en «Comparar periodos no paralelos sin USERELATIONSHIP»

  1. Tengo un problema que aún no soluciono, quiero comparar mes actual con anterior a la fecha entonces, no hay problema si comparo meses iguales o con número de días iguales, por ejemplo comparo abril (30 días) marzo (31 días), tengo un slicer para días, entonces si selecciono 30 me compara el 30 de abril con el 30 de marzo, pero el problema radica por el número de días diferente, si quisiera comparar el mes total, ejemplo abril hasta 30 y marzo 31 no me da o no me suma valor a marzo dado que la comparación se trunca a 30, como podría solucionarlo cuando tenga ese caso.

    1. Hola Edison, si tu modelo de datos tiene tabla de fechas puedes usar funciones de time intelligence. La función DAX recomendada en este caso es SAMEPERIODLASTYEAR, PREVIOUSMONTH o DATEADD, dependiendo del enfoque que necesites. Para tu caso (mes anterior, independientemente de la cantidad de días), la más adecuada es PREVIOUSMONTH o DATEADD:

      Ventas Mes Anterior =
      CALCULATE(
      [Ventas],
      PREVIOUSMONTH(DimFecha[Fecha])
      )

      o:

      Ventas Mes Anterior =
      CALCULATE(
      [Ventas],
      DATEADD(DimFecha[Fecha], -1, MONTH)
      )

      1. Me funciona parcialmente utilizando DATEADD, pero mi objetivo final es comparación no paralela: Tengo una tabla calendario, al comparar mes ejemplo abril con marzo, tengo el problema que solo compara hasta 30 de abril con 30 de marzo, pero quiero tambien que me permita poder comparar hasta 30 abril con el hasta 31 marzo(que seria comparación total mesnual) , con la sigueinte medida me calcula hasta el 30 de abril con el 30 de marzo pero se trunca y ya no acumula el valor del 31 de marzo para que sea mensual:
        LEADS_MES-1 =
        VAR FechaFinPeriodoActual = MAX(ro_omnicanalidad[fch_creacion_omnicanalidad])
        VAR FechaInicioPeriodoActual = MIN(ro_omnicanalidad[fch_creacion_omnicanalidad])
        VAR FechaInicioPeriodoAnterior = EDATE(FechaInicioPeriodoActual, -1)
        VAR FechaFinPeriodoAnterior = EDATE(FechaFinPeriodoActual, -1)
        VAR LeadsPeriodoAnterior =
        CALCULATE(
        COUNT(ro_omnicanalidad[llv_omnicanalidad_lead]),
        ro_omnicanalidad[fch_creacion_omnicanalidad] >= FechaInicioPeriodoAnterior &&
        ro_omnicanalidad[fch_creacion_omnicanalidad] <= FechaFinPeriodoAnterior,
        ALL(ro_omnicanalidad)
        )
        RETURN

        LeadsPeriodoAnterior

  2. Saludos
    Tengo esta funcion
    sumagrupos = CALCULATE(SUM(pago[valor]);CROSSFILTER(pago[cod_rubro];rubro[cod_rubro];OneWay);CROSSFILTER(rubro[cod_rubro];grupos[cod_rubro];Both))

    Mi consulta es si se puede utlizar una funcion alternantiva que pueda simular el comportamiento del crossfilter con relacion Both debido a que mi Analyisis Services no soporta esta funcion

    Gracias

    1. Hola Marcelo, quizá viendo el modelo se me ocurriese alguna alternativa, pero como tal, he de reconocer que si la hay, la desconozco. Siento no ser de más ayuda.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *