Excel Power Query: Custom Text String Formula

Kieffer_Farn

New Member
Joined
Nov 25, 2023
Messages
5
Office Version
  1. 365
Platform
  1. MacOS
Hi,

I'm looking for some help to create a custom text string formula to convert this original date text string (20230926173000) into this exact format (2023-09-26T17:30:00.000). The original date text string is always this length.

It new sting has to be this exact format.

I could really use the complete formula that I can simply copy and paste into to Schema view when in Power Editor.

I tried building this using multiple new column inputs and have failed. It next to impossible to troubleshot incorrect formulas in Power Query (way more difficult than Excel itself). I'm self taught in using Excel and Google Sheets formulas and can muddle through but Power Query requires a completely new programing / code skill set that I'm having a difficult time with as a newbie.

The name of the column with the original date text sting is Clock In (YYYYMMDDHHMMSS). I don't want to change this name since that's who it's exported from the source data.

Any assistance would be greatly appreciated.

Kieffer
 

Excel Facts

Links? Where??
If Excel says you have links but you can't find them, go to Formulas, Name Manager. Look for old links to dead workbooks & delete.
Welcome to the MrExcel Message Board!

This is almost the same solution that I have recently provided for another question.

The following is the code adapted to your question. Create a blank query and use the Advanced Editor to copy and paste this code. Change the table name with yours and execute it.
Power Query:
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Convert = Table.TransformColumns(Source, 
            {"Clock In (YYYYMMDDHHMMSS)", 
                each DateTime.ToText(
                        DateTime.FromText(
                            Text.From(_), 
                            [Format="yyyyMMddHHmmss"]
                        ), 
                        [Format="yyyy-MM-ddTHH:mm:ss.000"]
                    )
            })
in
    Convert

How does it work? Let's start from the date extraction from the source data.

The DateTime.FromText() converts a given text value into an actual DateTime value. The yyyyMMddHHmmss format is the format that the original data is provided in your project. Note that I used HH to indicated it is in 24 hours format. By using the following function with the given format string, we create an actual DateTime value matching the source value format to be used in the next function.
Note: _ character here identifies the row value in the transformed column. We'll get to that a bit later, and how we use it with "each" keyword.
Power Query:
DateTime.FromText(Text.From(_), [Format="yyyyMMddHHmmss"]),

Since we have the DateTime value, we can now format this value into the required format - yyyy-MM-ddTHH:mm:ss.000 in this case. We are using the DateTime.ToText() function to format the value as we need. This function is basically the reversed version of the DateTime.FromText() function. It takes the given DateTime value (that we extracted and converted to a real DateTime value in the previous step) and formats this value as a text value.
Power Query:
DateTime.ToText(
                DateTime.FromText(Text.From(_), [Format="yyyyMMddHHmmss"]), 
                [Format="yyyy-MM-ddTHH:mm:ss.000"]
)

And finally the Table.TransformColumns() function. The Table.TransformColumns() function transforms the table column(s) by using the provided transformation function(s). It takes minimum two parameters, the source table and the column transformation function(s) as a list.

The first parameter, source table, is easy. It is just the table identifier that identifies your table.
Rich (BB code):
  Convert = Table.TransformColumns(Source, transformation_function)

The second parameter requires a bit of explanation. It is a list comprising two items. The first item is the name of the column to be transformed, and the second item is the function that will transform the values of that column, executing the logic on 'each' row. For example, consider the following function - it simply says: 'take the Source table and add 5 to each row value in the MyColumn column.'
The underscore, '_', represents the value of 'that' row when the 'each' keyword is used to iterate through rows (or any list/array).
Rich (BB code):
  Convert = Table.TransformColumns(Source, {"MyColumn", each _ + 5})

Instead of adding 5 to each value, we use our own transformation function that I explained at the beginning, and here is the result. Note that I used a single-column table named as Table1. You need to change the table name in the code if it is different in your project).
Clock In (YYYYMMDDHHMMSS)Clock In (YYYYMMDDHHMMSS)
202309261730002023-09-26T17:30:00.000
202309291420002023-09-29T14:20:00.000
202310011230002023-10-01T12:30:00.000
202310041500002023-10-04T15:00:00.000


Additional note on the Table.TransformColumns() function's second parameter, the list of transformation(s). The reason of using the (s) in this description is pointing the fact that we can transform multiple columns by using different transformation functions at single step. Take a look at the following sample:
Rich (BB code):
  Convert = Table.TransformColumns(Source, { {"MyColumn", each _ + 5}, {"MyColumn2", each _ + 10} })

As you can see, we created a single list of lists consisting of the individual column name and transformation function, and this way, each column in the provided list will be updated as required.

The entire procedure can be executed by adding and removing columns as I explained in the earlier question linked above. I recommend the method I've outlined here if you intend to learn M Language. However, if you prefer using the Power Query interface only, it's perfectly fine to achieve the same results by adding, removing, and renaming columns.

Hope this helps. Please let us know if you have any questions.
 
Upvote 0
Solution
Hi @smozgur

This is great! I also appreciate the detail and explanation, knowing I'm a newbie. I have figured out how to get what I needed using PQ interface (add columns, format, merge, etc) but it's lengthy process.

But I'm still going to give your solution a try. However, I'm already stuck at the first step. For some reason I the Query Editor won't let me just paste your solution into it. I'm using a Mac if that makes any difference.

I also want to try to keep the query inline with the main query by adding a custom column and then adding the code in the box (see image below) but it doesn't allow user to paste into the input box.

Screen Shot 2023-11-26 at 9.35.33 AM.png


