Forum Discussion
Transform Table With Years and Sales Targets
Good morning folks,
I have a data connection that outputs data that looks like this:
| Business Case | Target First Invoice Year | Y1 Target | Y2 Target | Y3 Target | Y4 Target | Y5 Target |
| BC001 | 2025 | 10000 | 25000 | 35000 | 40000 | 50000 |
| BC002 | 2026 | 25000 | 50000 | 75000 | 90000 | 100000 |
| BC003 | 2027 | 5000 | 7500 | 10000 | 11000 | 12000 |
And I'd like to overlay it against sales data, which would require it to be in this form:
| Business Case | Year | Sales |
| BC001 | 2025 | 10000 |
| BC001 | 2026 | 25000 |
| BC001 | 2027 | 35000 |
| BC001 | 2028 | 40000 |
| BC001 | 2029 | 50000 |
| BC002 | 2026 | 25000 |
| BC002 | 2027 | 50000 |
| BC002 | 2028 | 75000 |
| BC002 | 2029 | 90000 |
| BC002 | 2030 | 100000 |
| BC003 | 2027 | 5000 |
| BC003 | 2028 | 7500 |
| BC003 | 2029 | 10000 |
| BC003 | 2030 | 11000 |
| BC003 | 2031 | 12000 |
I haven't quite figured out how to achieve this yet. Can anyone assist?
Hi lxjen ,
Paste this M in your Advanced editor:
let // Step 1: Load Excel file, replace "YourFilePath.xlsx" with your actual file path Source = Excel.Workbook(File.Contents("C:\Path\To\YourFile.xlsx"), null, true), // Step 2: Load the specific sheet, replace "YourSheetName" with the actual sheet name Sheet_Data = Source{[Item="YourSheetName", Kind="Sheet"]}[Data], // Step 3: Promote headers to use the first row as column names #"Promoted Headers" = Table.PromoteHeaders(Sheet_Data, [PromoteAllScalars=true]), // Step 4: Change data types to ensure proper formatting #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers", {{"Business Case", type text}, {"Target First Invoice Year", Int64.Type}, {"Y1 Target", Int64.Type}, {"Y2 Target", Int64.Type}, {"Y3 Target", Int64.Type}, {"Y4 Target", Int64.Type}, {"Y5 Target", Int64.Type}}), // Step 5: Unpivot Y1-Y5 Target columns to transform data into a long format #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Business Case", "Target First Invoice Year"}, "Year Offset", "Sales"), // Step 6: Extract the year offset number from the column name (e.g., "Y1 Target" → 1) #"Extracted Offset Number" = Table.AddColumn(#"Unpivoted Columns", "Year Offset Number", each Number.From(Text.Middle([Year Offset], 1, 1)), Int64.Type), // Step 7: Calculate the actual sales year based on the target first invoice year #"Calculated Year" = Table.AddColumn(#"Extracted Offset Number", "Year", each [Target First Invoice Year] + [Year Offset Number] - 1, Int64.Type), // Step 8: Remove unnecessary columns #"Removed Unnecessary Columns" = Table.RemoveColumns(#"Calculated Year", {"Year Offset", "Year Offset Number", "Target First Invoice Year"}), // Step 9: Rename columns for better readability #"Renamed Columns" = Table.RenameColumns(#"Removed Unnecessary Columns", {{"Sales", "Sales"}}), // Step 10: Reorder columns to maintain logical order #"Reordered Columns" = Table.ReorderColumns(#"Renamed Columns",{"Business Case", "Year", "Sales"}) in #"Reordered Columns"This will result on this:
5 Replies
- Bibiano_Geraldo
Super User
Hi lxjen ,
Paste this M in your Advanced editor:
let // Step 1: Load Excel file, replace "YourFilePath.xlsx" with your actual file path Source = Excel.Workbook(File.Contents("C:\Path\To\YourFile.xlsx"), null, true), // Step 2: Load the specific sheet, replace "YourSheetName" with the actual sheet name Sheet_Data = Source{[Item="YourSheetName", Kind="Sheet"]}[Data], // Step 3: Promote headers to use the first row as column names #"Promoted Headers" = Table.PromoteHeaders(Sheet_Data, [PromoteAllScalars=true]), // Step 4: Change data types to ensure proper formatting #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers", {{"Business Case", type text}, {"Target First Invoice Year", Int64.Type}, {"Y1 Target", Int64.Type}, {"Y2 Target", Int64.Type}, {"Y3 Target", Int64.Type}, {"Y4 Target", Int64.Type}, {"Y5 Target", Int64.Type}}), // Step 5: Unpivot Y1-Y5 Target columns to transform data into a long format #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Business Case", "Target First Invoice Year"}, "Year Offset", "Sales"), // Step 6: Extract the year offset number from the column name (e.g., "Y1 Target" → 1) #"Extracted Offset Number" = Table.AddColumn(#"Unpivoted Columns", "Year Offset Number", each Number.From(Text.Middle([Year Offset], 1, 1)), Int64.Type), // Step 7: Calculate the actual sales year based on the target first invoice year #"Calculated Year" = Table.AddColumn(#"Extracted Offset Number", "Year", each [Target First Invoice Year] + [Year Offset Number] - 1, Int64.Type), // Step 8: Remove unnecessary columns #"Removed Unnecessary Columns" = Table.RemoveColumns(#"Calculated Year", {"Year Offset", "Year Offset Number", "Target First Invoice Year"}), // Step 9: Rename columns for better readability #"Renamed Columns" = Table.RenameColumns(#"Removed Unnecessary Columns", {{"Sales", "Sales"}}), // Step 10: Reorder columns to maintain logical order #"Reordered Columns" = Table.ReorderColumns(#"Renamed Columns",{"Business Case", "Year", "Sales"}) in #"Reordered Columns"This will result on this:
- lxjenRegular Visitor
This worked perfectly, thank you!
- lxjenRegular Visitor
I don't think that does it. I only have a single year value in the source data, and in the new data I need a row for each year (the single year value is the source, and then each year will be source +1, source +2, etc.) and then I need to use the target values (Target Y1, Target Y2, etc. would be just Sales).
- wini_R
Solution Supplier
EDIT: My bad, I missed one specific requirement regarding Year column. That is final output:
Code to test in Power Query advanced editor:
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("TY7BDQAhCAR74e0DUDR+tQxj/22cB5son8luGMJaNCazUCJltQPhM3+0YAYLenPuFKKGWB/BsNiQO7IfvmYOs8GA8DwgAqpr+wM=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Business Case" = _t, #"Target First Invoice Year" = Int64.Type, #"Y1 Target" = Int64.Type, #"Y2 Target" = Int64.Type, #"Y3 Target" = Int64.Type, #"Y4 Target" = Int64.Type, #"Y5 Target" = Int64.Type]), #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Business Case", "Target First Invoice Year"}, "Attribute", "Sales"), #"Extracted Text Range" = Table.TransformColumns(#"Unpivoted Other Columns", {{"Attribute", each Number.From(Text.Middle(_, 1, 1))-1, Int64.Type}}), #"Merged Columns" = Table.CombineColumns(#"Extracted Text Range", {"Target First Invoice Year", "Attribute"}, each List.Sum(List.Transform(_, (i)=> Number.From(i))) ,"Year") in #"Merged Columns"