Formulas DAX de proyectos Power BI

1. Documentación Supply Chain Logistic Problem

Medida 1: Obtener el peso total de los productos

Para ello hacemos una suma simple con SUM a toda la columna de peso de la tabla principal. Se puede presentar en matriz con los productos respectivos o en una viñeta.

Peso de productos = SUM(OrderList[Weight])

Medida 2: Obtener el peso promedio por productos (o cualquier otra variable)

Utilizamos la función AVERAGE para sacar un promedio simple a través de la columna Weight de la tabla principal. Se puede presentar en matriz con los productos respectivos o en una viñeta.

Peso promedio = AVERAGE(OrderList[Weight])

Medida 3: Obtener el peso promedio de los productos guardado en un almacén (o cualquier otra variable)

La primera forma de utilizarlo es través de la función AVERAGEX y VALUES. Primero AVERAGEX recibe la tabla virtual por medio de la función VALUES que contine los productos diferentes por almacén (debido a un objeto visual matriz o tabla). Luego AVERAGEX recibe el parámetro, en este caso una medida existente de suma [Peso de pedidos] que se calcula para cada producto diferente de VALUES por almacén. Por último, AVERAGEX repite el proceso de calcula el promedio de la tabla virtual para cada almacén.

Peso promedio de los productos= 
  AVERAGEX(
      VALUES(products[Product]),
      [Peso de productos]
  )

Medida 4: Obtener el peso promedio de los productos guardado en un almacén con múltiples agrupaciones (o cualquier otra variable)

La segunda forma de obtener el peso promedio de los productos de un almacén es a través de SUMMARIZE. Para ello usamos AVERAGEX quien recibe una tabla virtual expandida creada con SUMMARIZE, que agrupará a través de suma los pesos de los productos con la medida de suma [Peso de pedidos] y se aplicará la agregación de promedio AVERAGEX por cada almacén del objeto visual matriz o tabla. A diferencia del anterior, con SUMMARIZE se puede agregar más variables de agrupación para sacar el promedio como, por ejemplo: país, día, año, tipo de servicio, etc.

Peso promedio de los productos = 
AVERAGEX(
    SUMMARIZE( #Tabla virtual agrupada
        OrderList,
        products[Product]
        ),
    [Peso de productos] # Medida por la que se agruparan
)

Medida 5: Calcular el peso porcentual de los productos por almacén

Paso 1: Calcular el peso absoluto. El peso total lo podemos obtener con la medida simple de suma [peso de productos] pero para calcular el total sin que afecten los filtros internos y por el cual se puedan dividir las filas relativas, será necesario utilizar ALLSELECTED y CALCULATE. ALLSELECTED ignora los filtros internos y deja solo los filtros externos para toda la tabla principal, de manera que se pueden hacer las sumas por cualquier segmentación externa del informe y calcular el total del peso de los productos.

Peso absoluto de productos = 
CALCULATE(
    [Peso de productos],
    ALLSELECTED(OrderList)
)

Paso 2: Calcular el porcentaje del peso. El porcentaje simplemente se calcula con la función DIVIDE a la cual se le pasa de numerador la medida [peso de productos] y como denominador [Peso absoluto de productos]. Luego se coloca en una matriz o tabla del informe.

Peso relativo porcentual (%) = 
DIVIDE(
    [Peso de productos],
    [Peso absoluto de productos]
)

Medida 6: Obtener el peso por planta de los productos con envío DPT

Para ello usamos la función CALCULATE que recibe una medida de suma [peso de productos] y un modificador de filtro en forma de tabla por medio de la columna service ID de la dimensión tipo de servicio. De ello obtenemos dos contextos de filtros, el primero viene de la matriz o tabla visual con los almacenes y el segundo filtro por la tabla de la segunda expresión de CALCULATE.

Peso de productos con envio DTP = 
CALCULATE(
    [Peso de pedidos], # Expresión a evaluar después del filtro
    typeService[service ID] = "DTP" # filtro en forma de tabla
)

Medida 7: Obtener el peso por planta de los productos con envío DPT y que sean de un consumidor especial (o cualquier otra variable)

Siempre usando CALCULATE podemos expresar una medida existente de suma [Peso de productos] y generar una tabla en forma de filtro con la función FILTER. Esto debido a que CALCULATE no puede tomar otro filtro directamente si es de una tabla distinta a la principal o a la que se está evaluando, de manera que creamos una tabla de filtro dentro de CALCULATE. Para ello usamos SUMMARIZE como primer argumento en FILTER con el agrupamiento de service ID de la dimensión tipo de servicio y custumerSpecial de la dimensión consumidores. Luego como segundo argumento de FILTER pasamos las condiciones a evaluar dentro de la tabla virtual creada. Finalmente se ejecuta el primer argumento de CALCULATE para hacer la suma de los pesos por planta de acuerdo al filtro de tabla creado con FILTER.

