Calcolo giacenza media annua rolling

Il software per la BI di Microsoft, leader nel mercato
Avatar utente

alex77
Messaggi: 160 | Topic creati
Iscritto il: sab 24 ott 2020, 23:04
Luogo: Treviso
Ringraziato: 11 volte

Calcolo giacenza media annua rolling

Messaggio da alex77 »

Buongiorno a tutti,
nel mio ormai celeberrimo (o famigerato) report sul magazzino vorrei calcolare la giacenza media annua rolling (in verità il valore, ma il problema della misura è evidentemente sulla quantità).
Il calcolo della giacenza lo faccio come somma dei movimenti, così:

Codice: Seleziona tutto

DAX.Giacenza = 
calculate(TOTALYTD(sum(fMovimenti[Qta]),dimCalendario[Data]), dimArticoli)
La media rolling ho provato così:

Codice: Seleziona tutto

DAX.Giacenza Media Annua = calculate('Misure DAX'[DAX.Giacenza]/distinctcout(dimcalendario[annomese]),
                                    DATESINPERIOD(dimCalendario[Data],max(dimCalendario[Data]),-12,MONTH))
Ma la misura non cumula la giacenza sui 12 mesi.

Grazie per un eventuale aiuto


Avatar utente

Autore del topic
alex77
Messaggi: 160 | Topic creati
Iscritto il: sab 24 ott 2020, 23:04
Luogo: Treviso
Ringraziato: 11 volte

Calcolo giacenza media annua rolling

Messaggio da alex77 »

Buongiorno a tutti,
mi autorispondo parzialmente, ma ho ancora un problema su cui spero qualcuno possa aiutarmi. Ho creato la misura seguente, che funziona, ma facendo il calcolo sul giorno, quando si tratta di utilizzarla all'interno della misura che calcola il valore, il tutto diventa troppo lento. Ho allora creato misura simile, che raggruppa per mese, ma non funziona e lo spiego dopo il codice...

Codice: Seleziona tutto

DAX.GMA PROVA1 giorno = 

VAR vMaxData = calculate(max(dimCalendario[data]),
                         filter(
                             values(dimCalendario[Data]),
                             dimCalendario[Data]<=TODAY())
                         )

VAR vTabMesi = CALCULATETABLE(values(dimCalendario[data]),DATESINPERIOD(dimCalendario[data],vmaxdata,-12,MONTH))

VAR vTabGiacenzaPeriodo = ADDCOLUMNS(vtabmesi,
                                   "@Giacenza",'Misure DAX'[DAX.Giacenza Modificata])

var vresult = averagex(vTabGiacenzaPeriodo,[@Giacenza])

return
vresult

Codice: Seleziona tutto

DAX.GMA PROVA1 mese = 

VAR vMaxData = calculate(max(dimCalendario[data]),
                         filter(
                             values(dimCalendario[Data]),
                             dimCalendario[Data]<=TODAY())
                         )

VAR vTabMesi = CALCULATETABLE(values(dimCalendario[AnnoMese]),DATESINPERIOD(dimCalendario[data],vmaxdata,-12,MONTH))

VAR vTabGiacenzaPeriodo = ADDCOLUMNS(vTabMesi,
                                   "@Giacenza",[DAX.Giacenza Modificata])

var vresult = averagex(vTabGiacenzaPeriodo,[@Giacenza])

return
vresult
La misura "per mese", quando si tratta di creare la tabella temporanea "vtabGiacenzaPeriodo", riporta il valore della giacenza solo sul mese corrente, lasciando vuote le altre (dico questo perchè la misura mi dà il valore esatto della giacenza del mese corrente, se faccio minx o maxx o sumx mi dà lo stesso valore... se conto le righe mi dà 12 che è corretto... ma vuol dire che 11 righe sono blank). E' come se nella misura per mese il filter context impedisse di scrivere negli 11 mesi precedenti la giacenza. Cosa che non succede con la misura per giorno. Qualcuno sa spiegarmi il perchè?

Grazie per l'eventuale aiuto
Avatar utente

Enrico Galli
Messaggi: 890 | Topic creati
Iscritto il: dom 28 giu 2020, 19:03
Luogo: San Giovanni in Persiceto (BO)
Ringraziato: 325 volte
Contatta:

Calcolo giacenza media annua rolling

Messaggio da Enrico Galli »

Ciao. La soluzione (non necessariamente semplice) è sicuramente nel codice della misura [DAX.Giacenza Modificata], puoi mostrarlo?
Enrico Galli
Link utili: I nostri tutorial | Come inserire: Immagini - Codice - Risolto
Se il forum ti è stato utile, considera di supportarlo con una libera donazione
Avatar utente

Autore del topic
alex77
Messaggi: 160 | Topic creati
Iscritto il: sab 24 ott 2020, 23:04
Luogo: Treviso
Ringraziato: 11 volte

