Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
EpicTriffid
Helper IV
Helper IV

Change Column Headers to references in lookup table

Hi all,

 

So I have a set of data laid out like below:

 

Item2016/172017/182018/192019/202020/21

A

12416
B45647
C73853

 

I just ended up finding out that the five years of data listed above will change every year, shifting forward by one. So the 2016/17 column will be dropped and the 2021/22 column will be added in the excel spreadsheet. Bit annoying as any later step in my query that references those headers will break. 

 

So I am thinking that when the data gets updated in the spreadsheet I can put it in under the headers of Year 1, Year 2, Year 3 and so on, then I can have a lookup table that lists the actual years in it, like:

 

2017/18
2018/19
2019/20
2020/21
2021/22

 

Then I will be able to add a step in shortly after the "Source" step that converts the headers to each row in my lookup table, so "Year 1" will change to the first row of my lookup table ("2017/18"), "Year 2" will change to the second row ("2018/19") and so on.

 

However, I have absolutely no idea how to do that. Can I get M code to do that?

1 ACCEPTED SOLUTION
Vijay_A_Verma
Super User
Super User

Actually, you need not make a reference table. Just demote your headers, Transpose, look if your header contains "/", change it to Year1....5 and then Transpose and promote your headers again.

This way it will be completely dynamic and having no dependency on another table maintenance.

See the working here - Open a blank query - Home - Advanced Editor - Remove everything from there and paste the below code to test (later on when you use the query on your dataset, you will have to change the source appropriately)

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIEYiMgNoGyzZRidaKVnKAipmARCNscLOMMZukoGQOxBVSFsVJsLAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Item = _t, #"2016/17" = _t, #"2017/18" = _t, #"2018/19" = _t, #"2019/20" = _t, #"2020/21" = _t]),
    #"Demoted Headers" = Table.DemoteHeaders(Source),
    #"Changed Type" = Table.TransformColumnTypes(#"Demoted Headers",{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}}),
    #"Transposed Table" = Table.Transpose(#"Changed Type"),
    #"Added Index" = Table.AddIndexColumn(#"Transposed Table", "Index", 0, 1, Int64.Type),
    #"Added Custom" = Table.AddColumn(#"Added Index", "ColumnNames", each if Text.Contains([Column1],"/") then "Year"&Text.From([Index]) else [Column1]),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index", "Column1"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"ColumnNames", "Column2", "Column3", "Column4"}),
    #"Transposed Table1" = Table.Transpose(#"Reordered Columns"),
    #"Promoted Headers" = Table.PromoteHeaders(#"Transposed Table1", [PromoteAllScalars=true]),
    #"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",{{"Item", type text}, {"Year1", Int64.Type}, {"Year2", Int64.Type}, {"Year3", Int64.Type}, {"Year4", Int64.Type}, {"Year5", Int64.Type}})
in
    #"Changed Type1"

View solution in original post

3 REPLIES 3
BA_Pete
Super User
Super User

Hi @EpicTriffid ,

 

This is an XY Problem.

 

You don't need to do what you think you do with the column names.

You should select your [Item] column then go to the transform tab > Unpivot Columns (dropdown) > Unpivot Other Columns.

 

This will put your data into the following structure:

BA_Pete_0-1649682414875.png

 

This means you only ever have to reference the generic [Attribute] and [Value] column names and is therefore dynamic for changing years. You can change these names by editing these parts of the code generated by the unpivot step:

BA_Pete_1-1649682534066.png

 

It also structures your data in the correct/most efficient/best practice structure for reporting.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIEYiMgNoGyzZRidaKVnKAipmARCNscLOMMZukoGQOxBVSFsVJsLAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Item = _t, #"2016/17" = _t, #"2017/18" = _t, #"2018/19" = _t, #"2019/20" = _t, #"2020/21" = _t]),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Item"}, "Attribute", "Value")
in
    #"Unpivoted Other Columns"

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




Vijay_A_Verma
Super User
Super User

Actually, you need not make a reference table. Just demote your headers, Transpose, look if your header contains "/", change it to Year1....5 and then Transpose and promote your headers again.

This way it will be completely dynamic and having no dependency on another table maintenance.

See the working here - Open a blank query - Home - Advanced Editor - Remove everything from there and paste the below code to test (later on when you use the query on your dataset, you will have to change the source appropriately)

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIEYiMgNoGyzZRidaKVnKAipmARCNscLOMMZukoGQOxBVSFsVJsLAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Item = _t, #"2016/17" = _t, #"2017/18" = _t, #"2018/19" = _t, #"2019/20" = _t, #"2020/21" = _t]),
    #"Demoted Headers" = Table.DemoteHeaders(Source),
    #"Changed Type" = Table.TransformColumnTypes(#"Demoted Headers",{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}}),
    #"Transposed Table" = Table.Transpose(#"Changed Type"),
    #"Added Index" = Table.AddIndexColumn(#"Transposed Table", "Index", 0, 1, Int64.Type),
    #"Added Custom" = Table.AddColumn(#"Added Index", "ColumnNames", each if Text.Contains([Column1],"/") then "Year"&Text.From([Index]) else [Column1]),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index", "Column1"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"ColumnNames", "Column2", "Column3", "Column4"}),
    #"Transposed Table1" = Table.Transpose(#"Reordered Columns"),
    #"Promoted Headers" = Table.PromoteHeaders(#"Transposed Table1", [PromoteAllScalars=true]),
    #"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",{{"Item", type text}, {"Year1", Int64.Type}, {"Year2", Int64.Type}, {"Year3", Int64.Type}, {"Year4", Int64.Type}, {"Year5", Int64.Type}})
in
    #"Changed Type1"
jennratten
Super User
Super User

Hello - I recommend saving your column names in columns instead of rows.  It makes it a little more straight forward to convert it to a list of headers.  You can use Table.RenameColumns and then provide a list of the old columns and the new columns.  This is how you can do it.

 

New Column Headers in Columns:

jennratten_0-1649680056989.png

 

Sample Data with Columns to be Renamed:

jennratten_1-1649680102017.png

 

Sample Data with the Columns Renamed:

jennratten_2-1649680142329.png

 

Script (copy this and paste it into a blank query):

let
    // Headers in Rows
    HeadersInRows = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMtQ3MlLSUfJLLXfOzynNzTNE5qDIGCvF6oC1GOkbGSNLOCJznJA5zkqxsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Year = _t, Column1 = _t, Column2 = _t, Column3 = _t]),

    // Headers in Columns
    HeadersInColumns = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45W8kstd87PKc3NM1TSQXAclWJ1kOSMkOWcUOWMIXLJYI6zUmwsAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"2021/22" = _t, #"2022/23" = _t]),

    // Data
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKkpNUdJRMgTixIKCnFSlWJ1opaSc0lSggBEQF6QmFoHF0otSU/OAAsZAnJSYB4RKsbEA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Color = _t, Number = _t, Fruit = _t]),

    // RenameColumns
    RenameColumns = Table.RenameColumns ( Source, 
        List.Zip (
            {
                Table.ColumnNames ( Source ), // old header names
                HeadersInColumns[#"2022/23"]  // new header names
            }
        )
    )
in
    RenameColumns

 

 

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

December 2025 Power BI Update Carousel

Power BI Monthly Update - December 2025

Check out the December 2025 Power BI Holiday Recap!

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.