Peso de productos con envio DTP y consumidor especial = 
CALCULATE(
    [Peso de productos],
    FILTER(
        SUMMARIZE(
            OrderList,
            typeService[service ID],
            custumers[custumerSpecial]
        ),
        typeService[service ID] = "DTP" &&
        custumers[custumerSpecial] = "1"
    )
)

Medida 8: Número de productos con más de una orden por almacén

Podemos usar FILTER como filtro de tabla dentro de CALCULATE para obtener que productos tiene más de una orden por almacén. CALCULATE recibe un recuento de productos de la tabla principal [número de productos] y como segundo argumento recibe la tabla filtro creada por FILTER. FILTER recibe como primer argumento una tabla original de productos, como segundo argumento recibe las ordenes distintas, para eso se utiliza otro CALCULATE de manera que exista una transición de contexto y los productos se agreguen como filtro a la tabla principal. Por último, se ejecuta la función de recuento que calcula cuantos productos aparecen en más de una orden por cada planta.

Numero de productos > 1 orden = 
CALCULATE(
    [Numero de productos],
    FILTER(
        products,
        CALCULATE(DISTINCTCOUNT(OrderList[Order ID])) > 1
    )
)

Donde:
  
Numero de productos = DISTINCTCOUNT(OrderList[producto])

Medida 9: Contar cuántas ordenes tienen más de 500 unidades

Para ello podemos usar la función COUNTROWS y FILTER en una medida nueva, COUNTROWS ayudará a contar los valores obtenidos con la iteración de FILTER (tabla virtual), en un contexto de filtro del objeto visual elegido, en este caso una viñeta simple. El resultado será de 4,409 órdenes con más de 500 unidades de productos:

Ordenes con mas de 500 productos = 
COUNTROWS( # recibe tabla creada con FILTER y cuenta las filas
    FILTER(
        OrderList, # recibe una tabla original
        OrderList[Unit quantity] > 500 # aplica condición fila a fila
    )
)

2. Documentación Ventas y Proyecciones

Medida 1: Obtener el total de ingresos (o el total de otra variable)

Para ellos utilizamos una función de suma simple SUM con la tabla y la columna que queremos sumar.

Ingresos = sum(Ingresos[Ingreso Total reserva])

Medida 2: Obtener el número de hoteles totales (o el total de otra variable)

Usamos la función DISTINCTCOUNT con la tabla y columnas de donde queremos sacar los valores distintos.

Numero Hoteles = DISTINCTCOUNT( Ingresos[ID_Hotel]) # Cuenta los distintos de la tabla

Medida 3: Obtener el precio de venta promedio (o el promedio de otra variable)

Su usa el promedio simple con AVERAGE pasando como argumento la tabla y columna a la que le queremos sacar el promedio.

Precio Venta Promedio = 
  AVERAGE(Ingresos[Precio Promedio por habitación])

Medida 4: Cantidad de Reservas

Reservas = COUNTROWS(Ingresos) # Cantidad de filas de la tabla deseada

Medida 5: Obtener el total de clientes

Total Clientes = DISTINCTCOUNT(Ingresos[ID_Cliente]) # cuenta los distintos de la tabla y columna deseada

Medida 6: Obtener el total de huéspedes

Total Huespedes = sum(Ingresos[Total huesped]) # suma de una columna deseada

Medida 7: Obtener una tarjeta que diga el tipo de hotel seleccionado

Titulo Tipo Hotel = 
  "Tipo de Hotel: " & SELECTEDVALUE(Hoteles[Tipo Hotel])

Medida 8: Obtener el ingreso promedio por huesped

Gasto Promedio por huesped = 
  DIVIDE(
    [Ingresos], #Numerador
    [Total Huespedes] #denominador
         )

Medida 9: Obtener los ingresos del periodo pasado (last Date)

En este punto usamos CALCULATE. Pasamos como primer argumento el parámetro que es una medida existente de suma [ingresos] y como segundo argumento la SAMEPERIODLASTYEAR función que devuelve una tabla con fechas de un año atras desde el contexto de filtro actual. Es decir, si tenemos una matriz visual con fechas del año 2024 como contexto de filtro, la función SAMEPERIODLASTYEAR retornará una tabla con las mismas fechas pero del año 2023, el cual debido a CALCULATE, se transformarán en el nuevo contexto de filtro y procederá la suma por medio de la medida existente [Ingresos] de las fechas de ese año 2023.

Ingresos LY = 
CALCULATE(
    [Ingresos], # una medida existente de suma como parámetro
    SAMEPERIODLASTYEAR(Calendario[Date]) #Tabla con la fecha del año pasado
)

Medida 10: Variación de ingresos actuales vs ingresos pasados

Esta es una simple resta que se hace con las dos medidas calculadas, a los ingresos del año corriente (o la fecha actual) se le restan los ingresos del año pasado (o la fecha pasada). Es decir bajo la simple formula \((\Delta) = Y_{t} - Y_{t-1}\).

Variación = [Ingresos] - [Ingresos LY]

Medida 11: Variación porcentual de ingresos entre dos periodos

