![Waving :wave:](./images/smilies/icon_wave.gif)
Prendendo spunto da alcuni commenti ricevuti in merito ai tutorial mostrati, volevo portare un mio piccolo contributo in merito all'apprendimento di uno dei pilastri del linguaggio DAX: il contesto valutativo (evaluation context).
A sua volta esso può essere suddiviso in due parti: contesto riga (row context) e contesto filtro (filter context).
In questo breve tutorial andremo a parlare del primo elemento, senza la pretesa di entrare troppo nel merito poiché l'argomento in questione è complesso e pertanto è meglio proseguire per piccoli steps.
La prima domanda da porsi è la seguente: a cosa serve il contesto valutativo?
Il linguaggio DAX è un linguaggio funzionale, pertanto il codice che andremo a scrivere verrà inserito all'interno di un'unica funzione, la quale riporterà (se saremo bravi
![Mr. Green :mrgreen:](./images/smilies/icon_mrgreen.gif)
La stessa formula può portare a risultati diversi a seconda del contesto valutativo all'interno del quale essa viene valorizzata.
A questo punto è necessario chiedersi, ma cosa è il contesto riga? ed il contesto filtro?
Per ora limitiamoci a focalizzare la nostra attenzione su una regola fondamentale (cit. Marco Russo e Alberto Ferrari
![Clapping :clap:](./images/smilies/icon_clap.gif)
"Il contesto filtro, filtra, mentre il contesto riga, itera"
Ma cosa si intende per "iterare" ?
Prendiamo il seguente modello dati:
![Immagine](https://i.postimg.cc/x1y0XZ7C/001-Modello.png)
In PowerBi (o anche in PowerPivot), possiamo aggiungere dei campi calcolati (tramite DAX) direttamente dentro al nostro modello.
Proviamo ora a scrivere la seguente formula, premendo sul pulsante "Nuova Colonna" presente nel tab "Home" (all'interno del menu "Dati"):
Codice: Seleziona tutto
NewPrice = [PrezzoUni] * 1.1
Ma come ha fatto DAX a valutare in modo differente la stessa formula, se nessuno gli ha detto quale era il contesto valutativo all'interno del quale valorizzare l'espressione?
Ebbene, quando si crea una colonna calcolata, DAX genera in automatico un contesto riga, il quale itera la tabella corrente (in questo caso l'unica presente nel modello) e dunque va ad eseguire RIGA per RIGA l'espressione indicata.
In parole ancora più semplici:
Per valorizzare il valore del nuovo campo [NewPrice] in riga 1, ha utilizzato il valore [PrezzoUni] della riga 1 (4) e l'ha moltiplicato per 1.1
Per valorizzare il valore del nuovo campo [NewPrice] in riga 2, ha utilizzato il valore [PrezzoUni] della riga 2 (1) e l'ha moltiplicato per 1.1
e così via fino a raggiungere l'ultima riga della tabella.
Proviamo allora a scrivere una misura all'interno del nostro applicativo in Power BI, utilizzando la stessa formula vista nei passaggi precedenti.
Vedremo fin da subito che qualcosa non sta avvenendo nel modo corretto, infatti mentre prima, quando scrivevamo la formula appariva il suggerimento di completamento tramite intellisense, ora questo non avviene.
Inoltre se "forziamo" il sistema a scrivere comunque la formula e premiamo Invio il risultato ottenuto sarà il seguente:
![Immagine](https://i.postimg.cc/pdmFb8qR/002-Errore.png)
Non sempre i messaggi di errore sono esplicativi (specie quando vengono tradotti dall'inglese), però quello che otteniamo può in questo caso aiutarci, soprattutto se leggiamo le ultime parole:
non è presente alcuna riga corrente per questa colonna
La riga corrente è un concetto che si sposa bene con il contesto riga.
Il messaggio di errore dice che tale contesto manca, e pertanto l'espressione non può essere valorizzata poiché manca il contesto valutativo entro cui calcolarla.
Ecco una prima grande differenza tra le COLONNE CALCOLATE e le MISURE (argomento sempre molto gettonato tra gli utenti che chiedono quando utilizzare una o l'altra):
Le Colonne Calcolate hanno il contesto riga automatico, le Misure no!!!
L'unico modo per poter utilizzare all'interno delle misure il contesto riga è quello di richiamare una particolare tipologia di funzioni: le funzioni iterative (o iterators). Queste ultime, di norma, terminano con X, come ad esempio: SUMX - MAXX - AVERAGEX - ecc
Cosa fanno queste formule? Semplicemente utilizzano due argomenti:
1. Il riferimento alla tabella da iterare
2. L'espressione da iterare (e dunque da valorizzare riga per riga prima di poter essere aggregata)
Sull'ultimo punto vorrei chiarire meglio il concetto tramite un esempio:
Supponiamo di voler calcolare il totale delle vendite, inteso come prodotto delle quantità per il relativo prezzo.
In Excel potremmo essere portati a calcolare una colonna di appoggio che effettua l'operazione indicata. Il risultato finale sarebbe il medesimo (ottenuto con una colonna calcolata):
![Immagine](https://i.postimg.cc/NGXfhbtd/003-Vendite.png)
A questo punto non bisogna far altro che creare una misura che calcoli la somma di questa nuova colonna:
![Immagine](https://i.postimg.cc/44vkb0sR/004-Tot-Vendite.png)
Sul motivo per il quale la misura così calcolata riporta il valore corretto sarà spiegato meglio in un successivo tutorial.
Per il momento focalizziamoci sulle operazioni svolte fino ad ora:
.Abbiamo creato una colonna calcolata che RIGA per RIGA è andata a calcolare le quantità vendute
.Abbiamo sommato i valori contenuti in questa nuova colonna, ottenendo così il totale.
Ebbene, il tutto poteva essere risolto in un unico passaggio utilizzando le proprietà del contesto riga applicato internamente alle misure:
Codice: Seleziona tutto
TotVendite_RowContext = SUMX(Dati1,Dati1[Quantità] * Dati1[PrezzoUni])
![Immagine](https://i.postimg.cc/tTqqhGwJ/005-Misura.png)
Perché?
Semplicemente perché la misura così calcolata è in grado di generare un contesto riga sulla tabella che contiene i due campi da mettere in relazione. Pertanto essa creerà, solo momentaneamente, un nuovo campo contenente il valore dato dall'espressione. Quel valore così calcolato verrà poi aggregato tramite la formula SUM (quel campo calcolato in modo temporaneo non permane all'interno del modello e pertanto non lo appesantisce come invece fa la colonna calcolata).
Se fosse stata la stessa formula ma con AVERAGEX al posto di SUMX il valore temporaneamente ottenuto tramite l'espressione posta come secondo argomento sarebbe stata infine aggregata mediante la formula della media invece che della somma.
Per coloro abituati a lavorare con Excel lo stesso valore si sarebbe potuto ottenere mediante la formula MATR.SOMMA.PRODOTTO(), utilizzando come matrici la colonna Quantità e la colonna PrezzoUni.
Dunque, al termine di questo primo e breve tutorial sul tema del contesto riga ritengo sia necessario portarsi a casa i seguenti aspetti:
1) L'iterazione è un'operazione eseguita riga per riga all'interno di una tabella.
2) Il contesto riga è uno degli elementi del contesto valutativo (l'altro è il contesto filtro).
3) Un'espressione in DAX può essere valutata solamente all'interno di un contesto valutativo correttamente definito.
4) Il contesto riga è automatico all'interno delle colonne calcolate, non lo è all'interno delle misure.
5) Per inserire un contesto riga all'interno di una misura è necessario utilizzare una formula iterativa (SUMX() - AVERAGEX() - MAXX() - ecc)
Ovviamente non è tutto così semplice, in particolar modo quando andiamo ad utilizzare contesti riga riferiti a più tabelle presenti all'interno dello stesso modello dati, oppure quando inseriamo più contesti riga annidati all'interno della stessa espressione.
Pertanto seguiranno altri tutorial in merito a questo argomento, che ripetiamo essere uno dei pilastri che sorreggono l'intero linguaggio DAX.
Come sempre per eventuali commenti, suggerimenti, o integrazioni al tutorial è possibile scrivere un messaggio all'interno della sezione "segnala un problema" --> Qui
Colgo l'occasione per ringraziare tutti coloro che hanno deciso di dedicare parte del loro tempo alla lettura di questo tutorial.
A presto,
Andrea