Modify Column Names Using Power Query M Functions

by Prathy Kamasani

Update – There is already a dedicated function available to do this, Table.TransformColumnNames. Thanks Imke Feldmann for the shutout. You can find her blog post here.

Recently while I was working on a Power BI model, where I need to modify multiple column names in multiple tables, I wondered is there any function already available which will let me do this with a single statement.

Why I want to format Column Names:

I imported few SSISDB Catalog tables, and one of them looks like below

I don’t want to see underscores in my report, So I started renaming each column. But I was working with multiple queries with this kind of column names. So I began looking under Power BI Query Editor tab, I found Use Headers as FirstRow (I never knew, I can demote Column Headers 🙂 ).

At this stage I thought, I could just use Replace values after this step which would replace all Under Scores. However, data in my table also has Under Scores, that I don’t want to replace. Also, I want to change column names to Proper Case. Fundamentally, I just want to modify only the first row in each query after I demoted headers, but how?

I remember Chris Webb demo about Lists in London Power BI user group; he showed how you could use Lists in Power BI. He also has a blog post about it – https://blog.crossjoin.co.uk/2016/06/21/creating-sequences-of-integers-and-characters-in-power-bipower-query-lists/

I can adopt what he described and select only one row from a list. To do what I want, I need to convert my table to a List and select the first row. Then do all the transformation’s I want on that row. Subsequently, append the transformed row table to the existing table.

Let’s see this in M Language:

At First, my query looked like below

let
Source = Sql.Database(ServerName, "SSISDB"),
catalog_catalog_properties = Source{[Schema="catalog",Item="catalog_properties"]}[Data]
in
catalog_catalog_properties

Then I chose Use Headers as the First Row

DemotedHeaders = Table.DemoteHeaders(catalog_catalog_properties)
in
DemotedHeaders

Then I changed table to List

TabletoList = Table.ToList(DemotedHeaders)

Then selected only first row of the list, which was my header column

TabletoList1 = TabletoList{0}

Then I did the transformations I want to do

//Replace Under scores and format to Proper case
ALLRows = Text.Replace(Text.Proper(TabletoList1),"_"," ")

Then I converted it to list

#"Converted to List" = {ALLRows },

then to a table

#"Converted to Table" = Table.FromList(#"Converted to List", Splitter.SplitTextByDelimiter(","), null, null, ExtraValues.Error)

Now I have the table I want; header row with the changes I need. Next step, to combine with original data of my table that I left at TabletoList1 step. The beauty of M Language is, whatever transformation you do between the steps, your final result is what you chose in your “In” Statement.
So at this stage, I wanted DemotedHeaders Step. Which gives me my dataset as below

As I already prepared another table in my advance script, I removed top 1 row.


Then I used Table.Combine to combine two tables

And finally promoted nicely formatted first row as Header. Now I can easily convert this query to a function by right clicking on the query or from a new blank query. I went for a blank query, so I can polish the query, remove extra spaces and symbols created by GUI.
Function:

 

/*
This Function will remove all Under scores in the Column Names and changes column names to Proper Case.
It takes StepName as Parameter, which is the last Step in the Query
*/

let
FormatColumnNames = (StepName as any) =>
let
DemotedHeaders = Table.DemoteHeaders(StepName),
RemovedTop1Rows = Table.Skip(DemotedHeaders,1),
TabletoList = Table.ToList(DemotedHeaders),
TabletoList1 = TabletoList{0},
ALLRows = Text.Replace(Text.Proper(TabletoList1),"_"," "),
ConvertedToList = {ALLRows},
ConvertedToTable = Table.FromList(ConvertedToList , Splitter.SplitTextByDelimiter(","), null, null, ExtraValues.Error),
Combine = Table.Combine({ConvertedToTable, RemovedTop1Rows}),
PromotedHeaders = Table.PromoteHeaders(Combine)
in

PromotedHeaders

in FormatColumnNames

This was an attempt  to change column names; it saves a lot of time. This function is certainly a keeper for me. It’s worth having your own Power Query functions repository, few already available online (I have not checked, modify column names available in this list or not) – https://github.com/tycho01/pquery.

Prathy 🙂

You may also like

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More