March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early bird discount ends December 31.
Register NowBe one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now
Hi there,
My last 3 columns 2024, 2025 and 2026 always change from time to time, as it represents year of my sales that I want to track, therefore I created a list (I named it as Years) for these column names since they are dynamic.
However, I am stuck when trying to replace my original M code below with the list (Years) that I created earlier,
= Table.TransformColumnTypes(#"Promoted Headers",{{"Region", type text}, {"Country", type text}, {"Item", type text}, {"Price", type text}, {"Color", type any}, {"2024", Int64.Type}, {"2025", Int64.Type}, {"2026", Int64.Type}})
I have tried to replace
{"2024", Int64.Type}, {"2025", Int64.Type}, {"2026", Int64.Type}
to
{Year, Int64.Type}
but unfortunately, it does not work. Hope to get some guidance here after hours of searching with no similar answers found, thank you
Regards,
M
Solved! Go to Solution.
If it is only the last three columns that need to have dynamic names, you can set the data types for all the columns by creating a list similar to:
#"Types List" = {{"Region", type text}, {"Country", type text}, {"Item", type text}, {"Price", Currency.Type}, {"Color", type text}}
& List.Transform(List.LastN(Table.ColumnNames(#"Promoted Headers"),3), each {_, Int64.Type}),
Then you can use it in the Transform.ColumnTypes function like:
#"Promoted Headers" = ...,
#"Types List" = {{"Region", type text}, {"Country", type text}, {"Item", type text}, {"Price", Currency.Type}, {"Color", type text}}
& List.Transform(List.LastN(Table.ColumnNames(#"Promoted Headers"),3), each {_, Int64.Type}),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers", #"Types List")
in
#"Changed Type"
If it is only the last three columns that need to have dynamic names, you can set the data types for all the columns by creating a list similar to:
#"Types List" = {{"Region", type text}, {"Country", type text}, {"Item", type text}, {"Price", Currency.Type}, {"Color", type text}}
& List.Transform(List.LastN(Table.ColumnNames(#"Promoted Headers"),3), each {_, Int64.Type}),
Then you can use it in the Transform.ColumnTypes function like:
#"Promoted Headers" = ...,
#"Types List" = {{"Region", type text}, {"Country", type text}, {"Item", type text}, {"Price", Currency.Type}, {"Color", type text}}
& List.Transform(List.LastN(Table.ColumnNames(#"Promoted Headers"),3), each {_, Int64.Type}),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers", #"Types List")
in
#"Changed Type"
Hi Ron,
Thank you so much and this is exactly what I was confused about. In fact, I have found a similar solution here
https://goodly.co.in/dynamic-data-types-power-query/
Regards,
M
Hi @M001 ,
Do you mean you have got something like this:
And then want to use something like Transpose:
And after that promote your headers?
Hello! Here is a custom function you can use to detect the column types without specifying column names. Add a new blank query, go to the Advanced Editor and replace the contents with the custom function script below. Name the query fnDetectDataTypes. Then replace your Table.TransformColumnTypes step with this:
= fnDetectDataTypes(#"Promoted Headers")
Custom Function
// ****************************************************************************************************************/
// fnDetectDataTypes
// ****************************************************************************************************************/
// PURPOSE
// - Detect data types from a table's data and transform to the appropriate type
//
// LIMITATIONS
// -
//
// DEVELOPER (Adapted from)
// - https://www.thebiccountant.com/2020/05/01/detect-change-types-of-all-columns-in-power-query/
// ****************************************************************************************************************/
let
fn = (table as table, optional first_n_records as nullable number, optional culture as nullable text) as table =>
let
TextColumns = Table.ColumnsOfType ( table, {type nullable text} ),
TempKey = "--(^_^)--",
ReplaceNulls = Table.ReplaceValue ( table, null, TempKey, Replacer.ReplaceValue, TextColumns),
InvalidTypes = {type list, type record, type table, type function, type type, type null, type duration},
Culture = if culture = null then "en-US" else culture,
TopRows = if first_n_records = null then 200 else top_records, //set default to 200 rows to establish a column type
TopNRows = Table.FirstN(ReplaceNulls, TopRows),
ColumnNameList = Table.ColumnNames(TopNRows),
ColumnDataLists = List.Accumulate(ColumnNameList, {}, (accumulated, i) => accumulated & {Table.Column(TopNRows, i)}),
ColumnTypes = List.Transform(ColumnDataLists, (i) => List.ItemType(i)),
TransformList = List.Select(List.Zip({ColumnNameList, ColumnTypes}), (i) => not List.Contains(List.Transform(InvalidTypes, (j) => Type.Is(i{1}, j)), true)),
TypedTable = Table.TransformColumnTypes(ReplaceNulls, TransformList, Culture),
List.ItemType = (list as list) =>
let
ItemTypes = List.Transform(
list,
each
if Value.Type(Value.FromText(_, Culture)) = type number
then
if Text.Contains(Text.From(_, Culture),"%")
then Percentage.Type
else
if Text.Length(Text.Remove(Text.From(_, Culture), {"0".."9"} & Text.ToList("., -+eE()/'"))) > 0
then Currency.Type
else
if Int64.From(_, Culture) = Value.FromText(_, Culture)
then Int64.Type
else type number
else Value.Type(Value.FromText(_, Culture))
),
ListItemType = Type.Union(ItemTypes)
in
ListItemType
in
let
//RemoveInvalidTypes = Table.RemoveColumns ( TypedTable, Table.ColumnsOfType ( TypedTable, {type list, type record, type table, type function} ) ),
// dataflows currently converts all dates to datetime
PrimitiveTypes = Table.ColumnsOfType(TypedTable, {type nullable number, type nullable text, type nullable logical, type nullable datetime}),
NonConformingTypes = List.RemoveMatchingItems ( Table.ColumnNames ( TypedTable ), PrimitiveTypes ),
NonConformingTypesToText = Table.TransformColumnTypes( TypedTable, List.Zip( { NonConformingTypes,
List.Repeat( {type text}, List.Count( NonConformingTypes ) ) } ) ),
TextColumnsNew = Table.ColumnsOfType (NonConformingTypesToText, {type nullable text} ),
ReplaceTempKey = Table.ReplaceValue(NonConformingTypesToText ,TempKey,"",Replacer.ReplaceValue, TextColumnsNew )
in
ReplaceTempKey
in
fn
Hi Jenn,
My question is more about why the column names for 2024, 2025 and 2026 that I have converted to a List (named as Year) doesnt work when I put in the following code. Thank you
= Table.TransformColumnTypes(#"Promoted Headers",{{Year, Int64.Type}})
If your 'Year' field contains a list of values, like this:
and your objective it to simply set the correct type for the column, it would not be 'Int64.Type' because your field does not contain integers - it contains a list of integers. Therefore, you would leave it as 'type any' by omitting it from the transform column types step.
Hi @M001 ,
Do you mean the column name always changes and is dynamic so you can't quote them in a 'Change Type'?
If so, you could try to split the column change and header promotion. If the structure of the data source stays the same, changing Column 6 through Column 8 to Int64-type, followed by dynamicly promoting the header without mentioning any column name in the first row.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCkpNz8zPU9JRcs4vzSspqgSyPEtSc4FUQFFmcipYIie/CEgbGRiZQChTCGWmFBsLAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t, Column5 = _t, Column6 = _t, Column7 = _t, Column8 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", Int64.Type}, {"Column7", Int64.Type}, {"Column8", Int64.Type}}),
#"Promoted Headers" = Table.PromoteHeaders(#"Changed Type", [PromoteAllScalars=true])
in
#"Promoted Headers"
Hi Jasper,
This is a good idea. However, I would like to know how to put the column names that I have converted to list into Table.TransformColumnTypes?
I convert column names for 2024, 2025, 2026 to a list named as Year, and how do I put it into Table.TransformColumnTypes? The code below doesnt work
= Table.TransformColumnTypes(#"Promoted Headers",{{Year, Int64.Type}})
Thank you,
M
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.
User | Count |
---|---|
21 | |
16 | |
13 | |
12 | |
9 |
User | Count |
---|---|
36 | |
31 | |
20 | |
19 | |
17 |