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

Find everything you need to get certified on Fabric—skills challenges, live sessions, exam prep, role guidance, and more. Get started

Reply
buttercream
Frequent Visitor

Calculating Stage Duration in a Column

Hello,

 

Trying to calculate the number of business days between stages.  A SalesID is considered New until it is invoiced.  Any following  instances of "Invoiced" should be labelled Existing and should be calculated separately.  See below table for example.  The fields in red are needed as calculated columns (not measures).

 

SalesIDStageDateNew/ExistingRankDuration
10Entered4/1/2024New18
10Processed4/10/2024New213
10Invoiced4/26/2024New30
12Entered5/1/2024New13
12Processed5/3/2024New26
12Invoiced5/10/2024New30
12Returned3/1/2024Existing13
12Adjusted3/5/2024Existing214
12Invoiced3/23/2024Existing30
12Returned7/7/2024Existing11
12Researched7/8/2024Existing23
12Adjusted7/10/2024Existing316
12Invoiced7/31/2024Existing40
1 ACCEPTED SOLUTION
rajendraongole1
Super User
Super User

Hi @buttercream - Create below calcualted column to get the New/Existing

Calculated column:

NewExisting =
VAR FirstInvoiceDate =
    CALCULATE(
        MIN(Stage[Date]),
        Stage[Stage] = "Invoiced",
        ALLEXCEPT(Stage, Stage[SalesID])
    )
RETURN
    IF(
        Stage[Date] <= FirstInvoiceDate,
        "New",
        "Existing"
    )

 

rajendraongole1_0-1722621657628.png

 

create another calculated column to bring the rank

Rank =
RANKX(
    FILTER(
        Stage,
        Stage[SalesID] = EARLIER(Stage[SalesID]) &&
        Stage[NewExisting] = EARLIER(Stage[NewExisting])
    ),
    Stage[Date],
    ,
    ASC,
    DENSE
)

rajendraongole1_1-1722621749447.png

 

calcualte the duration calculated column :

Duration =
VAR CurrentDate = Stage[Date]
VAR NextDate =
    CALCULATE(
        MIN(Stage[Date]),
        FILTER(
            Stage,
            Stage[SalesID] = EARLIER(Stage[SalesID]) &&
            Stage[NewExisting] = EARLIER(Stage[NewExisting]) &&
            Stage[Rank] = EARLIER(Stage[Rank]) + 1
        )
    )
VAR BusinessDays =
    IF(
        NOT ISBLANK(NextDate),
        COUNTROWS(
            FILTER(
                ADDCOLUMNS(
                    CALENDAR(CurrentDate, NextDate),
                    "IsBusinessDay",
                    WEEKDAY([Date], 2) < 6
                ),
                [IsBusinessDay] = TRUE
            )
        ) - 1,
        0
    )
RETURN
    BusinessDays

rajendraongole1_2-1722622035468.png

 

Replace the table name as per your model.

rajendraongole1_3-1722622072476.png

 

 

Hope it works

 

 





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!





View solution in original post

3 REPLIES 3
sroy_16
Resolver II
Resolver II

Hello @buttercream 

 

There are two options for doing this. I would provide both the solutions. Try using them and see if they work.

 

Using advanced Editor in Power Query Mode.

let
Source = ... // your source step,

