Forum Discussion
Calculations in Custom Column with LOOKUP and IF
- 8 years ago
Another way, using the same sample data, is to use the TOPN function:
ProjectCost2 = CALCULATE(MAX(Costs[Cost]), TOPN(1, FILTER(Costs,Costs[Category] = Projects[Category] && Costs[Date] <= Projects[Start]), Costs[Date])) - 8 years ago
Of course. Bare with me though as this may appear a little more complex. I could post just the "M" code (you can see it below) but I assume it to be more helpful to lead you through the steps in the GUI to get there. Apply these steps:
1. Use Get Data to load your Projects and Costs tables and edit in Power Query. Select the Projects table.
2. Select Merge Queries. Select the Category table from Projects, select the Costs table in the dropdown, select the Category column in the Costs table and select an Inner Join in the drop down. Click OK.
3. Expand the resulting tables in the Costs column in the result by clicking the icon to the right in the Costs column header.
4. Now we need to only keep rows where Costs.Date is equal or earlier than Start date. Create a new custom column named Keep defined as [Costs.Date] <= [Start]. Click the filter button in the Keep header and unselect FALSE.
5. Click Group By under transform. Click Advanced. Select ID as your Group By column. Enter CostDate as your New column name, select Max as you operation and select Costs.Date as Column. Click Add aggregation to get a new row. Enter Start, Max, Start for the fields. Click Add aggregation again. Enter Category, Max, Category. Click Add aggregation again. Enter ProjectCost, MAX, Costs.Cost. Repeat this as necessary if you have other columns you need to have in your result. Click OK.
Done. You can now remove/reorder/rename columns as appropriate. If you click Advanced Editor you can see the resulting "M" code, it should look something like this:
let Source = Excel.Workbook(File.Contents("D:\OneDrive\file.xlsx"), null, true), Projects_Sheet = Source{[Item="Projects",Kind="Sheet"]}[Data], #"Promoted Headers" = Table.PromoteHeaders(Projects_Sheet, [PromoteAllScalars=true]), #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ID", type text}, {"Start", type date}, {"Category", type text}, {"Sum", Int64.Type}}), #"Merged Queries" = Table.NestedJoin(#"Changed Type",{"Category"},Costs,{"Category"},"Costs",JoinKind.Inner), #"Expanded Costs" = Table.ExpandTableColumn(#"Merged Queries", "Costs", {"Category", "Date", "Cost"}, {"Costs.Category", "Costs.Date", "Costs.Cost"}), #"Added Custom" = Table.AddColumn(#"Expanded Costs", "Keep", each [Costs.Date] <= [Start]), #"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([Keep] = true)), #"Grouped Rows" = Table.Group(#"Filtered Rows", {"ID"}, {{"CostDate", each List.Max([Costs.Date]), type date}, {"Start", each List.Max([Start]), type date}, {"Category", each List.Max([Category]), type text}, {"ProjectCost", each List.Max([Costs.Cost]), type number}}) in #"Grouped Rows"Good luck, let me know if you run into issues.
Of course. Bare with me though as this may appear a little more complex. I could post just the "M" code (you can see it below) but I assume it to be more helpful to lead you through the steps in the GUI to get there. Apply these steps:
1. Use Get Data to load your Projects and Costs tables and edit in Power Query. Select the Projects table.
2. Select Merge Queries. Select the Category table from Projects, select the Costs table in the dropdown, select the Category column in the Costs table and select an Inner Join in the drop down. Click OK.
3. Expand the resulting tables in the Costs column in the result by clicking the icon to the right in the Costs column header.
4. Now we need to only keep rows where Costs.Date is equal or earlier than Start date. Create a new custom column named Keep defined as [Costs.Date] <= [Start]. Click the filter button in the Keep header and unselect FALSE.
5. Click Group By under transform. Click Advanced. Select ID as your Group By column. Enter CostDate as your New column name, select Max as you operation and select Costs.Date as Column. Click Add aggregation to get a new row. Enter Start, Max, Start for the fields. Click Add aggregation again. Enter Category, Max, Category. Click Add aggregation again. Enter ProjectCost, MAX, Costs.Cost. Repeat this as necessary if you have other columns you need to have in your result. Click OK.
Done. You can now remove/reorder/rename columns as appropriate. If you click Advanced Editor you can see the resulting "M" code, it should look something like this:
let
Source = Excel.Workbook(File.Contents("D:\OneDrive\file.xlsx"), null, true),
Projects_Sheet = Source{[Item="Projects",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Projects_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ID", type text}, {"Start", type date}, {"Category", type text}, {"Sum", Int64.Type}}),
#"Merged Queries" = Table.NestedJoin(#"Changed Type",{"Category"},Costs,{"Category"},"Costs",JoinKind.Inner),
#"Expanded Costs" = Table.ExpandTableColumn(#"Merged Queries", "Costs", {"Category", "Date", "Cost"}, {"Costs.Category", "Costs.Date", "Costs.Cost"}),
#"Added Custom" = Table.AddColumn(#"Expanded Costs", "Keep", each [Costs.Date] <= [Start]),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([Keep] = true)),
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"ID"}, {{"CostDate", each List.Max([Costs.Date]), type date}, {"Start", each List.Max([Start]), type date}, {"Category", each List.Max([Category]), type text}, {"ProjectCost", each List.Max([Costs.Cost]), type number}})
in
#"Grouped Rows"Good luck, let me know if you run into issues.
erik_tarnvik, expertise is a beautiful thing. I'm more or less with you until Step 5. Are there other ways to achieve the grouping step? I have 85 columns that contain a lot of project data that I didn't want to lose in the process. Or would it be easier to load the Projects data file in twice and relate the unformatted table to this newly created table by Project ID?
- erik_tarnvik8 years ago
Solution Specialist
Yes that would be easier. You don't even have to relate, you should be able to just merge (on project ID) what you have after step 5 with a new load of the file and thereby avoid repeating all the columns. Should have thought of that. If you try that and run into issues, let me know and I'll take a stab at it.
- FrankZappasMama8 years agoFrequent Visitor
erik_tarnvik, thanks again.
I've now been able to create all the measures that build on this which was always the ultimate goal. I went back to use the original solution with TOPN in a new column so I avoided importing the same data twice. That dataset is on our an internal server which is already streched so fewer queries is better.
Power to the Power BI people.