Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Shape the future of the Fabric Community! Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions. Take survey.

Reply
CornelisV
Helper II
Helper II

Transpose table with calculation

Dear all,

 

I want to transpose the table:

TimePhase
01:05Start heating
05:50End heating
06:00Start Cooling
12:17

End cooling

 

Into this form:

DurationPhase
04:45Heating
06:17Cooling

 

Tim difference between end and start heating is 04:45 hours, for cooling 06:17 hours.

Could you demonstrate how to do this?

 

Best regards,

 

Cornelis

1 ACCEPTED SOLUTION

@CornelisV This will calculate the number of minutes in a column. See attached PBIX below sig.

Column = 
    VAR __Phase = [Phase]
    VAR __Current = [Date time]
    VAR __Type = 
        SWITCH( TRUE(),
            __Phase = "End heating", "Start heating",
            __Phase = "End cooling", "Start Cooling"
        )
    VAR __Result = 
        SWITCH(
            __Phase,
            "Start heating", 0,
            "Start cooling", 0,
                VAR __DateTime = [Date time]
                VAR __Result = MAXX( FILTER( ALL( 'Table' ), [Date time] < __DateTime && [Phase] = __Type ), [Date time] )
            RETURN
                __Current - __Result
        )
RETURN
    __Result * 60 * 24


Follow on LinkedIn
@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
Power BI Cookbook Third Edition (Color)

DAX is easy, CALCULATE makes DAX hard...

View solution in original post

7 REPLIES 7
v-jtian-msft
Community Support
Community Support

Hi,@CornelisV .Thank you for your reply.
During my testing, the date column was not really put into the calculation logic, it was in my case a reference column to generate the index. The most important logic is that the current row selected is calculated against the previous row if it is an odd number, as you mentioned, creating an index column as a marker to determine the order of calculation is the most important point, in my test, determining whether the index is odd or not is the key element, it doesn't matter whether the two rows of data being calculated are on the same day or not.
In my tests, determining whether the index is odd or not is the key element. You tried labeling the two rows of data before and after with a single index, which is also a viable solution (two rows of data with the same index are computed).
All in all, creating the right labeled columns is the key to solving your problem.

I hope my suggestions give you good ideas, if you have any more questions, please clarify in a follow-up reply.
Best Regards,
Carson Jian,
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Dear Carson Jian,

 

Thank you for your explanation.

I agree with you and your demonstrated steps gives me a lot of inspiration for other some issues in the Power BI.

It is not very easy for me, since I'm trying to apply process data calculation, that is different in comparison to financial data treatment.

 

Best regards,

 

Cornelis

v-jtian-msft
Community Support
Community Support

Hi,Greg_Deckler ,thanks for your concern about this issue.

Your answer is excellent!
And I would like to share some additional solutions below.
Hello,@CornelisV . I am glad to help you.

Like this?

vjtianmsft_0-1731474762663.png

This is my test data:
I'm assuming that you have multiple records like this in your real data with multiple dates
 

vjtianmsft_1-1731474785426.png

You can add a grouped sorting sequence for calculations (based on the value of index).
This way it is easier to locate and calculate when multiple records exist at the same time.

I have created a grouping sequence (assuming that each day exists and is grouped by date)

vjtianmsft_2-1731474810424.png

Create the required Duration (calculated based on whether the GroupID is an odd number (End), versus the previous column of data (Start))

vjtianmsft_3-1731474846169.png

Filtering to remove Null rows
Getting results

vjtianmsft_4-1731474871184.png


Note that Power BI Desktop does not support the Duration type of data, which is displayed as a Text/Decimal number by default.

vjtianmsft_5-1731474909931.png


So I recalculated the column [Totals Minutes], calculated the duration of each row (in minutes)

vjtianmsft_6-1731474939397.png

The results in Power BI Desktop are as follows:

vjtianmsft_7-1731474965646.png


This is my M code:

