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
Fin-DuS
New Member

Calculating monthly or yearly costs based on single "monthly cost definition"

Hi Power BI Pros!

 

I have a problem and cant figure out the correct solution.

 

I have a table called Software that looks like this:

 

softwareIdnameinitialPricemonthlyPricepurchaseDatelicenseValidUntilcategory
1O365 License1003501.1.202131.7.2021User
2Contoso X 20017.2.2021 User
3XYZ500 1.9.202130.8.2022Internal
4ABC 500  Datacenter
5ETC10005020.5.202028.4.2021User

 

What I needed now was to create a view based on these definitions, so I created a dax calendar table and the first thought was for each day calculate the cost (monthly costs always at the first day of the month). But then I just had a sum per day and I was not able to place any legend on these visuals for category i.e.

 

Then I created a measure that calculates that and in the visual I just show the specific month so the measure should get applied correctly.

 

Here are the measures that I wrote:

 

 

InitialPriceSumPerMonth = CALCULATE(
    SUM('software'[initialPrice]),
    FILTER('software',DATE(YEAR('software'[purchaseDate]),MONTH('software'[purchaseDate]),1) = MIN('software cost (calendar)'[Date]))
)

 

Here I check all the initial costs of the current filtered month using the calendar table.

 

 

MonthlyPriceSumPerMonth = 
    CALCULATE(
        sum('software'[monthlyPrice]),
        filter('software', 
            and(
                or(
                    date(year('software'[purchaseDate]),month('software'[purchaseDate]),1) <= min('software cost (calendar)'[Date]),
                    isblank('software'[purchaseDate])
                ),
                or(
                    date(year('software'[licenseValidUntil]),month('software'[licenseValidUntil]),1) >= date(year(max('software cost (calendar)'[Date])),month(max('software cost (calendar)'[Date])),1),
                    isblank('software'[licenseValidUntil])
                )
            )
        )
    )

 

With this measure I sum all monthy costs of all softwares that are >= purchase date month and <=  licenseValidUntil.

 

 

TotalPricePerMonth = [InitialPriceSumPerMonth] + [MonthlyPriceSumPerMonth]

 

 Thats just the sum of both to show it in different visuals.

 

But now other people want to see this data summed quarterly or yearly.

I know that with a lot more calculation it should be possible to archive these results for years and quarters as well but I am wondering if there isnt a better way to do it.

 

Does somebody has an idea or had the same situation? Thank you!

1 ACCEPTED SOLUTION
Fin-DuS
New Member

Thanks for the advice @parry2k , luckily I did some more research and came accross this post

https://community.powerbi.com/t5/Desktop/Splitting-Values-between-months-of-two-dates/td-p/180075

and that pointed me into the right direction.

 

For reference, here is the DAX that I used now:

 

Creating a new calendar table:

 

software cost (calendar) = 
var s = date(2016,1,1)
var e = now()
return CALENDAR(date(year(s),month(s),1),date(year(e),month(e+1),1))

 

And then crossjoin to the software table:

 

software cost (history) = 
SUMMARIZE(
    FILTER(
        CROSSJOIN('software','software cost (calendar)'), // cross joining the software with the calendar table (to iterate the months where a software was active
        (
               'software cost (calendar)'[Date] >= date(year('software'[purchaseDate]),month('software'[purchaseDate]),1) // join all the dates after the software was purchased
            || isblank('software'[purchaseDate]) // or join if there is no purchase date (software have been there for ever and all time (so lets use the first possible date from the calendar table)
        )
        && (
               'software cost (calendar)'[Date] <= date(year('software'[licenseValidUntil]),month('software'[licenseValidUntil]),1)  // join all the dates untill software is valid
           || isblank('software'[licenseValidUntil]) // or join to the last possible date because its never be valid (set to null)
        )
        && (
               'software cost (calendar)'[Date].[Tag] = 1 // join only the first month (we only have monthly, not daily prices
           || 'software cost (calendar)'[Date] = 'software'[purchaseDate] // or join if we are at the purchase date
        ) 
    ),
'software'[softwareId],'software cost (calendar)'[Date] // show only needed columns
)

 

And with that data I was able to create the needed columns and created a relation between software and software history.

 

 

 

 

 

View solution in original post

2 REPLIES 2
Fin-DuS
New Member

Thanks for the advice @parry2k , luckily I did some more research and came accross this post

https://community.powerbi.com/t5/Desktop/Splitting-Values-between-months-of-two-dates/td-p/180075

and that pointed me into the right direction.

 

For reference, here is the DAX that I used now:

 

Creating a new calendar table:

 

software cost (calendar) = 
var s = date(2016,1,1)
var e = now()
return CALENDAR(date(year(s),month(s),1),date(year(e),month(e+1),1))

 

And then crossjoin to the software table:

 

software cost (history) = 
SUMMARIZE(
    FILTER(
        CROSSJOIN('software','software cost (calendar)'), // cross joining the software with the calendar table (to iterate the months where a software was active
        (
               'software cost (calendar)'[Date] >= date(year('software'[purchaseDate]),month('software'[purchaseDate]),1) // join all the dates after the software was purchased
            || isblank('software'[purchaseDate]) // or join if there is no purchase date (software have been there for ever and all time (so lets use the first possible date from the calendar table)
        )
        && (
               'software cost (calendar)'[Date] <= date(year('software'[licenseValidUntil]),month('software'[licenseValidUntil]),1)  // join all the dates untill software is valid
           || isblank('software'[licenseValidUntil]) // or join to the last possible date because its never be valid (set to null)
        )
        && (
               'software cost (calendar)'[Date].[Tag] = 1 // join only the first month (we only have monthly, not daily prices
           || 'software cost (calendar)'[Date] = 'software'[purchaseDate] // or join if we are at the purchase date
        ) 
    ),
'software'[softwareId],'software cost (calendar)'[Date] // show only needed columns
)

 

And with that data I was able to create the needed columns and created a relation between software and software history.

 

 

 

 

 

parry2k
Super User
Super User

@Fin-DuS it will be easier if you throw a sample data and expected output. Very hard to follow the whole post. Read this post to get your answer quickly.

https://community.powerbi.com/t5/Community-Blog/How-to-Get-Your-Question-Answered-Quickly/ba-p/38490



Subscribe to the @PowerBIHowTo YT channel for an upcoming video on List and Record functions in Power Query!!

Learn Power BI and Fabric - subscribe to our YT channel - Click here: @PowerBIHowTo

If my solution proved useful, I'd be delighted to receive Kudos. When you put effort into asking a question, it's equally thoughtful to acknowledge and give Kudos to the individual who helped you solve the problem. It's a small gesture that shows appreciation and encouragement! ❤


Did I answer your question? Mark my post as a solution. Proud to be a Super User! Appreciate your Kudos 🙂
Feel free to email me with any of your BI needs.

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.