Image of the editor box to add custom column.
1701020859299.png
 

Attachments

  • 1701020824996.png
    1701020824996.png
    104.6 KB · Views: 6
Upvote 0
@smozgur it worked! Thank you!

This issue I had regarding pasting was because Power Query editor does not accept right click paste. So I just used Command - V.

A couple of f/u questions:

1. To do the same thing for Clock-Out data do I need to create another Query or can I just copy/paste and then edit by adding the additional code below the code for the Clock-In data code.

2. Now that I have this extra query, I get a side box showing the new Query. Will all these Queries combine and work (the all pull from the same source data) without me having to trigger them one by one?

Kieffer
 
Upvote 0
Here is what I'm now seeing on the left side bar. The new one you provided is simply called Query.
 

Attachments

  • Screen Shot 2023-11-26 at 4.38.55 PM.png
    Screen Shot 2023-11-26 at 4.38.55 PM.png
    135.1 KB · Views: 6
Upvote 0
1. To do the same thing for Clock-Out data do I need to create another Query or can I just copy/paste and then edit by adding the additional code below the code for the Clock-In data code.
It will be something like this (please take a look at my initial description about why I used (s) when I explained TransformColumns function. As you can see below, I transformed two columns)
Power Query:
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Convert = Table.TransformColumns(Source, 
            {
                {"Clock In (YYYYMMDDHHMMSS)", 
                    each DateTime.ToText(
                            DateTime.FromText(
                                Text.From(_), 
                                [Format="yyyyMMddHHmmss"]
                            ), 
                            [Format="yyyy-MM-ddTHH:mm:ss.000"]
                        )
                },
                {"Clock Out (YYYYMMDDHHMMSS)", 
                    each DateTime.ToText(
                            DateTime.FromText(
                                Text.From(_), 
                                [Format="yyyyMMddHHmmss"]
                            ), 
                            [Format="yyyy-MM-ddTHH:mm:ss.000"]
                        )
                }
            })
in
    Convert

2. Now that I have this extra query, I get a side box showing the new Query. Will all these Queries combine and work (the all pull from the same source data) without me having to trigger them one by one?
No, you will delete that extra query but embed the code in your own query instead. In my sample query above, the first line gets the Source data. You won't use that line but the second one, Convert and you will change the first parameter of the TransformColumn function in the Convert line, Source identifier, with the identifier that holds the data right before the step where you want to put this line (it will be most likely the last step)

Let's say your existing query is:
Power Query:
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    ChangedType = Table.TransformColumnTypes(Source,{{"Clock In (YYYYMMDDHHMMSS)", Int64.Type}, {"Clock Out (YYYYMMDDHHMMSS)", Int64.Type}})
in
    ChangedType

You will put a comma right after the last identifier in the "let" block, copy & paste the Convert line from the sample, and finally change the final line in the "in" block to return Convert instead of ChangeType.
Power Query:
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    ChangedType = Table.TransformColumnTypes(Source,{{"Clock In (YYYYMMDDHHMMSS)", Int64.Type}, {"Clock Out (YYYYMMDDHHMMSS)", Int64.Type}}),
    Convert = Table.TransformColumns(ChangedType, 
            {
                {"Clock In (YYYYMMDDHHMMSS)", 
                    each DateTime.ToText(
                            DateTime.FromText(
                                Text.From(_), 
                                [Format="yyyyMMddHHmmss"]
                            ), 
                            [Format="yyyy-MM-ddTHH:mm:ss.000"]
                        )
                },
                {"Clock Out (YYYYMMDDHHMMSS)", 
                    each DateTime.ToText(
                            DateTime.FromText(
                                Text.From(_), 
                                [Format="yyyyMMddHHmmss"]
                            ), 
                            [Format="yyyy-MM-ddTHH:mm:ss.000"]
                        )
                }
            })
in
    Convert

The result:
Clock In (YYYYMMDDHHMMSS)Clock Out (YYYYMMDDHHMMSS)Clock In (YYYYMMDDHHMMSS)Clock Out (YYYYMMDDHHMMSS)
20230926173000202309261930002023-09-26T17:30:00.0002023-09-26T19:30:00.000
20230929142000202309291920002023-09-29T14:20:00.0002023-09-29T19:20:00.000
20231001123000202310011830002023-10-01T12:30:00.0002023-10-01T18:30:00.000
20231004150000202310041600002023-10-04T15:00:00.0002023-10-04T16:00:00.000


I hope this helps.
 
Upvote 0
You've been a great help @smozgur (Suat)! Thank you so much :)

This fabulous code you provided, along with equally helpful explanation, replaced about 20 different steps I had to do to get these results. I'm going to replace those steps with your solution but keep a copy of my original work to remind me how to go about things when I've something more basic.

Using Excel Power Query along with leaning a bit of M language as been great and will save a lot of time for our companies payroll department every 2 weeks. I'll also be looking at this for another process we have to do regularly for reporting.

Cheers!

Kieffer
 
Upvote 0
You're welcome, Kieffer. Thanks for the feedback.

One big benefit of writing the query using M language directly is that it often takes fewer steps to get the result. Also, there are many functions you can't access through the user interface alone; you need the advanced editor for that. However, solving the problem with your own work is also valuable because the Power Query user interface offers different ways to achieve results without diving into the advanced editor. It makes us think and discover useful methods, making Power Query an amazing tool!

Glad to hear the method and the explanation helps!
 
Upvote 0

Forum statistics

Threads
1,215,073
Messages
6,122,974
Members
449,095
Latest member
Mr Hughes

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top