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
The business wants to be able to see the total AR by age, trended over time or at any point in time for the recent history.
If you have been working with financial data, you likely already have some kind of aging buckets in your Dates Table. However, as we need to be able to evaluate the age at past points in time, these won’t work, because the age is typically tied to that date records distance from “today”. So we will need a novel solution to solve this problem.
I say “My Solution” as it may in fact not be the only, or even best solution. This worked and made sense to me, but I welcome and feedback on better or more simplistic solutions.
We will need to create 3 key things:
Since we cannot use Aging Buckets that may already be in the Dates Table, we will need new ones. For this, I created a new table with 2 columns called “Financial Aging Buckets”.
For this, I created a new Dates Table called “Financial Aging”.
I only brought in 2 columns, the DateKey and the DateValue. I brought the table in from an SQL warehouse, but if you use Power Query to create the Date Table, then you only need the Date Value, as that will be used to join to the existing Dates Table.
Here are the details:
#"Added 31-60" = Table.AddColumn(#"Renamed Columns", "31 - 60 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -31 )),
#"Added 61-90" = Table.AddColumn(#"Added 31-60", "61 - 90 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -61 )),
#"Added 91-120" = Table.AddColumn(#"Added 61-90", "91 - 120 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -91 )),
#"Added 121-150" = Table.AddColumn(#"Added 91-120", "121 - 150 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -121 )),
#"Added 151-180" = Table.AddColumn(#"Added 121-150", "151 - 180 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -151 )),
#"Added 181-365" = Table.AddColumn(#"Added 151-180", "181 - 365 Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -181 )),
#"Added >1 Y" = Table.AddColumn(#"Added 181-365", "> 1 Year Range Upper", each Date.AddDays([#"0 - 30 Range Upper"], -366 )),
The measure will use a SWITCH function with SELECTEDVALUE to determine which Bucket from “Financial Aging Buckets” it is in, and then calculate the amount, filtering each Age Bucket differently using the appropriate combination of Age Range Upper columns from the “Financial Aging” Dates Table.
The SELECTEDVALUE uses the "Order" column from the “Financial Aging Buckets” table so that I do not have to do any string comparisons. I think it is cleaner.
Each calculation in the SWITCH SUMs the Total AR with a different filter applied. The KEEPFILTERS filters to where the "Invoice Date" (In my code, it is "Date Value Date of Serivce") is (Between) <= MAX Range Upper of the current age bucket, and > MAX Range Upper of the next older age bucket.
Gross AR Aging =
VAR _Measure =
CALCULATE(
SWITCH(
SELECTEDVALUE('Financial Aging Buckets'[Financial Aging Buckets (order)] )
, 7
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[> 1 Year Range Upper] ) )
)
, 6
, CALCULATE( [Gross AR (Toggle)]
,KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[181 - 365 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[> 1 Year Range Upper] ) )
)
, 5
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[151 - 180 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[181 - 365 Range Upper] ) )
)
, 4
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[121 - 150 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[151 - 180 Range Upper] ) )
)
, 3
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[91 - 120 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[121 - 150 Range Upper] ) )
)
, 2
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[61 - 90 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[91 - 120 Range Upper] ) )
)
, 1
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[31 - 60 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[61 - 90 Range Upper] ) )
)
, 0
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[0 - 30 Range Upper] ) && 'Financial Transactions'[Date Value Date of Service] > MAX( 'Financial Aging'[31 - 60 Range Upper] ) )
)
, CALCULATE( [Gross AR (Toggle)]
, KEEPFILTERS( 'Financial Transactions'[Date Value Date of Service] <= MAX( 'Financial Aging'[0 - 30 Range Upper] ) )
)
)
, KEEPFILTERS( Dates[DateValue] <= MAX( Dates[DateValue] ) )
)
RETURN _Measure
The measure requires the “Financial Aging Buckets” to be present in the visual in order for the SELECTEDVALUE function to work (Or, you could use a single-select slicer). For the Matrix I put it in the rows, and for the Stacked Area chart, the Legend.
I hope someone out there has found this helpful, and Happy Aging!
Thank you for all your sharing!
The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!
| User | Count |
|---|---|
| 41 | |
| 38 | |
| 36 | |
| 30 | |
| 28 |
| User | Count |
|---|---|
| 128 | |
| 88 | |
| 79 | |
| 67 | |
| 62 |