Aquí estoy de nuevo con la saga de post relativos a los iteradores. Esta vez os voy hablar de los contextos anidados con iteradores.

En el post de contexto fila y filtro (que si no lo habéis leído os dejo aquí el link) y el de la semana pasada que fue el primero de la saga de iteradores, vimos que DAX crea un contexto de fila cada vez que ejecuta una iteración o creamos una columna calculada.

Esta vez, voy a cambiar un poco la dinámica del post, ya que hemos visto la “teoría” de los iteradores y vamos directamente con la práctica, que es como mejor se aprende. Para ello nos vamos a nuestro modelo de Contoso de Power BI y vamos a crear una columna calculada en nuestra tabla de dimensión DimProduct en la que nos muestre un ranking de los productos más caros a los más económicos.

Para ello, escribimos la siguiente métrica:

 
 

Nota: La función EARLIER, según la web de Microsoft, devuelve el valor actual de la columna especificada en un paso de evaluación externo de la columna mencionada.

EARLIER es útil para los cálculos anidados en los que se quiere usar un determinado valor como entrada y generar cálculos basados en esa entrada. En Microsoft Excel, estos cálculos solo se pueden realizar dentro del contexto de la fila actual. Sin embargo, en DAX puede almacenar el valor de la entrada y luego hacer cálculos con los datos de toda la tabla.

EARLIER se usa principalmente en el contexto de columnas calculadas y su sintaxis es:

 
Donde:
 

Column es la columna o expresión que se resuelve en una columna

Number es un número positivo para el paso de evaluación externo.

El siguiente nivel de evaluación externo se representa mediante 1; dos niveles externos se representan mediante 2, y así sucesivamente.

Si se omite, el valor predeterminado es 1. 

  

Bien, volviendo a la métrica creada, esta nos ha creado la siguiente columna con el ranking correspondiente como podéis ver:

 


 
 

Ahora os lanzo una pregunta, ¿Cuántos contextos tenemos en la expresión? ¿Y de qué tipo son esos contextos? ¿1? ¿2? ¿5?

….

Como hemos visto, si yo creo una columna calculada, esta crea un contexto de fila ¿Hasta aquí se entiende? Bien, y si dentro de esa columna calculada hago uso de un iterador que también me crea un contexto de fila, ¿Cuántos contextos tengo? … La respuesta es 2. Tengo el contexto de fila que me ha generado la columna calculada y el contexto de fila que me ha generado el iterador. ¿Correcto?

Volviendo un poco a la función EARLIER, es una función especial que me permite acceder al valor de una columna en un contexto anterior al que me encuentro. Sabiendo esto, y que en la medida anterior hay dos contextos, ¿sabemos indicar cuál es el contexto más externo y el contexto más interno? Dicho de otra forma, de los dos contextos presentes, ¿cuál es el primero en aparecer? ¿El de la columna o el iterador? Cortocircuito mental ¿eh? :)

 
 

 Y ahora entra en juego la función EARLIER, que me permite obtener el valor del precio en el contexto de fuera en el que me encuentro que es el de la columna calculada:

 

 
 
 

¿Se entiende? Vamos a detallarlo un poco más, para ello ordenamos la tabla por el ranking de manera ascendente de tal forma que nos situemos en la fila número 1.


 
 
 
 

¿Cuál es el precio unitario para la primera fila? El valor es 3199.99 €. Y cuándo se ejecute el iterador, ¿cuál va a ser el valor del precio unitario? Depende, estamos recorriendo la tabla de productos por lo que irá variando por cada fila en la que pasa, desde la primera hasta última.

Es decir, lo que debo hacer es comparar el valor en el que estoy (3199.99€), que es el de la fila en el que estoy creando la columna calculada con el resto de valores.

Entonces, cuando estoy en el segundo iterador el valor del precio unitario va a equivaler a la fila que estoy recorriendo y me lo está comparando con el valor anterior. ¿Se entiende?

Lo que viene a ser lo mismo, si quiero comparar el valor de las filas que estoy recorriendo con el iterador con el valor de la fila en la que me encuentro en la columna calculada que es el contexto de fila 1, es cuando interviene EARLIER que me permite obtener ese valor, es decir, el valor del precio unitario en el que estoy.

Vamos a la expresión para analizarlo de otra forma:


 
 

En la medida anterior, tenemos una sintaxis muy similar a la vista hasta ahora con la diferencia de que no tenemos la función EARLIER y estamos creando una variable para quedarme con el valor de la fila en la que estoy iterando por la columna calculada. Me explico:

 

 
 

Se ejecuta la medida, lo primero que hacemos es entrar en la fila calculada y almacenamos ese valor en el variable PrecioUnitario del contexto de fila en el que me encuentro. (3199.99€):

 

 
 

Y ahora lo que realiza es el contaje de las filas de la tabla DimProduct que la engloba la función FILTER: 

 
 


 

Recorremos todas las filas, y comparamos el precio de todas las filas con el valor almacenado en la variable PrecioUnitario (3199.99 €), que es el valor de la fila en la que me encuentro de la columna calculada, y así sucesivamente hasta la última fila de la tabla.

Y con esto, es suficiente por hoy. Espero que haberme explicado y que os sea útil.


¡Nos vemos en los datos!