Pagina 1 di 1

Simbolo @ nel linguaggio M per ricorsività

Inviato: gio 26 gen 2023, 16:40
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.

Simbolo @ nel linguaggio M per ricorsività

Inviato: gio 26 gen 2023, 16:44
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

Simbolo @ nel linguaggio M per ricorsività

Inviato: ven 27 gen 2023, 1:27
da canapone
Ti ringrazio Andrea, alla prossima.

Simbolo @ nel linguaggio M per ricorsività

Inviato: ven 27 gen 2023, 6:47
da Andrea90
Se hai bisogno di impostare la formula fa sapere che ci proviamo a dare un’occhiata :thumbup:

Simbolo @ nel linguaggio M per ricorsività

Inviato: ven 27 gen 2023, 9:03
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

Simbolo @ nel linguaggio M per ricorsività

Inviato: sab 28 gen 2023, 14:04
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

Simbolo @ nel linguaggio M per ricorsività

Inviato: lun 30 gen 2023, 8:25
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

Simbolo @ nel linguaggio M per ricorsività

Inviato: lun 30 gen 2023, 14:17
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".

Simbolo @ nel linguaggio M per ricorsività

Inviato: mer 1 feb 2023, 9:15
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

Simbolo @ nel linguaggio M per ricorsività

Inviato: gio 2 feb 2023, 16:44
da canapone
Andrea ti ringrazio,

appena posso mi metto a studiare il procedimento.

A presto