En algún momento u otro, cualquier desarrollador de Power BI debe escribir complejo Dax expresiones para analizar datos. Pero nadie te dice cómo hacerlo. ¿Cuál es el proceso para hacerlo? ¿Cuál es la mejor manera de hacerlo y cómo puede ser un proceso de desarrollo? Estas son las preguntas que responderé aquí.

Introducción

A veces a mis clientes me preguntan cómo se me ocurrió la solución para una medida específica en DAX. Mi respuesta es siempre que sigo un proceso específico para encontrar una solución.

A veces, el proceso no es sencillo, y debo desviarme o comenzar desde cero cuando veo que he tomado la dirección equivocada.

Pero el proceso de desarrollo es siempre el mismo:

1. Comprender los requisitos.

2. Defina las matemáticas para calcular el resultado.

3. Comprenda si la medida debe funcionar en algún o un escenario específico.

4. Comience con los resultados intermediarios y trabaje paso a paso hasta que comprenda completamente cómo debería funcionar y puedo entregar el resultado solicitado.

5. Calcule el resultado final.

El tercer paso es el más difícil.

A veces mi cliente me pide que calcule un resultado específico en un escenario particular. Pero después de que vuelva a preguntar, la respuesta es: sí, también la usaré en otros escenarios.

Por ejemplo, hace algún tiempo, un cliente me pidió que creara algunas medidas para un escenario específico en un informe. Tuve que hacerlo en vivo durante un taller con el equipo del cliente.

Días después de que entregué los resultados solicitados, me pidió que creara otro informe basado en el mismo modelo y lógica semántica que elaboramos durante el taller, pero para un escenario más flexible.

El primer conjunto de medidas fue diseñado para funcionar estrechamente con el primer escenario, por lo que no quería cambiarlas. Por lo tanto, creé un nuevo conjunto de medidas más genéricas.

Sí, este es el peor de los casos, pero es algo que puede suceder.

Este fue solo un ejemplo de lo importante que es tomar algún tiempo para comprender a fondo las necesidades y los posibles casos de uso futuros para las medidas solicitadas.

Paso 1: los requisitos

Para esta pieza, tomo una medida de mi artículo anterior para calcular la extrapolación lineal de mi recuento de clientes.

Los requisitos son:

  • Utilice la medida del conteo de clientes como medida de base.
  • El usuario puede seleccionar el año para analizar.
  • El usuario puede seleccionar cualquier otra dimensión en cualquier cortadora.
  • El usuario analizará el resultado con el tiempo por mes.
  • El recuento pasado de clientes debe tomarse como valores de entrada.
  • La tasa de crecimiento de YTD debe usarse como base para el resultado.
  • Según la tasa de crecimiento de YTD, el recuento de clientes debe extrapolarse hasta fin de año.
  • El recuento de clientes de YTD y la extrapolación deben mostrarse en el mismo gráfico de línea.

El resultado debería verse así para el año 2022:

Figura 1 – Resultado solicitado para la extrapolación lineal del recuento de clientes (figura del autor)

Ok, veamos cómo desarrollé esta medida.

Pero antes de hacerlo, debemos entender cuál es el contexto del filtro.

Si ya está familiarizado con él, puede omitir esta sección. O puede leerlo de todos modos para asegurarnos de que estamos al mismo nivel.

Interludio: el contexto del filtro

El contexto del filtro es el concepto central de DAX.

Al escribir medidas en un modelo semántico, ya sea en Power Biun modelo semántico de tela, o un modelo semántico de servicios de análisis, siempre debe comprender el contexto del filtro actual.

El contexto del filtro es:

La suma de todos los filtros que afectan el resultado de una expresión de DAX.

Mira la siguiente imagen:

Figura 2 – Pregúntese: ¿Cuál es el contexto de filtro de las celdas marcadas? (Figura del autor) ¿Puede explicar el contexto del filtro de las celdas marcadas?

Ahora, mira la siguiente imagen:

Figura 3: todos los filtros que afectan el contexto del filtro de las celdas marcadas (figura del autor)

Hay seis filtros que afectan el contexto de filtro de las celdas marcadas para las dos medidas «Ventas minoristas de suma» y «ventas minoristas AVG»:

  • La tienda «Tienda Contoso Paris»
  • La ciudad «París»
  • El nombre de clase «economía»
  • El mes de abril de 2024
  • El país «Francia»
  • El fabricante «Proseware Inc.»

Los primeros tres filtros provienen de lo visual. Podemos llamarlos «filtros internos». Controlan cómo puede expandirse la visual de matriz y cuántos detalles podemos ver.

Los otros filtros son «filtros externos», que provienen de las cortadoras o del panel de filtro en Power BI y son controlados por el usuario.