De igual forma esta es una simple división entre la medida de variación y los ingresos pasados. Es decir de la forma \((\Delta)~\% = \dfrac{(\Delta)}{Y_{t-1}}\).

var % ingresos = 
DIVIDE(
    [Variación],
    [Ingresos LY]
)

Medida 12: Realizar un segmentación visual que permita seleccionar un año deseado y un periodo comparativo dentro de ese año (sea semana, mes, trimestre, año) mostrando los indicadores en el informe con las fechas de ese periodo actual selecionado versus las fechas pasadas del mismo periodo, o en todo caso las variaciones entre esos periodos.

Paso 1: Encontrar fecha máxima seleccionada. Para ello hacemos uso de CALCULATE que retornará la última fecha registrada en la tabla ingresos completa, ignorando filtros internos y dejando únicamente filtros externos, es decir, filtros visuales debido a ALLSELECTED.

FechaMaxSeleccionada = 
 CALCULATE(
    MAX(Ingresos[Fecha Reserva]), #última fecha de la que se tiene registro
    ALLSELECTED(Ingresos) #Tabla completa ignorando filtros internos
)

Paso 2: encontrar la fecha mínima. Para ello primero cargamos una tabla simple con los periodos deseados en el filtro visual. En este caso queremos comparativos por semanas, meses y años, de manera que la tabla llamada periodo quedará de la siguiente forma:

##   Id Periodo
## 1  1      1S
## 2  2      1M
## 3  3      2M
## 4  4      3M
## 5  5      6M
## 6  6     12M

Por lo tanto primero debemos saber cuál es el periodo seleccionado, para ello agregamos una segmentación de datos, de manera que nos muestre el valor activo con la función SELECTEDVALUE, y guardamos en una variable llamada PeriodoSeleccionado. Luego guardamos en otra variable llamada FechaFin la medida de fecha máxima calculada previamente para obtener la última fecha del periodo seleccionado en la segmentación. Por último retornamos una condicional a través de SWITCH, que nos diga que periodo ha sido activado en la segmentación de datos, y de acuerdo a el filtrar el informe con sus datos actuales vs datos pasados.

FechaMinFiltrada = 
  
VAR PeriodoSeleccionado = SELECTEDVALUE(Periodos[Periodo])
VAR FechaFin = [FechaMaxSeleccionada]

RETURN

SWITCH(
    PeriodoSeleccionado,
    "1S", FechaFin - 6, #atrás 7 días en total incluyendo el día de fin.
    "1M", EOMONTH(FechaFin, -1), #atrás 1 mes desde última fecha actual
    "2M", EOMONTH(FechaFin, -2), #2 meses atrás desde última fecha actual
    "3M", EOMONTH(FechaFin, -3), #3 meses atrás
    "6M", EOMONTH(FechaFin, -6), #6 meses atrás
    "1A", EOMONTH(FechaFin, -12),#12 meses atrás
    MIN(Calendario[Date]) #Si no selecciona fecha actual
)

Medida 13: Calcular los ingresos filtrados por la medida anterior

Para ello hacemos uso de las fechas máximas y mínimas con las medidas ya calculadas, que servirán como modificador de CALCULATE a través de la función FILTER. De manera que los datos serán mostrados de acuerdo a la selección en la segmentación de datos, mostrando los datos actuales de la variable.

IngresosTotalesFiltrados = 
  
VAR FechaMinima = [FechaMinFiltrada] #fecha mínima del perido seleccionado
VAR FechaMaxima = [FechaMaxSeleccionada] #fecha máxima del periodo

RETURN

CALCULATE(
    [Ingresos], #medida a evaluar
    FILTER( #Tabla filtro
        Calendario, # tabla original por la que se filtrará
        Calendario[Date] >= FechaMinima && Calendario[Date] <= FechaMaxima #condición
    )
    
)

Medida 14: Calcular los ingresos pasados filtrados por la medida anterior

La lógica es la misma que la medida 13, la diferencia es que aquí usamos como parámetro de CALCULATE la medida 9 de los ingresos pasados [Ingresos LY]. De manera que ahora la segmentación de datos devolvera los valores pasados del mismo periodo seleccionado.

IngresosLYFiltrados = 
  
VAR FechaMinima = [FechaMinFiltrada] 
VAR FechaMaxima = [FechaMaxSeleccionada]

RETURN

CALCULATE(
    [IngresosLY], # suma totoal de ingresos pasados
    FILTER(
        Calendario,
        Calendario[Date] >= FechaMinima && Calendario[Date] <= FechaMaxima
    )
)

Medida 15: Obtener la variación real y porcentual de ingresos en periodos selecionados

La lógica de las medidas es la misma que las medidas 10 y 11, pero en este caso con los nuevos datos calculados y filtrados por los periodos deseados en la segmentación de datos.

variación real de ingresos:

Variación = 
[IngresosTotalesFiltrados] - [IngresosLYFiltrados]

Variación porcentual de ingresos:

CambioPorcentual = 
DIVIDE(
    [Variación],
    [IngresosLYFiltrados],
    0
)