After trying a lot of approaches and formulas I decided to ask this question.
See this Matrix visual:
WeekDate
is column in a table called Planning
. It's related to another date time column Week_Imported
in another table called Export
.
Export
table only has values for the dates: 23-Dec-19, 30-Dec-19 and 06-Jan-20 whereas Planning
table has dates spanning multiple weeks in the past and future.
Cumulative Plan Count
is calculating correctly as long as there are matching dates between the tables Planning
and Export
.
Now I'd like to keep calculating even when there's no date matching. I want to get the value 32
from the FIRSTDATE
which has data (in this case 23-Dec-2019) and backfill the past with 32
.
For dates in the future I'd like to use LASTDATE
(06-Jan-20) value which is 89
.
Something like this:
WeekDate Cumulative Plan Count
.
.
.
25-Nov-19 32
02-Dec-19 32
09-Dec-19 32
16-Dec-19 32
23-Dec-19 32 <= First WeekDate which has data [backfill past with 32]
30-Dec-19 57
06-Jan-19 89 <= Last WeekDate which has data [fill future with 89]
13-Jan-20 89
20-Jan-20 89
27-Jan-20 89
.
.
.
The formula used for the cumulative SUM
is this:
Cumulative Plan Count =
CALCULATE (
ROUNDUP([1 - Target] * MAX(Planning[1 - Plan]), 0)
,
FILTER (
ALL ( Planning[WeekDate] ),
Planning[WeekDate] <= MAX(Planning[WeekDate])
)
)
####### Edit 1 #######
Using this measure below I get 1s for the past...
1 - Target =
VAR minWeek = MIN(Export[Week_Imported])
VAR targetCount =
CALCULATE (
COUNT( 'Export'[1 - Plan]),
FILTER('Export', OR(Export[1 - Plan]="YES", Export[1 - Plan]="_")))
var minTarget = CALCULATE (
COUNT( 'Export'[1 - Plan]),
FILTER('Export', OR(Export[1 - Plan]="YES", Export[1 - Plan]="_")
&& Export[Week_Imported] = minWeek))
RETURN
SWITCH(TRUE,
targetCount = BLANK(), 1, // Here is where I need to get the 1st row value (32) and fill up the column up above...
targetCount)
The problem is that no matter what I do I can't get the 1st value for 23-Dec-2019 (32) to fill up the Cumulative Plan Count column.
This is the result when I use the formula above:
WeekDate Cumulative Plan Count
.
.
.
25-Nov-19 1
02-Dec-19 1
09-Dec-19 1
16-Dec-19 1
23-Dec-19 32 <= First WeekDate which has data
30-Dec-19 57
06-Jan-19 89 <= Last WeekDate which has data
13-Jan-20 89
20-Jan-20 89
27-Jan-20 89
.
.
.
####### Edit 2 #######
I put together a simplified Sample.pbix which shows what I'm trying to accomplish with minimum data to test things: https://drive.google.com/drive/folders/1zxS_2VE9_0JEMXvsg9Dq196BK552RbNo?usp=sharing
This screenshot has more details: https://drive.google.com/open?id=1_-IMEpLwuWWN6vrrT_TNWbeqZ7f1LOan
Let me introduce the solution with intermediate steps.
In your data schema, Planning
and Export
tables are in one to many relationship. Planning
is in the grain of every week, while Export
has more rows for each week.
On this basis, the measure to count the number of Export
rows for each Planning
week is as simple as this.
Plan Count (Basic) = COUNTROWS ( 'Export' )
When you slice by Planning[WeekDate]
, this measure returns the counts of Export
rows for the corresponding weeks.
Actually, you need FILTER
to count only rows you are interested in.
Plan Count =
COUNTROWS (
FILTER (
'Export',
OR ( 'Export'[Plan] = "YES", 'Export'[Plan] = "_" )
)
)
Here is the result we get so far.
Having this measure as the starting point, we need to extend the calculation to the periods where the data does not exist. In order to do that, we need to handle the filter context where [Plan Count]
is evaluated.
We need to get the first and final weeks where Export
data exists. Here is a formula that returns the first date of the data regardless of the slicer.
First Data Week =
CALCULATE (
MIN ( Planning[WeekDate] ),
REMOVEFILTERS ( Planning[WeekDate] ),
TREATAS (
CALCULATETABLE (
VALUES ( 'Export'[Week_Imported] ), -- Foreign key referencing Planning[WeekDate]
REMOVEFILTERS ( Planning )
),
Planning[WeekDate]
)
)
We can use this date to modify the filter context to calculate [Plan Count]
of the first data week. In fact, below measure always returns 1064, which is the number of [Plan Count]
in December 30, 2019.
First Week Plan Count =
VAR _FirstDataWeek = CALCULATE (
MIN ( Planning[WeekDate] ),
REMOVEFILTERS ( Planning[WeekDate] ),
TREATAS (
CALCULATETABLE (
VALUES ( 'Export'[Week_Imported] ),
REMOVEFILTERS ( Planning )
),
Planning[WeekDate]
)
)
RETURN
CALCULATE (
[Plan Count],
Planning[WeekDate] = _FirstDataWeek
)
Using this technique, we can expand the first and final values of [Plan Count]
to the past and the future dates. Below is the final formula, which iterates over Planning
table, and apply different filter context to calculate [Plan Count]
.
Extended Plan Count =
-- Planning[WeekDate] values where Export data exists
VAR _DataWeeks = CALCULATETABLE (
VALUES ( Planning[WeekDate] ),
REMOVEFILTERS ( Planning[WeekDate] ),
TREATAS (
CALCULATETABLE (
VALUES ( 'Export'[Week_Imported] ), -- Foreign key referencing Planning[WeekDate]
REMOVEFILTERS ( Planning )
),
Planning[WeekDate]
)
)
-- First and last Planning[WeekDate] where Export data exists
VAR _FirstDataWeek = MINX ( _DataWeeks, [WeekDate] )
VAR _FinalDataWeek = MAXX ( _DataWeeks, [WeekDate] )
-- [Plan Count] values of first and last weeks
VAR _FirstDataWeekPlanCount = CALCULATE ( [Plan Count], Planning[WeekDate] = _FirstDataWeek )
VAR _FinalDataWeekPlanCount = CALCULATE ( [Plan Count], Planning[WeekDate] = _FinalDataWeek )
RETURN
SUMX (
Planning,
SWITCH (
TRUE,
Planning[WeekDate] < _FirstDataWeek, _FirstDataWeekPlanCount,
Planning[WeekDate] > _FinalDataWeek, _FinalDataWeekPlanCount,
[Plan Count]
)
)