El poder de las medidas DAX radica en la posibilidad de extraer el valor del contexto del filtro y la capacidad de manipular el contexto del filtro.

Hacemos esto al escribir expresiones DAX: manipulamos el contexto del filtro.

Paso 2: resultados intermediarios

Ok, ahora estamos listos para ir.

Primero, no empiezo con la visual de línea, sino con una mesa o una visual matriz.

Esto se debe a que es más fácil ver el resultado como un número que como una línea.

Aunque una progresión lineal es visible solo como una línea.

Sin embargo, los resultados intermediarios son mejor legibles en una matriz.

Si no está familiarizado con trabajar con variables en DAX, le recomiendo leyendo esta piezadonde explico los conceptos de las variables:

El siguiente paso es definir la medida base. Esta es la medida que queremos usar para calcular el resultado previsto.

Como queremos calcular el resultado de YTD, podemos usar una medida YTD para el recuento de clientes:

Online Customer Count YTD =
VAR YTDDates = DATESYTD('Date'[Date])
RETURN
CALCULATE(
DISTINCTCOUNT('Online Sales'[CustomerKey])
,YTDDates
)

Ahora debemos considerar qué hacer con estos resultados intermediarios.

Esto significa que debemos definir la aritmética de la medida.

Para cada mes, debo calcular el último conteo de clientes conocido YTD.

Esto significa que siempre quiero calcular 2,091 para cada mes. Este es el último conteo de clientes de YTD para el año 2022.

Luego, quiero dividir este resultado en el último mes con las ventas, en este caso 6, para junio. Luego multiplíquelo por el número de mes actual.

Por lo tanto, el primer resultado intermediario es saber cuándo se realizó la última venta. Debemos obtener la última fecha en la tabla de ventas en línea para esto.

De acuerdo con los requisitos, el usuario puede seleccionar cualquier año para analizar, y el resultado debe calcularse mensualmente.

Por lo tanto, la definición correcta es: primero debo saber el mes en que se realizó la última venta para el año seleccionado.

La tabla de datos contiene una fecha y una relación con la tabla de fecha, que incluye el número de mes (columna: [Month]).

Entonces, la primera variable será algo como esto:

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = MAXX('Online Sales'

,RELATED('Date'[Month])
)

RETURN
LastMonthWithData

Este es el resultado:

Figura 4 – Obtenga el último mes con ventas (cifra del autor)

Espera: siempre debemos obtener el último mes con las ventas. Como es ahora, siempre tenemos el mismo mes que el mes de la fila actual.

Esto se debe a que cada fila tiene el contexto del filtro establecido cada mes.

Por lo tanto, debemos eliminar el filtro para el mes, mientras conservamos el año. Podemos hacer esto con ALLEXCEPT():

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = CALCULATE(MAXX('Online Sales'
,RELATED('Date'[Month])
)
,ALLEXCEPT('Date', 'Date'[Year])
)

RETURN
LastMonthWithData

Ahora, el resultado se ve mucho mejor:

Figura 5 – El mes pasado con ventas calculadas para todos los meses (cifra del autor)

A medida que calculamos el resultado para cada mes, debemos saber el número de mes de la fila actual (mes). Reutilizaremos esto como el factor para el cual multiplicamos el promedio para obtener la extrapolación lineal.

El siguiente resultado intermediario es obtener el número de mes:

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = CALCULATE(MAXX('Online Sales'
,RELATED('Date'[Month])
)
,ALLEXCEPT('Date', 'Date'[Year])
)
// Get the last month
// Is needed if we are looking at the data at the year, semester, or
quarter level
VAR MaxMonth = MAX('Date'[Month])
RETURN
MaxMonth

Puedo dejar la primera variable en su lugar y solo usar la variable MaxMonth después de la devolución. El resultado muestra el número de mes por mes:

Figura 6 – Obtenga el número de mes actual por fila (cifra del autor)

De acuerdo con la definición formulada anteriormente, debemos obtener el último recuento de clientes ytd para el último mes con ventas.

Puedo hacer esto con la siguiente expresión:

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = CALCULATE(MAXX('Online Sales'
,RELATED('Date'[Month])
)
,ALLEXCEPT('Date', 'Date'[Year])
)
// Get the last month
// Is needed if we are looking at the data at the year, semester, or
quarter level
VAR MaxMonth = MAX('Date'[Month])
// Get the Customer Count YTD
VAR LastCustomerCountYTD = CALCULATE([Online Customer Count YTD]
,ALLEXCEPT('Date', 'Date'[Year])
,'Date'[Month] = LastMonthWithData
)

RETURN
LastCustomerCountYTD

Como se esperaba, el resultado muestra 2.091 para cada mes:

Figura 7 – Calcular el último recuento de clientes YTD para cada mes (cifra del autor)

Puede ver por qué empiezo con una mesa o una matriz al desarrollar medidas complejas.