// Define a function to calculate business days between two dates
BusinessDaysBetween = (StartDate as date, EndDate as date) =>
let
DayCount = List.Count(List.Select(List.Dates(StartDate, Duration.Days(EndDate - StartDate) + 1, #duration(1, 0, 0, 0)), each not Date.IsInCurrentMonth(_))),
BusinessDays = List.Count(List.Select(List.Dates(StartDate, Duration.Days(EndDate - StartDate) + 1, #duration(1, 0, 0, 0)), each Date.DayOfWeek(_, Day.Monday) < 5))
in
BusinessDays,

// Add the "New/Existing" column based on your logic
AddNewExisting = Table.AddColumn(Source, "New/Existing", each if [Stage] = "Invoiced" and [Rank] > 1 then "Existing" else "New"),

// Sort the table by SalesID and Date
SortTable = Table.Sort(AddNewExisting,{{"SalesID", Order.Ascending}, {"Date", Order.Ascending}}),

// Add Rank column
AddRank = Table.Group(SortTable, {"SalesID"}, {
{"AllData", each Table.AddIndexColumn(_, "Rank", 1, 1, Int64.Type)}
}),
ExpandData = Table.ExpandTableColumn(AddRank, "AllData", {"SalesID", "Stage", "Date", "New/Existing", "Rank"}),

// Add Duration column
AddDuration = Table.AddColumn(ExpandData, "Duration", each if [New/Existing] = "Existing" then BusinessDaysBetween([Date], List.Min(Table.SelectRows(ExpandData, each [SalesID] = [SalesID] and [Rank] = [Rank] - 1)[Date])) else null, Int64.Type)
in
AddDuration

 

Using DAX:

Create a calculated Column:

New/Existing =
IF (
[Stage] = "Invoiced" && [Rank] > 1,
"Existing",
"New"
)

 

Duration =
VAR CurrentDate = [Date]
VAR PreviousDate =
CALCULATE (
MAX([Date]),
FILTER (
Table,
[SalesID] = EARLIER([SalesID]) && [Rank] = EARLIER([Rank]) - 1
)
)
RETURN
IF (
[New/Existing] = "Existing" && NOT ISBLANK(PreviousDate),
NETWORKDAYS(PreviousDate, CurrentDate),
BLANK()
)

 

Did I answer your question? Mark my post as a solution!
If I helped you, click on the Thumbs Up to give Kudos.

rajendraongole1
Super User
Super User

Hi @buttercream - Create below calcualted column to get the New/Existing

Calculated column:

NewExisting =
VAR FirstInvoiceDate =
    CALCULATE(
        MIN(Stage[Date]),
        Stage[Stage] = "Invoiced",
        ALLEXCEPT(Stage, Stage[SalesID])
    )
RETURN
    IF(
        Stage[Date] <= FirstInvoiceDate,
        "New",
        "Existing"
    )

 

rajendraongole1_0-1722621657628.png

 

create another calculated column to bring the rank

Rank =
RANKX(
    FILTER(
        Stage,
        Stage[SalesID] = EARLIER(Stage[SalesID]) &&
        Stage[NewExisting] = EARLIER(Stage[NewExisting])
    ),
    Stage[Date],
    ,
    ASC,
    DENSE
)

rajendraongole1_1-1722621749447.png

 

calcualte the duration calculated column :

Duration =
VAR CurrentDate = Stage[Date]
VAR NextDate =
    CALCULATE(
        MIN(Stage[Date]),
        FILTER(
            Stage,
            Stage[SalesID] = EARLIER(Stage[SalesID]) &&
            Stage[NewExisting] = EARLIER(Stage[NewExisting]) &&
            Stage[Rank] = EARLIER(Stage[Rank]) + 1
        )
    )
VAR BusinessDays =
    IF(
        NOT ISBLANK(NextDate),
        COUNTROWS(
            FILTER(
                ADDCOLUMNS(
                    CALENDAR(CurrentDate, NextDate),
                    "IsBusinessDay",
                    WEEKDAY([Date], 2) < 6
                ),
                [IsBusinessDay] = TRUE
            )
        ) - 1,
        0
    )
RETURN
    BusinessDays

rajendraongole1_2-1722622035468.png

 

Replace the table name as per your model.

rajendraongole1_3-1722622072476.png

 

 

Hope it works

 

 





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!





Thanks.  It works.

Helpful resources

Announcements
Europe Fabric Conference

Europe’s largest Microsoft Fabric Community Conference

Join the community in Stockholm for expert Microsoft Fabric learning including a very exciting keynote from Arun Ulag, Corporate Vice President, Azure Data.

AugPowerBI_Carousel

Power BI Monthly Update - August 2024

Check out the August 2024 Power BI update to learn about new features.

September Hackathon Carousel

Microsoft Fabric & AI Learning Hackathon

Learn from experts, get hands-on experience, and win awesome prizes.

Sept NL Carousel

Fabric Community Update - September 2024

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