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
RHOU
Advocate III
Advocate III

Looping M Query function through list which includes column names to split DateTime

Hi, I need some help optimizing a function to iterate through a list of columns. 

 

Here is my function which takes a Table and a column and then splits the DateTime columns into a separate Date field and a separate Time field (rounded to minutes) and then removes the original DateTime column. This works well and I use it all the time.

 

 

(varTable as table, varCol as text) => let
  Source = varTable,
  #"Inserted date" = Table.AddColumn(Source, varCol & " Date", each DateTime.Date(Record.Field(_,varCol)), type nullable date),
  #"Inserted time" = Table.AddColumn(#"Inserted date", varCol & " Time", each DateTime.Time(DateTime.From(DateTime.ToText(Record.Field(_,varCol),"HH:mm"))), type nullable time),
  #"Remove DateTime Column" = Table.RemoveColumns(#"Inserted time", varCol)
in
  #"Remove DateTime Column"

 

 

 

I would like to further improve this to allow varCol to not include just one column but be a list of columns so that I can use this function and include 5 DateTime fields in a table at once. I started below, but the problem is I have no idea how to loop through the varCols list for the two steps to add the columns and continously change the table. 

Does anybody have a tip?  

 

 

(varTable as table, varCols as list) => let
  Source = varTable,
  
// what needs to happen here to loop this section for each value in the varCols list???

  #"Inserted date" = Table.AddColumn(Source, varCol & " Date", each DateTime.Date(Record.Field(_,varCol)), type nullable date),
  #"Inserted time" = Table.AddColumn(#"Inserted date", varCol & " Time", each DateTime.Time(DateTime.From(DateTime.ToText(Record.Field(_,varCol),"HH:mm"))), type nullable time),
  
// until here
  
  #"Remove DateTime Column" = Table.RemoveColumns(#"Inserted time", varCols)
in
  #"Remove DateTime Column"

 

 

 

 

1 ACCEPTED SOLUTION
RHOU
Advocate III
Advocate III

I was able to figure it out. The secret key ingredient is List.Accumulate and building a separate inner function to iterate. 

 

Here the final result that works. 

 

 

(varTable as table, varCols as list) => let
  
  // first define the inner function to iterate later
   sepDateTime = (varTable as table, varCol as text) => let
      Source = varTable,
      #"Inserted date" = Table.AddColumn(Source, varCol & " Date", each DateTime.Date(Record.Field(_,varCol)), type nullable date),
      #"Inserted time" = Table.AddColumn(#"Inserted date", varCol & " Time", each DateTime.Time(DateTime.From(DateTime.ToText(Record.Field(_,varCol),"HH:mm"))), type nullable time)
   in
      #"Inserted time",
   // inner function end    
  
  
  AddDateAndTimeColumns = List.Accumulate(varCols, varTable, (state, current) => sepDateTime(state,current)),
  RemoveAllDateTime = Table.RemoveColumns(AddDateAndTimeColumns, varCols)
in
  RemoveAllDateTime

 

 

 

View solution in original post

2 REPLIES 2
jennratten
Super User
Super User

Hello - if you are just wanting to get the time portion (rounded to minutes) from a list of DateTime fields, this is how you can do it.

BEFORE

jennratten_0-1650553470293.png

RESULT

jennratten_1-1650553495133.png

 

SCRIPT

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMtE3MtQ3MjAyUjA0sDKytDIwVXD0VdLBEDcFi8fGAgA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [DateTime1 = _t, DateTime2 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"DateTime1", type datetime}, {"DateTime2", type datetime}}),
    varColumnNames = {"DateTime1", "DateTime2"},
    TransformValues = Table.TransformColumns(#"Changed Type", List.Zip( { varColumnNames, 
        List.Repeat( {each DateTime.ToText ( _, "HH:mm" )}, List.Count( varColumnNames ) ) } ) )
in
    TransformValues
RHOU
Advocate III
Advocate III

I was able to figure it out. The secret key ingredient is List.Accumulate and building a separate inner function to iterate. 

 

Here the final result that works. 

 

 

(varTable as table, varCols as list) => let
  
  // first define the inner function to iterate later
   sepDateTime = (varTable as table, varCol as text) => let
      Source = varTable,
      #"Inserted date" = Table.AddColumn(Source, varCol & " Date", each DateTime.Date(Record.Field(_,varCol)), type nullable date),
      #"Inserted time" = Table.AddColumn(#"Inserted date", varCol & " Time", each DateTime.Time(DateTime.From(DateTime.ToText(Record.Field(_,varCol),"HH:mm"))), type nullable time)
   in
      #"Inserted time",
   // inner function end    
  
  
  AddDateAndTimeColumns = List.Accumulate(varCols, varTable, (state, current) => sepDateTime(state,current)),
  RemoveAllDateTime = Table.RemoveColumns(AddDateAndTimeColumns, varCols)
in
  RemoveAllDateTime

 

 

 

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!

November Power BI Update Carousel

Power BI Monthly Update - November 2025

Check out the November 2025 Power BI update to learn about new features.

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.