Ahora, imagine que un resultado intermediario es una fecha o un texto.

Mostrar tal resultado en una línea visual no será práctico.

Estamos listos para calcular el resultado final de acuerdo con la definición matemática anterior.

Paso 3: el resultado final

Tenemos dos formas de calcular el resultado:

1. Escribe la expresión después del RETURN declaración.

2. Cree una nueva variable «resultado» y use esta variable después de la declaración de retorno. La expresión final es esta:

(LastCustomerCountYTD / LastMonthWithData) * MaxMonth

La primera variante se ve así:

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = CALCULATE(MAXX('Online Sales'
,RELATED('Date'[Month])

)

,ALLEXCEPT('Date', 'Date'[Year])

)
// Get the last month
// Is needed if we are looking at the data at the year, semester, or
quarter level
VAR MaxMonth = MAX('Date'[Month])
// Get the Customer Count YTD
VAR LastCustomerCountYTD = CALCULATE([Online Customer Count YTD]
,ALLEXCEPT('Date', 'Date'[Year])
,'Date'[Month] = LastMonthWithData
)

RETURN
// Calculating the extrapolation
(LastCustomerCountYTD / LastMonthWithData) * MaxMonth

Esta es la segunda variante:

Linear extrapolation Customer Count YTD trend =
// Get the number of months since the start of the year
VAR LastMonthWithData = CALCULATE(MAXX('Online Sales'
,RELATED('Date'[Month])
)
,ALLEXCEPT('Date', 'Date'[Year])
)
// Get the last month
// Is needed if we are looking at the data at the year, semester, or
quarter level
VAR MaxMonth = MAX('Date'[Month])
// Get the Customer Count YTD
VAR LastCustomerCountYTD = CALCULATE([Online Customer Count YTD]
,ALLEXCEPT('Date', 'Date'[Year])
,'Date'[Month] = LastMonthWithData
)
// Calculating the extrapolation
VAR Result =
(LastCustomerCountYTD / LastMonthWithData) * MaxMonth
RETURN
Result

El resultado es el mismo.

La segunda variante nos permite volver rápidamente a los resultados intermediarios si el resultado final es incorrecto sin necesidad de establecer la expresión después de la RETURN declaración como comentario.

Simplemente facilita la vida.

Pero depende de ti qué variante te gusta más.

El resultado es este:

Figura 8 – Resultado final en una tabla (figura del autor)

Al convertir esta tabla en una línea visual, obtenemos el mismo resultado que en la primera figura. El último paso será establecer la línea como una línea discontinua, para obtener la visualización necesaria.

Figura 9 – Establezca la línea para la extrapolación como una línea discontinua (figura del autor)

Columnas calculadas complejas

El proceso es el mismo al escribir expresiones Dax complejas para columnas calculadas. La diferencia es que podemos ver el resultado en la vista de tabla del escritorio Power BI.

Tenga en cuenta que cuando se calculan las columnas calculadas, los resultados se almacenan físicamente en la tabla cuando presiona ENTER.

Los resultados de las medidas no se almacenan en el modelo. Se calculan sobre la mosca en las visualizaciones.

Otra diferencia es que podemos aprovechar la transición de contexto para obtener nuestro resultado cuando necesitamos que dependa de otras filas de la tabla.

Lea este artículo para obtener más información sobre este tema fascinante:

Conclusión

El proceso de desarrollo para expresiones complejas siempre sigue los mismos pasos:

1. Comprenda los requisitos: pregunte si algo no está claro.

2. Defina las matemáticas para los resultados.

3. Comience con los resultados intermediarios y comprenda los resultados.

4. Construya los resultados del intermediario uno por uno: no intente escribir todo en un solo paso.

5. Decide dónde escribir la expresión para el resultado final.

Seguir un proceso de este tipo puede ahorrarle el día, ya que no necesita escribir todo en un solo paso.

Además, obtener estos resultados intermediarios le permite comprender lo que está sucediendo y explorar el contexto del filtro.

Esto lo ayudará a aprender DAX de manera más eficiente y a construir cosas aún más complejas.

Pero, tenga en cuenta: aunque se necesita un cierto nivel de complejidad, un buen desarrollador lo mantendrá lo más simple posible, al tiempo que mantiene la menor cantidad de complejidad.

Referencias

Aquí es el artículo mencionado al comienzo de esta pieza, para calcular la interpolación lineal.

Como en mis artículos anteriores, uso el conjunto de datos de muestra Contoso. Puede descargar el conjunto de datos ContaSoretailDW gratis desde Microsoft aquí.

Los datos de Contoso se pueden usar libremente bajo la licencia MIT, como se describe aquí. Cambié el conjunto de datos para cambiar los datos a fechas contemporáneas.

Por automata