Forum Discussion
Splitting, Summing and Reformatting all in the same cell
Hi All. I'm a beginner user trying to do what I feel is advanced level user type work but I'm stuck with it so.....
My problem. I am building a table using an xlxs file. The "Date" field is a custom formatted cell (hh:mm:ss) in excel which gives me values that look like "00:07:47" and that is what I expect. This is a field for duration (Test times). When the excel file is imported into BI and I am working on it in the Power Query editor, it changes the format to "12/31/1899 12:07:47". I have been unsuccessful in every attempt to reformat that into a type that doesn't give me errors, and allows me to use a calculable field (average test times, etc). I need to be able to show average test duration in hh:mm:ss.
Also, to add to my problem, the original file has multiple duration entries.
So, I have an original excel file that looks like this:
| 0:00:10 |
| 0:08:11 |
| 00:04:42/00:04:12/00:05:21/00:04:47/00:11:26 |
| 0:01:51 |
| 0:06:39 |
| 0:00:10 |
| 0:09:21 |
| 00:01:22/00:17:07 |
| 0:10:51 |
But when imported into BI/Transform data, it ends up looking like this: (no this isn;t the same data just an example)
| 12/31/1899 12:07:57 AM |
| 12/31/1899 12:10:32 AM |
| 12/31/1899 12:09:06 AM |
| 00:22:54/00:14:39 |
| 00:30:30/00:08:04 |
| 12/31/1899 12:08:16 AM |
| 00:04:42/00:04:12/00:05:21/00:04:47/00:11:26 |
So my problems are two fold. I need to somehow sum all of the duplicate values into one value, then split out and convert the date/time values to the hh:mm:ss duration (so a date/time value of 12/31/1899 12:08:16 AM would look like 00:08:16. 8 minutes, 16 seconds duration).
Maybe I'm trying to overcomplicate this. Maybe what I want to do isn't possible..... but I'm going insane trying to figure it out.
Can anybody please help me?!
Hello Anonymous
add a custom column and add this function. Column name has to be "Duration" and formated as text
List.Accumulate(List.Transform(Text.Split(_[Duration],"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c)Here the complete example for reproducing it
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Tc3RDcAgCATQXfxuUs6q1FvFuP8atSBN/x6EO8ZIQhFC0jzMNwH3GgpLPh1wVGbsTdEXAHOLMFgRbrx6+P+gr4bvwQpbL5Si+wJiLfMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Duration = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}), SumAllDuration = Table.AddColumn ( #"Changed Type", "SumDuration", each List.Accumulate(List.Transform(Text.Split(_[Duration],"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c), type duration ) in SumAllDurationAs alternative you can also apply a Table.TransfromColumns. (so you don't need a additional column
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Tc3RDcAgCATQXfxuUs6q1FvFuP8atSBN/x6EO8ZIQhFC0jzMNwH3GgpLPh1wVGbsTdEXAHOLMFgRbrx6+P+gr4bvwQpbL5Si+wJiLfMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Duration = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}), SumAllDuration = Table.TransformColumns ( #"Changed Type", { "Duration", each List.Accumulate(List.Transform(Text.Split(_,"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c), type duration } ) in SumAllDurationCopy paste this code to the advanced editor in a new blank query to see how the solution works.
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy
14 Replies
- Greg_DecklerCommunity Champion
Anonymous - I did it like the following. PBIX is attached below sig, you want Table 14
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Tc3RDcAgCATQXfxuUs6q1FvFuP8atSBN/x6EO8ZIQhFC0jzMNwH3GgpLPh1wVGbsTdEXAHOLMFgRbrx6+P+gr4bvwQpbL5Si+wJiLfMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Duration = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}), #"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Duration", Splitter.SplitTextByDelimiter("/", QuoteStyle.Csv), {"Duration.1", "Duration.2", "Duration.3", "Duration.4", "Duration.5"}), #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Duration.1", type duration}, {"Duration.2", type duration}, {"Duration.3", type duration}, {"Duration.4", type duration}, {"Duration.5", type duration}}), #"Replaced Value" = Table.ReplaceValue(#"Changed Type1",null,#duration(0, 0, 0, 0),Replacer.ReplaceValue,{"Duration.2", "Duration.3", "Duration.4", "Duration.5"}), #"Added Custom" = Table.AddColumn(#"Replaced Value", "Custom", each [Duration.1]+[Duration.2]+[Duration.3]+[Duration.4]+[Duration.5]), #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Duration.1", "Duration.2", "Duration.3", "Duration.4", "Duration.5"}), #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Custom", "Duration"}}) in #"Renamed Columns"- AnonymousNot applicable
Thank you Greg_Deckler . I appreciate the response. I tried copying your query changes and pasting them into the advanced editor... starting with
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}),I then changed "Duration" to elapsed time (my fields name) and a few other tweaks to make sure i wasn;t writing over or duplicating anything. Unfortunately I kept getting an error that it couldn't find that field name. I've created a sample pibx with some of my timestamp data but I'm not sure how to upload that.
- Greg_DecklerCommunity Champion
Anonymous - Let's try it like this:
- Start with your column of values as Text
- Select your column in Power Query Editor
- From the Transform tab, choose Split Column, choose Custom and enter /
- Select all of the columns created, use the Ctrl or Shift keys
- Right-click a column header and choose Change Type and then Duration
- Select all of these columns again
- Right-click a column header and choose Replace Values, enter null and 0
- From Add column tab, choose Custom Column. Select each of the columns created and put a + between them, [Duration.1]+[Duration.2]+[Duration.3], etc.
- Select all of the intermediary columns created (not our Custom column), right-click a column header and choose Delete
- Double-click our Custom column header and rename to the original column name
Those are the steps that I did to create the query that I posted.
- ziying35Impactful Individual
try this:
- AnonymousNot applicable
ziying35 That I can do. It's the splitting and summing that I have to do first that is defeating me. Thank you
- Jimmy801Community Champion
Hello Anonymous
add a custom column and add this function. Column name has to be "Duration" and formated as text
List.Accumulate(List.Transform(Text.Split(_[Duration],"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c)Here the complete example for reproducing it
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Tc3RDcAgCATQXfxuUs6q1FvFuP8atSBN/x6EO8ZIQhFC0jzMNwH3GgpLPh1wVGbsTdEXAHOLMFgRbrx6+P+gr4bvwQpbL5Si+wJiLfMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Duration = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}), SumAllDuration = Table.AddColumn ( #"Changed Type", "SumDuration", each List.Accumulate(List.Transform(Text.Split(_[Duration],"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c), type duration ) in SumAllDurationAs alternative you can also apply a Table.TransfromColumns. (so you don't need a additional column
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Tc3RDcAgCATQXfxuUs6q1FvFuP8atSBN/x6EO8ZIQhFC0jzMNwH3GgpLPh1wVGbsTdEXAHOLMFgRbrx6+P+gr4bvwQpbL5Si+wJiLfMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Duration = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Duration", type text}}), SumAllDuration = Table.TransformColumns ( #"Changed Type", { "Duration", each List.Accumulate(List.Transform(Text.Split(_,"/"), each Duration.From(_)),#duration(0,0,0,0), (s,c)=> s + c), type duration } ) in SumAllDurationCopy paste this code to the advanced editor in a new blank query to see how the solution works.
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy- AnonymousNot applicable
Thanks for helping out Jimmy801
I have tried both of your suggestions and here is what I run into.
Creating custom field: I get no syntax errors, hit ok then it creates a new Duration column. The values that are already in hh:mm:ss format all seem to be summing properly into this one field, which is AWESOME! The only issue I still have is that all of the Date/Time entries show "error" in this new field. Here is the error it states:
Expression.Error: We couldn't parse the Duration literal.
Details:
1899 12:05:19 AMThe fact that the repeat values are summing now is amazingly helpful even with the other errors. I feel like I can probably work around those and end up combining two clean columns at the end. Hopefully.
I did also try the 2nd suggestion but it went straight to error:
Expression.Error: The column 'Duration' of the table wasn't found.
Details:
DurationYour first suggestion seems to be getting me in the right direction though. Am I correct in my assumption that I can use the newly column, then work on splittging/extracting out the 12/31/1899 12:00:00 times in the original column, then combine the two columns? Of course, I'm all ears if there is a better way.
Thanks guys for all your help. I am soooo close I can feel it. I was supposed to have these reports turned in last Friday. Our data is just disgustingly messy. Have already spent two weeks just trying to clean it up.
- Jimmy801Community Champion
Hello Anonymous
I think your errors coming coming from the autoformatting of Power BI. Please import the data and don't apply any type changes, because as you were stating in your first post, that your Excel-column is consisting of only duration, sometimes even more than one duration in one cell, combined with "/".
The other error you get is because you are referencing a column called "Duration", that probably in your database is not existing. Just adapt the column name in my formula, thats it.
all the best
Jimmy