Simbolo @ nel linguaggio M per ricorsività

Non è propriamente un programma di BI, ma nelle sue versioni più recenti anche Excel può fare grandi cose!

Moderatore: Utilizzo_prof_Excel

Rispondi
Avatar utente

canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Buonasera a tutti

nel mio cercare di scimmiottare la tecnica descritta in questo contributo per simulare un calcolo First In First Out



mi sono imbattuto per la prima volta nell'uso di "@" in una stringa di linguaggio M al minuto 8:45 del filmato.

=List.Sum(Table.SelectRows(@QtySold, (x)=>x[Sku]=[Sku] and x[Expiration]<[Date])[QtySold])


Qualcuno sa se questo simbolo sia utilizzabile esclusivamente su PowerBi; uso Power Query su Excel 2019 ed il simbolo sembra non essere riconosciuto.

Facile che abbia preso una cantonata.


Avatar utente

Andrea90
Messaggi: 2193 | Topic creati
Iscritto il: dom 28 giu 2020, 19:41
Luogo: Bologna
Ringraziato: 666 volte
Contatta:

Simbolo @ nel linguaggio M per ricorsività

Messaggio da Andrea90 »

canapone,

Quello che menzioni è linguaggio "M" ed è presente in PowerQuery sia in Excel che in Power BI.

Per quel che riguarda il simbolo "@" è una notazione che viene utilizzata per rendere il calcolo ricorsivo, ad esempio viene utilizzata per richiamare la stessa funzione dentro se stessa.

Andrea
Se hai gradito l'aiuto che hai ricevuto considera di contribuire alle spese per il mantenimento del forum facendo una libera DONAZIONE --> Link

Ricordarsi di segnare come "RISOLTE" le discussioni per le quali si è ricevuto un feedback positivo. Per vedere come fare --> Link
Avatar utente

Autore del topic
canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Ti ringrazio Andrea, alla prossima.
Avatar utente

Andrea90
Messaggi: 2193 | Topic creati
Iscritto il: dom 28 giu 2020, 19:41
Luogo: Bologna
Ringraziato: 666 volte
Contatta:

Simbolo @ nel linguaggio M per ricorsività

Messaggio da Andrea90 »

Se hai bisogno di impostare la formula fa sapere che ci proviamo a dare un’occhiata :thumbup:
Se hai gradito l'aiuto che hai ricevuto considera di contribuire alle spese per il mantenimento del forum facendo una libera DONAZIONE --> Link

Ricordarsi di segnare come "RISOLTE" le discussioni per le quali si è ricevuto un feedback positivo. Per vedere come fare --> Link
Avatar utente

Autore del topic
canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Grazie Andrea, mi devo chiarire diversi passaggi.
Sto cercando di portare interamente su Power Query un ragionamento per il calcolo dei fondi svalutazione di magazzino.
Al momento -siamo in chiusura di bilancio/i- sono veramente stupito di come Excel e Power Query possano interagire così efficientemente.
Ti tengo presente e continuo a leggere i tuoi contributi e quelli di Enrico.
Saluti da Firenze
Avatar utente

Autore del topic
canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Ciao a tutti

ho "sbobinato" dal contributo su youtube il linguaggio M

Questa è la query Fifo_simplex

Codice: Seleziona tutto