let
    Source = Excel.Workbook(File.Contents("C:\Users\username\Desktop\test_11_11.xlsx"), null, true),
    StatesTable_Sheet = Source{[Item="StatesTable",Kind="Sheet"]}[Data],
    #"Promoted Headers" = Table.PromoteHeaders(StatesTable_Sheet, [PromoteAllScalars=true]),
    #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Time", type time}, {"Phase", type text}, {"Date", type date}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Date"}, {{"DailyGroupID", each Table.AddIndexColumn(_, "Index", 0, 1, Int64.Type)}}),
    #"Expanded DailyGroupID" = Table.ExpandTableColumn(#"Grouped Rows", "DailyGroupID", {"Time", "Phase", "Index"}, {"DailyGroupID.Time", "DailyGroupID.Phase", "DailyGroupID.Index"}),
    #"Renamed Columns" = Table.RenameColumns(#"Expanded DailyGroupID",{{"DailyGroupID.Time", "Time"}, {"DailyGroupID.Phase", "Phase"}, {"DailyGroupID.Index", "GroupIndex"}}),
    CalculateDuration = Table.AddColumn(#"Renamed Columns", "Duration", each if Number.Mod([GroupIndex], 2) = 1 then Duration.From([Time] - #"Renamed Columns"[Time]{[GroupIndex]-1}) else null),
    FilteredRows = Table.SelectRows(CalculateDuration, each [Duration] <> null),
    ResultTable = Table.SelectColumns(FilteredRows, {"Duration", "Phase","Date"}),
    #"Replaced Value" = Table.ReplaceValue(ResultTable,"End heating","Heating",Replacer.ReplaceText,{"Phase"}),
    #"Replaced Value1" = Table.ReplaceValue(#"Replaced Value","End cooling","Cooling",Replacer.ReplaceText,{"Phase"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Replaced Value1",{{"Duration", type duration}}),
    #"Inserted Total Minutes" = Table.AddColumn(#"Changed Type1", "Total Minutes", each Duration.TotalMinutes([Duration]), type number)
in
    #"Inserted Total Minutes"


I shared the pbix file used for the test

I hope my suggestions give you good ideas, if you have any more questions, please clarify in a follow-up reply.
Best Regards,
Carson Jian,
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Dear @v-jtian-msft and @Greg_Deckler ,

 

Thank you very much for thinking along!

Looking at your reply, it seems a challenging task to find a proper solution.

First at all: it is correct that more than one cooling and/or heating will occur from the same table.

Likely, the solution has one drawback: it cannot make any difference when heating start at 10th November and end  at 11th November.

What about this data, where datetime is included:

DateTimeDate timePhase
10-11-202401:0510-11-2024 01:05Start heating
10-11-202405:5010-11-2024 05:05End heating
11-11-202406:0011-11-2024 06:00Start Cooling
11-11-202412:1711-11-2024 12:17End cooling
11-11-202413:0011-11-2024 13:00Start heating
12-11-202400:2912-11-2024 00:29End heating

As you can see, date and time will be helpfull, but the column with date cannot be used as anchor, so a new column may be created where ID = 1,1,2,2,3,3.

 What do you think?

 

Best regards,

 

Cornelis

@CornelisV This will calculate the number of minutes in a column. See attached PBIX below sig.

Column = 
    VAR __Phase = [Phase]
    VAR __Current = [Date time]
    VAR __Type = 
        SWITCH( TRUE(),
            __Phase = "End heating", "Start heating",
            __Phase = "End cooling", "Start Cooling"
        )
    VAR __Result = 
        SWITCH(
            __Phase,
            "Start heating", 0,
            "Start cooling", 0,
                VAR __DateTime = [Date time]
                VAR __Result = MAXX( FILTER( ALL( 'Table' ), [Date time] < __DateTime && [Phase] = __Type ), [Date time] )
            RETURN
                __Current - __Result
        )
RETURN
    __Result * 60 * 24


Follow on LinkedIn
@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
Power BI Cookbook Third Edition (Color)

DAX is easy, CALCULATE makes DAX hard...

Dear @Greg_Deckler ,

 

This is the very quick solution in one word: wow!

Thank you very much. 

One question: can you give me a clue where can I find the best documentation, url, etc how to deal with DAX programming as what you have demonstrated above? 

 

best regards,

 

Cornelis

Greg_Deckler
Super User
Super User

@CornelisV Are there more than just 1 instance of heating and cooling in the table? Do you want this in DAX or Power Query or do you not care?



Follow on LinkedIn
@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
Power BI Cookbook Third Edition (Color)

DAX is easy, CALCULATE makes DAX hard...

Helpful resources

Announcements
November Carousel

Fabric Community Update - November 2024

Find out what's new and trending in the Fabric Community.

Dec Fabric Community Survey

We want your feedback!

Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.