Forum Discussion
Power Query / Power Pivot - stock calculation
- 7 years ago
If you're worried about performance, you can use this trick to substantially improve speed for a case like this: https://www.thebiccountant.com/2017/05/29/performance-tip-partition-tables-crossjoins-possible-powerquery-powerbi/
Your code would look like so:
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcnQytTBX0lEyMjC0BFKGRkAiJD8XSAaUFiVnJBangiUNlGJ18CkOTswBKTQ0xarOGJuhZtjNNMYwk7DlJfnJ2SAhMxxKTbDZb0pILdR+EySFFkSEFCHV8KDCrhBHWBFSjAgsgvYjhRZ2tTiCi5BiRHgBVcYCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [CMT = _t, Year = _t, Week = _t, Customer = _t, Transaction = _t, Value = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"CMT", type text}, {"Year", Int64.Type}, {"Week", Int64.Type}, {"Customer", type text}, {"Transaction", type text}, {"Value", Int64.Type}}), #"Pivoted Column" = Table.Pivot(#"Changed Type", List.Distinct(#"Changed Type"[Transaction]), "Transaction", "Value"), #"Added Custom1" = Table.AddColumn(#"Pivoted Column", "YearWeek", each [Year] * 100 + [Week], Int64.Type), #"Grouped Rows" = Table.Group(#"Added Custom1", {"CMT"}, {{"All", (Partition) => Table.AddColumn(Partition, "Custom", each List.Sum( Table.AddColumn( Table.SelectRows( Partition, let _earWeek = [YearWeek] in each [YearWeek] <= _earWeek ), "var", each [Sale]- [Purchase] )[var] )) }}), #"Expanded All" = Table.ExpandTableColumn(#"Grouped Rows", "All", {"Year", "Week", "Customer", "Purchase", "Sale", "Stock", "YearWeek", "Custom"}, {"Year", "Week", "Customer", "Purchase", "Sale", "Stock", "YearWeek", "Custom"}), #"Replaced Value" = Table.ReplaceValue(#"Expanded All", each [Stock], each [Stock] + [Custom],Replacer.ReplaceValue,{"Stock"}), #"Filled Down" = Table.FillDown(#"Replaced Value",{"Stock"}), #"Changed Type1" = Table.TransformColumnTypes(#"Filled Down",{{"Stock", Int64.Type}}), #"Replaced Value1" = Table.ReplaceValue(#"Changed Type1",each [Stock], each [Stock] - [Custom],Replacer.ReplaceValue,{"Stock"}), #"Changed Type2" = Table.TransformColumnTypes(#"Replaced Value1",{{"Stock", Int64.Type}}), #"Removed Other Columns" = Table.SelectColumns(#"Changed Type2",{"CMT", "Year", "Week", "Customer", "Purchase", "Sale", "Stock"}) in #"Removed Other Columns"You'll find some more performance tricks here: https://www.thebiccountant.com/speedperformance-aspects/
- 7 years ago
Hi nexami ,
if you want to learn how to integrate M code into your own solution, this video might help: https://community.powerbi.com/t5/Webinars-and-Video-Gallery/Power-BI-Forum-Help-How-to-integrate-M-code-into-your-existing/m-p/179314
Hi Mariusz look at the provided screenshot, stock is calculated on weekly basis.
also not 12/ 13 / 14 / 15 are week numbers (just to avoid confusion).
Hi nexami
Please see the below output based on the original data sample provided.
Please see the below M expression I used to Pivot the data on transaction column and later creatred a running total for Purchase - sales to be deducted of the stock value for every line.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcnQytTBX0lEyMjC0BFKGRkAiJD8XSAaUFiVnJBangiUNlGJ18CkOTswBKTQ0xarOGJuhZtjNNMYwk7DlJfnJ2SAhMxxKTbDZb0pILdR+E5DCWAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [CMT = _t, Year = _t, Week = _t, Customer = _t, Transaction = _t, Value = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"CMT", type text}, {"Year", Int64.Type}, {"Week", Int64.Type}, {"Customer", type text}, {"Transaction", type text}, {"Value", Int64.Type}}),
#"Pivoted Column" = Table.Pivot(#"Changed Type", List.Distinct(#"Changed Type"[Transaction]), "Transaction", "Value"),
#"Added Custom1" = Table.AddColumn(#"Pivoted Column", "YearWeek", each [Year] * 100 + [Week], Int64.Type),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom", each List.Sum(
Table.AddColumn(
Table.SelectRows(
#"Added Custom1", let _cmt = [CMT], _earWeek = [YearWeek] in each [CMT] = _cmt and [YearWeek] <= _earWeek
),
"var", each [Sale]- [Purchase]
)[var]
)),
#"Replaced Value" = Table.ReplaceValue(#"Added Custom2", each [Stock], each [Stock] + [Custom],Replacer.ReplaceValue,{"Stock"}),
#"Filled Down" = Table.FillDown(#"Replaced Value",{"Stock"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Filled Down",{{"Stock", Int64.Type}}),
#"Replaced Value1" = Table.ReplaceValue(#"Changed Type1",each [Stock], each [Stock] - [Custom],Replacer.ReplaceValue,{"Stock"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Replaced Value1",{{"Stock", Int64.Type}}),
#"Removed Other Columns" = Table.SelectColumns(#"Changed Type2",{"CMT", "Year", "Week", "Customer", "Purchase", "Sale", "Stock"})
in
#"Removed Other Columns"Sales and purchase will be normal sum aggregation where Last Stock is as below.
Last Stock =
VAR _maxMonth = MAX( test[Week] )
VAR _maxYear = MAX( test[Year] )
RETURN
CALCULATE(
SUM( test[Stock] ),
test[Week] = _maxMonth &&
test[Year] = _maxYear
)Due to complicated M expression and the size of your data this will perform rather slow.
Mariusz
If this post helps, then please consider Accepting it as the solution.
Please feel free to connect with me.