let
    Origine = Excel.CurrentWorkbook(){[Name="Inventory"]}[Content],
    #"Modificato tipo" = Table.TransformColumnTypes(Origine,{{"Date", type date}, {"QtyPurchased", Int64.Type}, {"Unit Cost", type number}}),
    QtySold = Table.AddColumn(#"Modificato tipo", "QtySold", each List.Min({[QtyPurchased]}&{List.Sum(Table.SelectRows(Sales,(x)=>x[ProductID]=[ProductID])[QtySold]) - List.Sum(Table.SelectRows(@QtySold, (x)=> x[ProductID]=[ProductID] and x[Date]<[Date])[QtySold])})),
    COGS = Table.AddColumn(QtySold, "COGS", each [QtySold]*[Unit Cost])
in
    COGS
La Fifo_Complex

Codice: Seleziona tutto

let
    Origine = Table.Combine({Inventory, Sales}),
    #"Replaced Value" = Table.ReplaceValue(Origine,null,0,Replacer.ReplaceValue,{"QtyPurchased", "Unit Cost", "QtySold"}),
    QtySoldTiming = Table.AddColumn(#"Replaced Value", "QtySoldTiming", each List.Min({List.Sum(Table.SelectRows(#"Replaced Value", (x)=>x[ProductID]=[ProductID] and x[Date]<=[Date])[QtyPurchased])}

 & {List.Sum(Table.SelectRows(#"Replaced Value", (x)=>x[ProductID]=[ProductID] and x[Date]<=[Date])[QtySold])}) -  List.Sum(List.InsertRange(Table.SelectRows(@QtySoldTiming, (x)=> x[ProductID]=[ProductID] and x[Date]<[Date])[QtySoldTiming],0,{0}))),
    CumQtyBal = Table.AddColumn(QtySoldTiming, "CumQtyBal", each ([QtyPurchased]-[QtySoldTiming]) + (try Table.Max(Table.SelectRows(@CumQtyBal, (x)=> x[ProductID]=[ProductID] and x[Date]<[Date]),"Date")[CumQtyBal] otherwise 0)),
    COGS = Table.AddColumn(CumQtyBal, "COGS", each if [QtyPurchased] >0 and [QtySoldTiming]>0 then ( [QtyPurchased]-[CumQtyBal]) * [Unit Cost]  else if [QtySold]>0 and [QtySoldTiming]>0 then List.Sum(Table.SelectRows(Table.AddColumn(CumQtyBal,"CumBal", each ([QtyPurchased] -[QtySoldTiming])*[Unit Cost]), (x)=> x[ProductID]=[ProductID] and x[Date]<[Date])[CumBal])-([CumQtyBal]) * Table.Max(Table.SelectRows(@COGS, (x)=> x[ProductID]=[ProductID] and x[Date]<[Date]),"Date")[Unit Cost] else 0)
in
    COGS
Allego anche il file

Se servisse a qualcuno
Allegati
XXX MODELLO.xlsx
(31.78 KiB) Scaricato 5 volte
Avatar utente

Andrea90
Messaggi: 2193 | Topic creati
Iscritto il: dom 28 giu 2020, 19:41
Luogo: Bologna
Ringraziato: 666 volte
Contatta:

Simbolo @ nel linguaggio M per ricorsività

Messaggio da Andrea90 »

canapone,

Ho provato a dare un'occhiata al file, partendo dalla query "FIFO_simple", e sinceramente non mi è molto chiara la logica che vorresti applicare.

Ad esempio il codice prodotto ID = 67, è presente in entrambe le tabelle di "Inventory" e "Sales".

In Inventory è presente al 03/11/2020 con qyt = 10, mentre in Sales è presente al 07/06/2020 e poi al 04/08/2022, in entrambi i casi con QtySold = 2.

Nella query "FIFO_simple" compare una sola volta, con data al 03/11/2020 (visto che la source di questa query è la tabella Inventory) e poi hai come QtySold = 10.

Quale sarebbe la logica che giustifica quel valore di QtySold?

Andrea
Se hai gradito l'aiuto che hai ricevuto considera di contribuire alle spese per il mantenimento del forum facendo una libera DONAZIONE --> Link

Ricordarsi di segnare come "RISOLTE" le discussioni per le quali si è ricevuto un feedback positivo. Per vedere come fare --> Link
Avatar utente

Autore del topic
canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Ciao Andrea,
ho pubblicato la sbobinatura solo per chi -come me- volesse cercare di capire questo tipo di formule.
Io ci ho perso gli occhi a riportarle in maniera passiva sul mio foglio di calcolo.
Sono ancora molto lontano dal capire la logica di diversi passaggi: ne sono rimasto comunque "affascinato".
Avatar utente

Andrea90
Messaggi: 2193 | Topic creati
Iscritto il: dom 28 giu 2020, 19:41
Luogo: Bologna
Ringraziato: 666 volte
Contatta:

Simbolo @ nel linguaggio M per ricorsività

Messaggio da Andrea90 »

canapone,

Ok, la mia era una domanda che riguardava a priori la logica che volevi utilizzare, indipendentemente dal fatto che il video che hai guardato fosse corretto oppure no. In questo modo avrei potuto magari cercare delle vie alternative per raggiungere il risultato desiderato.

Comunque, non ho guardato il video, ma la formula che utilizzi credo non sia corretta.
Consiglio sempre di formattare le formule complesse in modo adeguato:

Codice: Seleziona tutto

QtySold = 
	Table.AddColumn(
		#"Modificato tipo", 
		"QtySold", 
		each 
			List.Min(
				{[QtyPurchased]} & 
				{ List.Sum(
					Table.SelectRows(
						Sales,
						(x)=> x[ProductID]=[ProductID]
						)[QtySold]
					) - 
				  List.Sum(
					Table.SelectRows(
						@QtySold, 
						(x)=> x[ProductID]=[ProductID] and x[Date]<[Date]
						)[QtySold]
					)
				}
				)
		),
La seconda parte di questa formula, per intenderci quella che riporta il Table.SelectRows(@QtySold, ...) riporterà sempre errore, dunque come risultato di List.Min avrai sempre e solo il minimo tra QtyPurchased e il valore del minuendo.

Provo ad allegarti un file dove ho cercato di calcolare il COGS (con il metodo FIFO) sulla base dei valori di due tabelle distinte "Purchase" e "Sales", magari potrà tornarti utile.

Andrea
Allegati
FIFO_Example.xlsx
(20.9 KiB) Scaricato 8 volte
Se hai gradito l'aiuto che hai ricevuto considera di contribuire alle spese per il mantenimento del forum facendo una libera DONAZIONE --> Link

Ricordarsi di segnare come "RISOLTE" le discussioni per le quali si è ricevuto un feedback positivo. Per vedere come fare --> Link
Avatar utente

Autore del topic
canapone
Messaggi: 11 | Topic creati
Iscritto il: mer 15 lug 2020, 16:13
Ringraziato: 1 volta

Simbolo @ nel linguaggio M per ricorsività

Messaggio da canapone »

Andrea ti ringrazio,

appena posso mi metto a studiare il procedimento.

A presto
Rispondi