Calcolo giacenza media annua rolling

Messaggio da alex77 »

Certo che sì! Mi viene da presumere, e un sospetto ce l'avevo, che dipenda dal fatto che il calcolo della giacenza lavori sulla colonna data (sto dicendo una cavolata?)
Questa è giacenza:

Codice: Seleziona tutto

DAX.Giacenza = 
TOTALYTD(sum(fMovimenti[Qta]),dimCalendario[Data])
e questa giacenza modificata:

Codice: Seleziona tutto

DAX.Giacenza Modificata = 

 var vGiacenzaNoDep = calculate('Misure DAX'[DAX.Giacenza],filter(all(dimDepositi),dimDepositi[Deposito Valorizzato]="S"))

var vGiacenzaDaValorizzare = calculate('Misure DAX'[DAX.Giacenza],dimDepositi[Deposito Valorizzato]="S")

var vResult = IF(vGiacenzaNoDep>0,vGiacenzaDaValorizzare)

return
vResult

Mara
Messaggi: 13 | Topic creati
Iscritto il: mar 7 giu 2022, 14:00
Ringraziato: 2 volte
Contatta:

Calcolo giacenza media annua rolling

Messaggio da Mara »

Ciao Alex, solo un consiglio prima di approfondire con il codice.
La colonna data è OK ?
Hai provato a crearti una tabella data sicuramente OK e collegarla al tuo data model ?
Spesso problemi simili (soprattutto sui rolling..) sono causati da data non corrette....
Ciao.
Buon lavoro con POWER BI
Avatar utente

Autore del topic
alex77
Messaggi: 160 | Topic creati
Iscritto il: sab 24 ott 2020, 23:04
Luogo: Treviso
Ringraziato: 11 volte

Calcolo giacenza media annua rolling

Messaggio da alex77 »

Ciao Mara
grazie per la risposta.
Al 99% direi che la tabella calendario è ok, nel senso che ho creato la lista di date con list.dates in power query e poi aggiunto le altre varie colonne (anno, mese,...). Visto quanto mi hai scritto mi sono anche premurato di contrassegnare la tabella come tabella data, cosa che di solito non faccio (se qualcuno vuole indicarmi vantaggi... ed eventuali svantaggi della cosa, ben venga). Ho appena controllato la profilatura delle colonne in power query e ho zero errori e zero campi vuoti.
Come potrei creare una tabella "sicuramente ok" (perchè mi pare ok già questa e non avrei molte altre strade per crearla :D )?

Grazie ancora
Avatar utente

Enrico Galli
Messaggi: 890 | Topic creati
Iscritto il: dom 28 giu 2020, 19:03
Luogo: San Giovanni in Persiceto (BO)
Ringraziato: 325 volte
Contatta:

Calcolo giacenza media annua rolling

Messaggio da Enrico Galli »

alex77 ha scritto: mar 7 giu 2022, 16:31 se qualcuno vuole indicarmi vantaggi... ed eventuali svantaggi della cosa, ben venga
https://www.sqlbi.com/articles/mark-as-date-table/
Enrico Galli
Link utili: I nostri tutorial | Come inserire: Immagini - Codice - Risolto
Se il forum ti è stato utile, considera di supportarlo con una libera donazione

Mara
Messaggi: 13 | Topic creati
Iscritto il: mar 7 giu 2022, 14:00
Ringraziato: 2 volte
Contatta:

Calcolo giacenza media annua rolling

Messaggio da Mara »

alex77 ha scritto: mar 7 giu 2022, 16:31
Come potrei creare una tabella "sicuramente ok" (perchè mi pare ok già questa e non avrei molte altre strade per crearla :D )?

Grazie ancora
Ciao Alex, hai diversi modi.
O usi la funzione CALENDARAUTO o usi questo script in PowerQuery:

let fnDateTable = (Inizio as date, Fine as date, Mese as number) as table =>
let
DayCount = Duration.Days(Duration.From(Fine - Inizio)),
Source = List.Dates(Inizio,DayCount,#duration(1,0,0,0)),
TableFromList = Table.FromList(Source, Splitter.SplitByNothing()),
ChangedType = Table.TransformColumnTypes(TableFromList,{{"Column1", type date}}),
RenamedColumns = Table.RenameColumns(ChangedType,{{"Column1", "Date"}}),
InsertYear = Table.AddColumn(RenamedColumns, "Year", each Date.Year([Date]),type text),
InsertYearNumber = Table.AddColumn(RenamedColumns, "YearNumber", each Date.Year([Date])),
InsertQuarter = Table.AddColumn(InsertYear, "QuarterOfYear", each Date.QuarterOfYear([Date])),
InsertMonth = Table.AddColumn(InsertQuarter, "MonthOfYear", each Date.Month([Date]), type text),
InsertDay = Table.AddColumn(InsertMonth, "DayOfMonth", each Date.Day([Date])),
InsertDayInt = Table.AddColumn(InsertDay, "DateInt", each [Year] * 10000 + [MonthOfYear] * 100 + [DayOfMonth]),
InsertMonthName = Table.AddColumn(InsertDayInt, "MonthName", each Date.ToText([Date], "MMMM"), type text),
InsertCalendarMonth = Table.AddColumn(InsertMonthName, "MonthInCalendar", each (try(Text.Range([MonthName],0,3)) otherwise [MonthName]) & " " & Number.ToText([Year])),
InsertCalendarQtr = Table.AddColumn(InsertCalendarMonth, "QuarterInCalendar", each "Q" & Number.ToText([QuarterOfYear]) & " " & Number.ToText([Year])),
InsertDayWeek = Table.AddColumn(InsertCalendarQtr, "DayInWeek", each Date.DayOfWeek([Date])),
InsertDayName = Table.AddColumn(InsertDayWeek, "DayOfWeekName", each Date.ToText([Date], "dddd"), type text),
InsertWeekEnding = Table.AddColumn(InsertDayName, "WeekEnding", each Date.EndOfWeek([Date]), type date),
InsertWeekNumber= Table.AddColumn(InsertWeekEnding, "Week Number", each Date.WeekOfYear([Date])),
InsertMonthnYear = Table.AddColumn(InsertWeekNumber,"MonthnYear", each [Year] * 10000 + [MonthOfYear] * 100),
InsertQuarternYear = Table.AddColumn(InsertMonthnYear,"QuarternYear", each [Year] * 10000 + [QuarterOfYear] * 100),
ChangedType1 = Table.TransformColumnTypes(InsertQuarternYear,{{"QuarternYear", Int64.Type},{"Week Number", Int64.Type},{"Year", type text},{"MonthnYear", Int64.Type}, {"DateInt", Int64.Type}, {"DayOfMonth", Int64.Type}, {"MonthOfYear", Int64.Type}, {"QuarterOfYear", Int64.Type}, {"MonthInCalendar", type text}, {"QuarterInCalendar", type text}, {"DayInWeek", Int64.Type}}),
InsertShortYear = Table.AddColumn(ChangedType1, "ShortYear", each Text.End(Text.From([Year]), 2), type text),
AddFY = Table.AddColumn(InsertShortYear, "FY", each "FY"&(if [MonthOfYear]>=Mese then Text.From(Number.From([ShortYear])+1) else [ShortYear]))
in
AddFY
in
fnDateTable




Se vuoi le istruzioni passo passo le trovi in questo tutorial:




Il mio consiglio è sempre quello di usare una tabella data come questa per evitare qualsiasi tipo di problema su funzioni di Time Intelligence.
Ciao.
Buona giornata e buon lavoro con POWER BI
Avatar utente

Autore del topic
alex77
Messaggi: 160 | Topic creati
Iscritto il: sab 24 ott 2020, 23:04
Luogo: Treviso
Ringraziato: 11 volte

Calcolo giacenza media annua rolling

Messaggio da alex77 »

Buongiorno Mara
grazie della risposta. Il metodo non è molto diverso da quello che uso io (anche se il tuo esempio è interessante per me, perchè usa le funzioni, a cui non sono ancora molto abituato).
Ho provato a sostituire il calendario con quello da te suggerito, ho segnato la tabella come tabella data, ma il risultato della misura "per mese" non cambia. A questo punto penso si possa mettere mano solo al codice.

Se qualcuno ha qualche idea... ben venga!

Grazie mille per l'aiuto.

A.
Avatar utente

Enrico Galli
Messaggi: 890 | Topic creati
Iscritto il: dom 28 giu 2020, 19:03
Luogo: San Giovanni in Persiceto (BO)
Ringraziato: 325 volte
Contatta:

Calcolo giacenza media annua rolling

Messaggio da Enrico Galli »

Ciao alex77 , al di là della specifica soluzione per cui non ho suggerimenti da dare, in futuro ti consiglio di prestare più attenzione alla formattazione del tuo codice per semplificarne la lettura e l'interpretazione. Vedo molti "errori", come anteporre al nome della misura quello della tabella che la contiene, un mix di maiuscole-minuscole, e soprattutto un'indentazione totalmente inadeguata. Per facilitarti le cose puoi usare DAX Formatter e ancora meglio scaricare il componente aggiuntivo BRAVO per Power BI, realizzato da SQLBI e che ti formatta correttamente le misure sul posto (tra le tante altre cose utili, come ad esempio generare un calendario).
Enrico Galli
Link utili: I nostri tutorial | Come inserire: Immagini - Codice - Risolto
Se il forum ti è stato utile, considera di supportarlo con una libera donazione
Rispondi