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

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
tonyclifton
Helper III
Helper III

Count Products over time dealing with two date fields

Hello community,

I need to calculated the count of products over time (months for now, maybe with daily accuracy). I want to show the increase or decrease of products based on when they were "added" and/or "removed".

Example:

tonyclifton_0-1707390597434.png


This is how I think the calculation should be:

tonyclifton_2-1707390964875.png

Not sure about 2024-01: maybe a date selection is also required for a day comparision.
I created a calendar table for selection but I'm stuck with the calculation because two dates need to be dealt with (or DiscontinuedDate is NULL) and when I do something like below it always returns the same values for each month:
PARALLELPERIOD('Calendar'[Date],-1,MONTH))

I also have the same CreatedDates and DiscontinuedDates multiple times which throws an error (duplicate dates) when I use PARALLELPERIOD.

Any tips on how this can be achived are highly appreciated.

Thanks in advance.


 

1 ACCEPTED SOLUTION

@tonyclifton 

 

tried it .

did work from my side . ( change my table to query2 , since i already have a table called exp_table)

 

Daniel29195_0-1707482313869.png

 

 

ok i think i know the problem you are encountering . 

change the code to this : 

count of active products per day new = 

var calendar_per_product = 
FILTER(
GENERATE(
    all(Query2[product]),
    var pr = Query2[product]
    var createddate = SELECTCOLUMNS(FILTER(Query2,Query2[product] = pr),"createddate",Query2[createddate])
    var enddate = SELECTCOLUMNS(FILTER(Query2,Query2[product] = pr),"enddate",Query2[enddate])
    return
    CALENDAR(
        if(
            ISBLANK(createddate)  , DATEVALUE("2024-01-01"),createddate)
        ,
        if(
            ISBLANK(enddate)  , DATEVALUE("2024-12-31"),enddate)
        )
    ),
    NOT ISBLANK(Query2[product])
)

var gds = 
GROUPBY(
    calendar_per_product,
    [Date],
    "c", countx(CURRENTGROUP() , DISTINCTCOUNT(Query2[product]))
)

var res=
MAXX(
    FILTER(gds,[Date] in  VALUES(dimdate[Date])),
    [c])
    
    return res

 

View solution in original post

13 REPLIES 13
Ashish_Mathur
Super User
Super User

Hi,

Follow the instructions mentioned here - Generating Rows by Month for Date Ranges in Power Query | by Daniel Marsh-Patrick | Daniel Marsh-Pat...

Hope this helps.


Regards,
Ashish Mathur
http://www.ashishmathur.com
https://www.linkedin.com/in/excelenthusiasts/
Daniel29195
Super User
Super User

JHello @tonyclifton ,

 

if you could provide some sample data, that would be helpful.

 

 

How to provide sample data in the Power BI Forum
https://community.fabric.microsoft.com/t5/Community-Blog/How-to-provide-sample-data-in-the-Power-BI-...

 

 

How to Get Your Question Answered Quickly
https://community.fabric.microsoft.com/t5/Desktop/How-to-Get-Your-Question-Answered-Quickly/m-p/1447...

 

 

Hello @Daniel29195 


The table below pretty much sums up my problem because I don't see how to dynamically calculate the valid date range and then show the differences over the months.


Example data:

ProductCreatedDateDiscontinuedDate
A01.01.2023 
B01.01.202431.01.2024
C03.01.202430.06.2024
D04.01.202431.12.2024


The problem I see is that I would need to calculate a valid date range for both dates so that I can show the changes over time.
With the link provided by @Ashish_Mathur I might create other problems by duplicating rows in the source. I will have a closer look though - it might work by using it as a lookup table or so.

Isn't there a way with DAX to dynamically calculate the valid date range?

Thanks alot.

@tonyclifton 

base on this sample data : 

Daniel29195_0-1707477938099.png

 

 

this is the dax code in case you want to expand your data and get the number of active products per day :  ( NB if enddate is blank i took the date to be 2024-12-31 , but it can be changed to take any dynamic value ) 

tttr = 

var calendar_per_product = 
FILTER(
GENERATE(
    VALUES(exp_table[product]),
    var pr = exp_table[product]
    var createddate = SELECTCOLUMNS(FILTER(exp_table,exp_table[product] = pr),exp_table[createddate])
    var enddate = SELECTCOLUMNS(FILTER(exp_table,exp_table[product] = pr),exp_table[enddate])
    return
    CALENDAR(
        if(
            ISBLANK(createddate)  , DATEVALUE("2024-01-01"),createddate)
        ,
        if(
            ISBLANK(enddate)  , DATEVALUE("2024-12-31"),enddate)
        )
    ),
    NOT ISBLANK(exp_table[product])
)

