Riprendiamo da dove avevamo lasciato l'ultima volta con il tutorial che trovate al seguente link: Qui
Avevamo accennato all'importanza del contesto valutativo, e di come quest'ultimo dipenda da due concetti fondamentali:
1) Row Context
2) Filter Context
Il row context è quell'elemento di un contesto valutativo che consente al DAX di sapere quale riga deve utilizzare (riferita ad un dato campo di una data tabella) durante l'esecuzione di un calcolo iterativo.
Inoltre il calcolo iterativo non risulta essere del tutto automatico. In particolare, è necessario ricordare che solamente il calcolo di una colonna calcolata è in grado di eseguire automaticamente il contesto riga (row context), al contrario, una misura necessità dell'utilizzo di una particolare tipologia di funzioni (chiamate per l'appunto iterative).
Inoltre il contesto riga, al contrario del contesto filtro, non si applica all'intero modello. Infatti, non si è in grado di svolgere in automatico il calcolo che segue:
Supponiamo di avere il seguente modello dati:
Molto banalmente la tabella "Vendite" contiene una lista di records con un campo che rappresenta il nome del prodotto [Prodotto] ed un campo che rappresenta le quantità vendute per ciascun prodotto [Quantità]. Essendo una tabella che registra semplicemente le quantità vendute nel tempo per singoli prodotti, può capitare che un prodotto venga ripetuto più volte.
La tabella "Prezzo" invece, contiene la lista dei soli prodotti univoci [Prodotto] con assegnati i singoli prezzi [Prezzo_Uni].
Le due tabelle possono essere pertanto messe in relazione tra loro da una relazione "1 a molti" dove il lato 1 è rappresentato dalla tabella "Prezzo", mentre il lato molti è rappresentato dalla tabella "Vendite".
Ora il nostro compito è di calcolare l'ammontare delle vendite. Possiamo agire in due modi:
1) Calcolare una colonna calcolata dentro la tabella "Vendite" così da creare una nuova colonna che contenga il prodotto tra la quantità venduta ed il relativo prezzo di vendita unitario. Questa colonna poi dovrà essere inserita all'interno di una misura, la quale ne effettuerà la somma.
2) Calcolare una misura che calcoli la somma iterativa di un'espressione, valutata all'interno di una tabella, tramite una formula SUMX().
La buona prassi prevede, in un caso come questo, l'utilizzo della seconda opzione.
Quello che però ci preme sottolineare è che indipendentemente dal metodo applicato, necessitiamo di un contesto riga che dica, quale riga devo valutare, di volta in volta, al fine di ottenere la corretta valorizzazione del venduto.
Dunque si potrebbe tentare l'approccio seguente:
Codice: Seleziona tutto
TotaleVendite = SUMX(Vendite,Vendite[Quantità] * Prezzo[Prezzo_Uni])
peccato che così facendo il sistema genererà un errore:
Il messaggio può risultare forviante. Quello che ci vuole trasmettere in realtà è che l'utente ha richiesto di iterare la tabella "Vendite" mediante la formula SUMX() la quale dovrebbe aggregare il risultato della seguente espressione: Vendite[Quantità] * Prezzo[Prezzo_Uni]
Il problema è che mentre per il valore del campo [Quantità] non vi sono problemi, poiché esso appartiene già alla tabella iterata e dunque il sistema è in grado di individuare la riga corrente dal quale estrapolare l'informazione del volume acquistato (riga per riga), per il campo [Prezzo_Uni] questo non è possibile.
Il motivo è rappresentato dal fatto che il contesto riga non si trasmette da una tabella ad un'altra. O almeno non in maniera automatica.
Per poter individuare il valore corretto del prezzo unitario, riferito alla riga che stiamo iterando, è necessario fare affidamento su altre due formule:
RELATED()
RELATEDTABLE()
L'utilizzo di una o dell'altra formula dipende dal tipo di relazione che lega la tabella iterata, con quella dalla quale si vuole cercare di recuperare i valori corrispondenti di un dato campo.
Nel nostro caso la tabella iterata è la tabella "Vendite" (lato molti), mentre la tabella "interrogata" è la tabella "Prezzo" (lato 1).
In questa situazione, visto che per ciascuna riga presente nella prima tabella, corrisponde un solo valore della seconda (ad un singolo prodotto della tabella "Vendite" corrisponderà solamente una riga della tabella "Prezzo") si utilizza la formula RELATED().
Pertanto la formula corretta risulterà essere la seguente:
Codice: Seleziona tutto
TotaleVendite = SUMX(Vendite,Vendite[Quantità] * RELATED(Prezzo[Prezzo_Uni]))
Vediamo ora un esempio di formula che utilizza RELATEDTABLE().
Quest'ultima viene richiamata quando la tabella che andremo ad iterare rappresenta il lato 1 della relazione.
Ad esempio, vogliamo aggiungere una colonna calcolata che vada a calcolare il numero di acquisti (nr°righe) presenti nella tabella "Vendite" per ciascun prodotto presente nella tabella "Prezzo".
Per farlo possiamo inserire in una nuova colonna calcolata la formula che segue:
Codice: Seleziona tutto
Nr_Acquisti = COUNTROWS(RELATEDTABLE(Vendite))
Ovviamente dovremo andare ad eseguire un'operazione in grado di riportare un valore scalare relativo alla tabella risultante.
Pertanto utilizziamo COUNTROWS() per contare il numero di righe di ciascuna tabella ottenuta mediante iterazione.
Terminiamo il tutorial ricordando il fatto che gli argomenti fino ad ora mostrati compongono solo una parte del vasto mondo rappresentato dal contesto valutativo. Pertanto è necessario partire per gradi al fine di comprendere appieno ogni singolo elemento.
Inoltre il contesto riga non è un argomento a sé stante, infatti egli risulta integrato all'interno della definizione di contesto valutativo, il quale a sua volta contiene anche il contesto filtro.
Pertanto il limitarsi a studiare solo uno di questi elementi porterebbe ad avere una visione parziale del vero potenziale di DAX.
Pertanto vi invitiamo ad approfondire tali aspetti ed a rimanere allineati con i tutorial che seguiranno, così da potersi costruire, col tempo, un bagaglio di nozioni tale per cui i calcoli che una volta sembravano complessi diventeranno "magicamente" comprensibili.
Come sempre per eventuali commenti, suggerimenti, o integrazioni al tutorial è possibile scrivere un messaggio all'interno della sezione "Feedback" --> 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