Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.
Register now!The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more
Need to rederive StartDTNew, EndDTNew based on existing StartDT and EndDT - For each Date, Tool & Module. Main purpose of this solution is needed to calculate the TotalHours occupied for each Tool,Module, Day.
Source data is generated with Overlap dates, so I thought if we shifting startDT, EndDate as below records are highlated (, may be we can able to derive the utilized hours. If any solution in M language or DAX is highly appreciated.
| Date | Tool | Module | StartDT | EndDT | StartDTNew | EndDTNew | Ex - formula for StartDTNew | Ex - formula for EndDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | StartDT<EndDT then StartDT else EndDT | EndDT |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:28:30 AM | 8/24/2023 10:29:37 AM | 8/24/2023 10:28:30 AM | 8/24/2023 10:29:37 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:29:47 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:29:47 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:29:47 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:30:11 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:30:11 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:30:11 AM | 8/24/2023 10:35:13 AM | StartDT<EndDT then StartDT else EndDT | EndDT |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:13 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:13 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:28:30 AM | 8/24/2023 10:29:37 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:13 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:29:47 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:29:47 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:30:11 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
| 8/24/2023 | Lab2 | PM1 | 8/24/2023 10:30:11 AM | 8/24/2023 10:35:13 AM | 8/24/2023 10:35:36 AM | 8/24/2023 10:35:36 AM | StartDT<PreviousRecordEndDT then PreviousRecordEndDT else StartDT | EndDT>StartDTNew then EndDT else StartDTNew |
Solved! Go to Solution.
Hi @hanuraolm ,
sorry I didn't get the problem right with my first answer.
The main reason your attempt is terribly slow is probably due to the "PreviousRows"-step.
(if you need a fast way to retrieve the previous row, check out my post here: Fast and easy way to reference previous or next rows in Power Query or Power BI – (thebiccountant.co...)
My solution now returns 100k rows in under 10 seconds, so this should be good for your data hopefully as well 😉
let
Source = SourceData,
#"Added Index1" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
fnShifts = (SourceTable as table) =>
let
InputTable = Table.Buffer(SourceTable),
Custom1 = List.Generate(
() => [
StartDT = InputTable[StartDT]{0},
EndDT = InputTable[EndDT]{0},
NewStartDT = if StartDT < EndDT then StartDT else EndDT,
NewEndDT = EndDT,
Counter = 0
],
each [Counter] < Table.RowCount(InputTable),
each [
Counter = [Counter] + 1,
StartDT = InputTable[StartDT]{Counter},
EndDT = InputTable[EndDT]{Counter},
NewStartDT = if StartDT < [NewEndDT] then [NewEndDT] else StartDT,
NewEndDT = if EndDT > NewStartDT then EndDT else NewStartDT
]
)
in
Custom1,
#"Grouped Rows" = Table.Group(
#"Added Index1",
{"Date", "Tool", "Module"},
{{"All", each fnShifts(_)}}
),
#"Expanded All" = Table.ExpandListColumn(#"Grouped Rows", "All"),
#"Expanded All1" = Table.ExpandRecordColumn(
#"Expanded All",
"All",
{"NewStartDT", "NewEndDT", "Counter", "StartDT", "EndDT"}
),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded All1",{{"NewStartDT", type datetime}, {"NewEndDT", type datetime}, {"StartDT", type datetime}, {"EndDT", type datetime}})
in
#"Changed Type"
Also, check the file attached.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Hi @hanuraolm ,
you are picking the wrong table here.
My table is "ImkeResult".
Please also check columns AT-AX where I reconciled the results agains the original requirement.
If you spot differences, please provide screenshots that include all relevant columns so that we can identify what is actually going on.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Hi @hanuraolm ,
very pleased to hear 🙂
You can adjust like so:
***Grouping Logic****
#"Grouped Rows" = Table.Group(
#"Added Index1",
{"Date", "Tool", "Module"},
{{"All", each fnShifts(_)}}
),
*****Function Definition****
let
InputTable = Table.Buffer(SourceTable),
Custom1 = List.Generate(
() => [
StartDT = InputTable[StartDT]{0},
EndDT = InputTable[EndDT]{0},
NewStartDT = if StartDT < EndDT then StartDT else EndDT,
NewEndDT = EndDT,
Counter = 0
Label = InputTable[sourcelabel]{0},
Recipe = InputTable[SourceRecipe]{0}
],
each [Counter] < Table.RowCount(InputTable),
each [
Counter = [Counter] + 1,
StartDT = InputTable[StartDT]{Counter},
EndDT = InputTable[EndDT]{Counter},
NewStartDT = if StartDT < [NewEndDT] then [NewEndDT] else StartDT,
NewEndDT = if EndDT > NewStartDT then EndDT else NewStartDT
Label = InputTable[sourcelabel]{Counter},
Recipe = InputTable[SourceRecipe]{Counter}
]
)
in
Custom1,
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Hi @hanuraolm ,
yes, you gave it the name "newlot" and that's what you have to expand and transform further on 🙂
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Hi @hanuraolm ,
very pleased to hear 🙂
You can adjust like so:
***Grouping Logic****
#"Grouped Rows" = Table.Group(
#"Added Index1",
{"Date", "Tool", "Module"},
{{"All", each fnShifts(_)}}
),
*****Function Definition****
let
InputTable = Table.Buffer(SourceTable),
Custom1 = List.Generate(
() => [
StartDT = InputTable[StartDT]{0},
EndDT = InputTable[EndDT]{0},
NewStartDT = if StartDT < EndDT then StartDT else EndDT,
NewEndDT = EndDT,
Counter = 0
Label = InputTable[sourcelabel]{0},
Recipe = InputTable[SourceRecipe]{0}
],
each [Counter] < Table.RowCount(InputTable),
each [
Counter = [Counter] + 1,
StartDT = InputTable[StartDT]{Counter},
EndDT = InputTable[EndDT]{Counter},
NewStartDT = if StartDT < [NewEndDT] then [NewEndDT] else StartDT,
NewEndDT = if EndDT > NewStartDT then EndDT else NewStartDT
Label = InputTable[sourcelabel]{Counter},
Recipe = InputTable[SourceRecipe]{Counter}
]
)
in
Custom1,
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
1. group by StartDate,Site,Tool & Module
2. Need to derive recordNewStartDT, recordNewEndDT
3. recordNewStartDT is same as NewStartDT, which is derived using fnShifts function. (Code is below)
4. recordNewEndDT - this value should pickup from "NewStartDT" in the next row in a group (StartDate,Site,Tool & Module) and For the last row in this group there is no value to pickup, so recordNewEndDT is same vaue from NewStartDT.
the above loop should be repeted for each group. Is this can we manage in the same fuction, or else do we need to go other fucntion to derive these columns. Your inputs are heighly appreciated.
Thanks, you so much and I really appreciate your work. This code is working as expected with super speed.😀
Small change is required without changing the below grouping logic we need to display other attributes. Like Chamber,recipe..etc how to get those or else we need to add in in fuction definition itself as below??
***Grouping Logic****
#"Grouped Rows" = Table.Group(
#"Added Index1",
{"Date", "Tool", "Module"},
{{"All", each fnShifts(_)}}
),
*****Function Definition****
let
InputTable = Table.Buffer(SourceTable),
Custom1 = List.Generate(
() => [
StartDT = InputTable[StartDT]{0},
EndDT = InputTable[EndDT]{0},
NewStartDT = if StartDT < EndDT then StartDT else EndDT,
NewEndDT = EndDT,
Counter = 0
Label = sourcelabel
Recipe = SourceRecipe
],
each [Counter] < Table.RowCount(InputTable),
each [
Counter = [Counter] + 1,
StartDT = InputTable[StartDT]{Counter},
EndDT = InputTable[EndDT]{Counter},
NewStartDT = if StartDT < [NewEndDT] then [NewEndDT] else StartDT,
NewEndDT = if EndDT > NewStartDT then EndDT else NewStartDT
Label = sourcelabel
Recipe = SourceRecipe
]
)
in
Custom1,
Hi @hanuraolm ,
you are picking the wrong table here.
My table is "ImkeResult".
Please also check columns AT-AX where I reconciled the results agains the original requirement.
If you spot differences, please provide screenshots that include all relevant columns so that we can identify what is actually going on.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Thanks so much for you help. It’s not just previou row to pick-up.
Logic as below
Sort StarDT Asc
Group Date,tool, module For each group, may we we can generate index to refer
then Shift the StartDT, EndDT in Order for each group (or ex see the targeted output below)
Your code is producing as below
Hi @hanuraolm ,
sorry I didn't get the problem right with my first answer.
The main reason your attempt is terribly slow is probably due to the "PreviousRows"-step.
(if you need a fast way to retrieve the previous row, check out my post here: Fast and easy way to reference previous or next rows in Power Query or Power BI – (thebiccountant.co...)
My solution now returns 100k rows in under 10 seconds, so this should be good for your data hopefully as well 😉
let
Source = SourceData,
#"Added Index1" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
fnShifts = (SourceTable as table) =>
let
InputTable = Table.Buffer(SourceTable),
Custom1 = List.Generate(
() => [
StartDT = InputTable[StartDT]{0},
EndDT = InputTable[EndDT]{0},
NewStartDT = if StartDT < EndDT then StartDT else EndDT,
NewEndDT = EndDT,
Counter = 0
],
each [Counter] < Table.RowCount(InputTable),
each [
Counter = [Counter] + 1,
StartDT = InputTable[StartDT]{Counter},
EndDT = InputTable[EndDT]{Counter},
NewStartDT = if StartDT < [NewEndDT] then [NewEndDT] else StartDT,
NewEndDT = if EndDT > NewStartDT then EndDT else NewStartDT
]
)
in
Custom1,
#"Grouped Rows" = Table.Group(
#"Added Index1",
{"Date", "Tool", "Module"},
{{"All", each fnShifts(_)}}
),
#"Expanded All" = Table.ExpandListColumn(#"Grouped Rows", "All"),
#"Expanded All1" = Table.ExpandRecordColumn(
#"Expanded All",
"All",
{"NewStartDT", "NewEndDT", "Counter", "StartDT", "EndDT"}
),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded All1",{{"NewStartDT", type datetime}, {"NewEndDT", type datetime}, {"StartDT", type datetime}, {"EndDT", type datetime}})
in
#"Changed Type"
Also, check the file attached.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
thank for you help. But i'm looking something as below, need to derived newStartDT, newEndDT based on avaible startDT, endDT for each day,tool, module
source-
DateToolModuleStartDTEndDT
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:26:02 AM | 8/24/2023 11:28:29 AM |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:36:02 AM | 8/24/2023 10:46:02 AM |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 11:38:29 AM | 8/24/2023 11:40:29 AM |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:36:02 AM | 8/24/2023 10:56:02 AM |
| 8/24/2023 | Lab1 | PM2 | 8/24/2023 10:56:02 PM | 8/24/2023 11:56:02 PM |
| 8/24/2023 | Lab1 | PM3 | 8/24/2023 9:26:02 AM | 8/24/2023 10:28:29 AM |
| 8/24/2023 | Lab1 | PM3 | 8/24/2023 9:36:02 AM | 8/24/2023 9:46:02 AM |
| 8/24/2023 | Lab1 | PM3 | 8/24/2023 10:38:29 AM | 8/24/2023 10:40:29 AM |
| 8/24/2023 | Lab1 | PM3 | 8/24/2023 9:36:02 AM | 8/24/2023 9:56:02 AM |
| 8/24/2023 | Lab1 | PM3 | 8/24/2023 9:56:02 PM | 8/24/2023 10:56:02 PM |
| 8/25/2023 | Lab1 | PM2 | 8/25/2023 10:26:02 AM | 8/25/2023 11:28:29 AM |
| 8/25/2023 | Lab1 | PM2 | 8/25/2023 10:36:02 AM | 8/25/2023 10:46:02 AM |
| 8/25/2023 | Lab1 | PM2 | 8/25/2023 11:38:29 AM | 8/25/2023 11:40:29 AM |
| 8/25/2023 | Lab1 | PM2 | 8/25/2023 10:36:02 AM | 8/25/2023 10:56:02 AM |
| 8/25/2023 | Lab1 | PM2 | 8/25/2023 10:56:02 PM | 8/25/2023 11:56:02 PM |
| 8/25/2023 | Lab1 | PM3 | 8/25/2023 9:26:02 AM | 8/25/2023 10:28:29 AM |
| 8/25/2023 | Lab1 | PM3 | 8/25/2023 9:36:02 AM | 8/25/2023 9:46:02 AM |
| 8/25/2023 | Lab1 | PM3 | 8/25/2023 10:38:29 AM | 8/25/2023 10:40:29 AM |
| 8/25/2023 | Lab1 | PM3 | 8/25/2023 9:36:02 AM | 8/25/2023 9:56:02 AM |
| 8/25/2023 | Lab1 | PM3 | 8/25/2023 9:56:02 PM | 8/25/2023 10:56:02 PM |
Target
DateToolModuleIndexStartDT - CopyEndDT - CopynewStartDTnewEndDT
| 8/24/2023 | Lab1 | PM2 | 0 | 8/24/2023 10:26:02 AM | 8/24/2023 11:28:29 AM | 8/24/2023 10:26:02 AM | 8/24/2023 11:28:29 AM |
| 8/24/2023 | Lab1 | PM2 | 1 | 8/24/2023 10:36:02 AM | 8/24/2023 10:46:02 AM | 8/24/2023 11:28:29 AM | 8/24/2023 11:28:29 AM |
| 8/24/2023 | Lab1 | PM2 | 2 | 8/24/2023 10:36:02 AM | 8/24/2023 10:56:02 AM | 8/24/2023 11:28:29 AM | 8/24/2023 11:28:29 AM |
| 8/24/2023 | Lab1 | PM2 | 3 | 8/24/2023 11:38:29 AM | 8/24/2023 11:40:29 AM | 8/24/2023 11:38:29 AM | 8/24/2023 11:40:29 AM |
| 8/24/2023 | Lab1 | PM2 | 4 | 8/24/2023 10:56:02 PM | 8/24/2023 11:56:02 PM | 8/24/2023 10:56:02 PM | 8/24/2023 11:56:02 PM |
| 8/24/2023 | Lab1 | PM3 | 0 | 8/24/2023 9:26:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 9:26:02 AM | 8/24/2023 10:28:29 AM |
| 8/24/2023 | Lab1 | PM3 | 1 | 8/24/2023 9:36:02 AM | 8/24/2023 9:46:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM |
| 8/24/2023 | Lab1 | PM3 | 2 | 8/24/2023 9:36:02 AM | 8/24/2023 9:56:02 AM | 8/24/2023 10:28:29 AM | 8/24/2023 10:28:29 AM |
| 8/24/2023 | Lab1 | PM3 | 3 | 8/24/2023 10:38:29 AM | 8/24/2023 10:40:29 AM | 8/24/2023 10:38:29 AM | 8/24/2023 10:40:29 AM |
| 8/24/2023 | Lab1 | PM3 | 4 | 8/24/2023 9:56:02 PM | 8/24/2023 10:56:02 PM | 8/24/2023 9:56:02 PM | 8/24/2023 10:56:02 PM |
| 8/25/2023 | Lab1 | PM2 | 0 | 8/25/2023 10:26:02 AM | 8/25/2023 11:28:29 AM | 8/25/2023 10:26:02 AM | 8/25/2023 11:28:29 AM |
| 8/25/2023 | Lab1 | PM2 | 1 | 8/25/2023 10:36:02 AM | 8/25/2023 10:46:02 AM | 8/25/2023 11:28:29 AM | 8/25/2023 11:28:29 AM |
| 8/25/2023 | Lab1 | PM2 | 2 | 8/25/2023 10:36:02 AM | 8/25/2023 10:56:02 AM | 8/25/2023 11:28:29 AM | 8/25/2023 11:28:29 AM |
| 8/25/2023 | Lab1 | PM2 | 3 | 8/25/2023 11:38:29 AM | 8/25/2023 11:40:29 AM | 8/25/2023 11:38:29 AM | 8/25/2023 11:40:29 AM |
| 8/25/2023 | Lab1 | PM2 | 4 | 8/25/2023 10:56:02 PM | 8/25/2023 11:56:02 PM | 8/25/2023 10:56:02 PM | 8/25/2023 11:56:02 PM |
| 8/25/2023 | Lab1 | PM3 | 0 | 8/25/2023 9:26:02 AM | 8/25/2023 10:28:29 AM | 8/25/2023 9:26:02 AM | 8/25/2023 10:28:29 AM |
| 8/25/2023 | Lab1 | PM3 | 1 | 8/25/2023 9:36:02 AM | 8/25/2023 9:46:02 AM | 8/25/2023 10:28:29 AM | 8/25/2023 10:28:29 AM |
| 8/25/2023 | Lab1 | PM3 | 2 | 8/25/2023 9:36:02 AM | 8/25/2023 9:56:02 AM | 8/25/2023 10:28:29 AM | 8/25/2023 10:28:29 AM |
| 8/25/2023 | Lab1 | PM3 | 3 | 8/25/2023 10:38:29 AM | 8/25/2023 10:40:29 AM | 8/25/2023 10:38:29 AM | 8/25/2023 10:40:29 AM |
| 8/25/2023 | Lab1 | PM3 | 4 | 8/25/2023 9:56:02 PM | 8/25/2023 10:56:02 PM | 8/25/2023 9:56:02 PM | 8/25/2023 10:56:02 PM |
Code Executed -
let
Source = Excel.Workbook(File.Contents("C:\Users\xxxxx\Downloads\Sample Data.xlsx"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Grouped Rows" = Table.Group(#"Promoted Headers", {"Date", "Tool", "Module"}, {{"fff", each Table.Sort(_,{{"StartDT", Order.Ascending}}), type table [Date=date, Tool=text, Module=text, StartDT=datetime, EndDT=datetime]}}),
#"Added Index" = Table.AddColumn(#"Grouped Rows", "Custom", each Table.AddIndexColumn([fff], "Index", 0)),
#"Removed Other Columns" = Table.SelectColumns(#"Added Index", {"Custom"}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Other Columns", "Custom", {"Date", "Tool", "Module", "StartDT", "EndDT", "Index"}, {"Date", "Tool", "Module", "StartDT", "EndDT", "Index"}),
#"Duplicated Column -StartDT" = Table.DuplicateColumn(#"Expanded Custom", "StartDT", "StartDT - Copy"),
#"Duplicated Column - EndDT" = Table.DuplicateColumn(#"Duplicated Column -StartDT", "EndDT", "EndDT - Copy"),
#"Unpivoted Columns - Attribute" = Table.UnpivotOtherColumns(#"Duplicated Column - EndDT", {"Date", "Tool", "Module", "Index", "StartDT - Copy", "EndDT - Copy"}, "Attribute", "Value"),
#"Grouped Rows1" = Table.Group(#"Unpivoted Columns - Attribute", {"Date", "Tool", "Module"}, {{"all", each _, type table [Date=date, Tool=text, Module=text, Index=number, Value=datetime]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows1", "Custom1", each Table.AddIndexColumn([all], "Index1", 0)),
#"Removed Other Columns1" = Table.SelectColumns(#"Added Custom", {"Custom1"}),
#"Expanded Custom1" = Table.ExpandTableColumn(#"Removed Other Columns1", "Custom1", {"Date", "Tool", "Module", "Index", "StartDT - Copy", "EndDT - Copy", "Attribute", "Value", "Index1"}, {"Date", "Tool", "Module", "Index", "StartDT - Copy", "EndDT - Copy", "Attribute", "Value", "Index1"}),
// Define a custom function to calculate the maximum value from previous rows within the same Date, Tool, and Module group
CalculateMaxValue = (table as table, index as number, dateValue as date, toolValue as text, moduleValue as text) =>
let
// Buffer the table to improve performance
bufferedTable = Table.Buffer(#"Expanded Custom1"),
// Filter the buffered table to select relevant rows
previousRows = Table.SelectRows(bufferedTable, each [Index1] < index and [Date] = dateValue and [Tool] = toolValue and [Module] = moduleValue),
// Calculate the maximum using List.Max
max = List.Max(previousRows[Value])
in
max,
// Add the "New StartDateTime" column using the custom function
#"AddNewStartDateTime" = Table.AddColumn(#"Expanded Custom1", "NewValue", each if [Index1] = 0 then [Value] else if [Value] >= CalculateMaxValue(#"Expanded Custom1", [Index1], [Date], [Tool], [Module]) then [Value] else CalculateMaxValue(#"Expanded Custom1", [Index1], [Date], [Tool], [Module])),
#"Pivoted Column" = Table.Pivot(AddNewStartDateTime, List.Distinct(AddNewStartDateTime[Attribute]), "Attribute", "NewValue"),
#"Grouped Rows2" = Table.Group(#"Pivoted Column", {"Date", "Tool", "Module", "Index", "StartDT - Copy", "EndDT - Copy"}, {{"newStartDT", each List.Min([StartDT]), type nullable datetime}, {"newEndDT", each List.Max([EndDT]), type nullable datetime}})
in
#"Grouped Rows2"
But i'm facing lot of performence issues. let assue to process 30000 rows it self it's taking 6 hours. Can anyone help me some better solution...
Hi @hanuraolm ,
if my answer has solved your problem, please mark it as a solution.
Thanks.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
Hello @hanuraolm ,
there are many ways to solve this, but if we would exactly follow your logic, then we'd need some recursive logic here that is potentially slow.
However, Power Query has a very neat optional 5th parameter in its group function that allows a more straightforward approach here:
// Table1
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(
Source,
{
{"Date", type text},
{"Tool", type text},
{"Module", type text},
{"StartDT", type text},
{"EndDT", type text}
}
),
#"Changed Type1" = Table.TransformColumnTypes(
#"Changed Type",
{{"StartDT", type datetime}, {"EndDT", type datetime}},
"en-US"
),
#"Grouped Rows1" = Table.Group(
#"Changed Type1",
{"Tool", "Module", "EndDT"},
{
{"StartDT_new", each List.Min([StartDT]), type nullable datetime},
{"EndDT_new", each List.First([EndDT]), type nullable datetime},
{"Shift", each _}
},
0,
(x, y) => Number.From(x[EndDT] < y[EndDT] or x[Module] <> y[Module] or x[Tool] <> y[Tool])
),
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows1", "Index", 0, 1, Int64.Type),
#"Expanded Shift" = Table.ExpandTableColumn(
#"Added Index",
"Shift",
{"Date", "StartDT"},
{"Date", "StartDT"}
)
in
#"Expanded Shift"
If you want to understand more about this function, please check out this blogpost:
Table.Group: Exploring the 5th element in Power BI and Power Query – (thebiccountant.com)
Sample file is also attached.
Imke Feldmann (The BIccountant)
If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!
How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries
The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!
Check out the November 2025 Power BI update to learn about new features.
| User | Count |
|---|---|
| 10 | |
| 6 | |
| 5 | |
| 4 | |
| 2 |