var gds = 
GROUPBY(
    calendar_per_product,
    [Date],
    "c", countx(CURRENTGROUP() , DISTINCTCOUNT(exp_table[product]))
)

    return gds

 

 

output table : 

Daniel29195_1-1707477972447.png

 

 

 

let me know if this can help.

 

 

 

@tonyclifton 

if you dont want to create a table : 

this is the measure you can use : 

sample data : 

Daniel29195_3-1707478765866.png

 

output :  as you can see, base on the sample data, you have in 2024-01-03 , 3 products active, which is displayed in the visual.

Daniel29195_2-1707478752627.png

 

 

measure : 

count of active products per day = 

var calendar_per_product = 
FILTER(
GENERATE(
    all(exp_table[product]),
    var pr = exp_table[product]
    var createddate = SELECTCOLUMNS(FILTER(exp_table,exp_table[product] = pr),exp_table[createddate])
    var enddate = SELECTCOLUMNS(FILTER(exp_table,exp_table[product] = pr),exp_table[enddate])
    return
    CALENDAR(
        if(
            ISBLANK(createddate)  , DATEVALUE("2024-01-01"),createddate)
        ,
        if(
            ISBLANK(enddate)  , DATEVALUE("2024-12-31"),enddate)
        )
    ),
    NOT ISBLANK(exp_table[product])
)

var gds = 
GROUPBY(
    calendar_per_product,
    [Date],
    "c", countx(CURRENTGROUP() , DISTINCTCOUNT(exp_table[product]))
)

var res=
MAXX(
    FILTER(gds,[Date] in  VALUES(dimdate[Date])),
    [c])
    
    return res

 

 

 

NB: dimdate should not be linked to the table dim_products. 

Daniel29195_4-1707478873850.png

 

 

and the visual is reading date from dimdate. 

 

 

NB: the measure may need some minor tweakings that i didnt do, just to know if this would be helpful to you . 

 

 

 

@Daniel29195thanks alot for your effort. I just tried to replicate your example with the same sample data but I get an error:

 

tonyclifton_1-1707480651939.png

 

tonyclifton_2-1707480672823.png

What am I missing?
Thank you.

@tonyclifton 

 

im not sure.  do you think it is possible to share the file so i can take a look ? 

I use below code for the table creation and call the table "exp_table" just like in your example.
For the measure I just pasted your code from above.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIw1AMiIwMjYyBHQSlWJ1rJCVnYBMgxRnBA8s4geWNkeQM9AzOEvAtI3gRVv6ERVD4WAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Product = _t, createddate = _t, enddate = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"createddate", type datetime}, {"enddate", type datetime}})
in
    #"Changed Type"

 

@tonyclifton 

 

tried it .

did work from my side . ( change my table to query2 , since i already have a table called exp_table)

 

Daniel29195_0-1707482313869.png

 

 

ok i think i know the problem you are encountering . 

change the code to this : 

count of active products per day new = 

var calendar_per_product = 
FILTER(
GENERATE(
    all(Query2[product]),
    var pr = Query2[product]
    var createddate = SELECTCOLUMNS(FILTER(Query2,Query2[product] = pr),"createddate",Query2[createddate])
    var enddate = SELECTCOLUMNS(FILTER(Query2,Query2[product] = pr),"enddate",Query2[enddate])
    return
    CALENDAR(
        if(
            ISBLANK(createddate)  , DATEVALUE("2024-01-01"),createddate)
        ,
        if(
            ISBLANK(enddate)  , DATEVALUE("2024-12-31"),enddate)
        )
    ),
    NOT ISBLANK(Query2[product])
)

var gds = 
GROUPBY(
    calendar_per_product,
    [Date],
    "c", countx(CURRENTGROUP() , DISTINCTCOUNT(Query2[product]))
)

var res=
MAXX(
    FILTER(gds,[Date] in  VALUES(dimdate[Date])),
    [c])
    
    return res

 

Thank you very much. It works now with the sample data.
Before I'll try to put this in my real data report can you tell me how to deal with adding slicers that affect the calculation?
For example, with the sample data, if I use CreatedDate as a slicer or have another column like "plant" it will always output a different calculation for each month - compared to not being filtered at all.

tonyclifton_0-1707486641752.png

 

tonyclifton_1-1707486650640.png


Any ideas how to deal with that?
Thank you.

@tonyclifton 

for date, you should filter from dimdate  and not createddate . 

 

because the code works base on the dimdate . 

I agree with dimdate but what about filtering by other columns of the original table like Plant for example?

tonyclifton_0-1707487790347.png

 

@tonyclifton 

i cant tell, since i dont have an idea how the model is structured. 

but i assume it should work, if you have plant column that already filters the data .

 

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

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

April Fabric Community Update

Fabric Community Update - April 2024

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