- ImkeF7 years agoCommunity Champion
If you're worried about performance, you can use this trick to substantially improve speed for a case like this: https://www.thebiccountant.com/2017/05/29/performance-tip-partition-tables-crossjoins-possible-powerquery-powerbi/
Your code would look like so:
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcnQytTBX0lEyMjC0BFKGRkAiJD8XSAaUFiVnJBangiUNlGJ18CkOTswBKTQ0xarOGJuhZtjNNMYwk7DlJfnJ2SAhMxxKTbDZb0pILdR+EySFFkSEFCHV8KDCrhBHWBFSjAgsgvYjhRZ2tTiCi5BiRHgBVcYCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [CMT = _t, Year = _t, Week = _t, Customer = _t, Transaction = _t, Value = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"CMT", type text}, {"Year", Int64.Type}, {"Week", Int64.Type}, {"Customer", type text}, {"Transaction", type text}, {"Value", Int64.Type}}), #"Pivoted Column" = Table.Pivot(#"Changed Type", List.Distinct(#"Changed Type"[Transaction]), "Transaction", "Value"), #"Added Custom1" = Table.AddColumn(#"Pivoted Column", "YearWeek", each [Year] * 100 + [Week], Int64.Type), #"Grouped Rows" = Table.Group(#"Added Custom1", {"CMT"}, {{"All", (Partition) => Table.AddColumn(Partition, "Custom", each List.Sum( Table.AddColumn( Table.SelectRows( Partition, let _earWeek = [YearWeek] in each [YearWeek] <= _earWeek ), "var", each [Sale]- [Purchase] )[var] )) }}), #"Expanded All" = Table.ExpandTableColumn(#"Grouped Rows", "All", {"Year", "Week", "Customer", "Purchase", "Sale", "Stock", "YearWeek", "Custom"}, {"Year", "Week", "Customer", "Purchase", "Sale", "Stock", "YearWeek", "Custom"}), #"Replaced Value" = Table.ReplaceValue(#"Expanded All", each [Stock], each [Stock] + [Custom],Replacer.ReplaceValue,{"Stock"}), #"Filled Down" = Table.FillDown(#"Replaced Value",{"Stock"}), #"Changed Type1" = Table.TransformColumnTypes(#"Filled Down",{{"Stock", Int64.Type}}), #"Replaced Value1" = Table.ReplaceValue(#"Changed Type1",each [Stock], each [Stock] - [Custom],Replacer.ReplaceValue,{"Stock"}), #"Changed Type2" = Table.TransformColumnTypes(#"Replaced Value1",{{"Stock", Int64.Type}}), #"Removed Other Columns" = Table.SelectColumns(#"Changed Type2",{"CMT", "Year", "Week", "Customer", "Purchase", "Sale", "Stock"}) in #"Removed Other Columns"You'll find some more performance tricks here: https://www.thebiccountant.com/speedperformance-aspects/
- Mariusz7 years agoCommunity Champion
Hi nexami
Please see the below link.https://drive.google.com/file/d/11VxbtLymDOKLOeEyfdBYfXhlgVWAxLIJ/view?usp=sharing
- ImkeF7 years agoCommunity Champion
Hi nexami ,
if you want to learn how to integrate M code into your own solution, this video might help: https://community.powerbi.com/t5/Webinars-and-Video-Gallery/Power-BI-Forum-Help-How-to-integrate-M-code-into-your-existing/m-p/179314
- nexami7 years agoHelper ILooks amazing, I'll apply the codes and will share results
- nexami7 years agoHelper IGot it.. Its perfect
Now tell me how to connect this code with the actual database of 300k records - nexami7 years agoHelper I
ImkeF moving on to the next level of my main quesiton.
i've a large database of around 300k records, and it keeps on adding up with purchases, sales, customers, etc.
so with the existing database, how am i suppose to integrate the MCODE. i can call up the database location from the Power Query, what i'm confused with is how does the MCODE provided by Mariusz will work with that specific databse.
- nexami7 years agoHelper I
here's something i just tried, using the MCODE, infact i dind't touched the MCODE at all :)
what i did is manually increased the number of records with different CMT / Customer Name / Sale and Purchase numbers.
and upon refreshing the query, i had the surprised results :)
- nexami7 years agoHelper IMariusz your provided codes are working fine except one glitch. Stock is only calculated on the basis of Week column and it does not function if other filters are applied. For example CMT or Customer.
Adding more, it should also work when year, month, quarter filters are applied.
Can you please modify the code and share - nexami7 years agoHelper I
- nexami7 years agoHelper I
M code.
see int he screenshots above, where i've increased the purchases / sales in each row, but after refreshing the query page, nothing happening.
- nexami7 years agoHelper I
SKU Transaction Week13 Week14 Week15
AB504 Purchase 200 60 50
AB504 Sales 15 100 450
AB504 Stock 1600 ???? ????