Historical Memberships 2


In a previous post I covered how to show historical membership dates, but that referred specifically to the Bromcom MAT Vision dataset, and I’ve since found out a more elegant way of writing the measures, hat tip @JonnySBristol so I’ll recap briefly in the first section of this post, then cover some new techniques in sections 2 and 3.

1 Calculate historical memberships from an enrolments table.
My sample data set is structured as a students table with ID, name and gender and an enrolments table with studentid, StartDate and EndDate. This is better than having date of entry/leaving on the students table because it can accurately record a student leaving, then rejoining school.

As well as the student and enrolments table we create a DateRef table, via modelling New Table (more details in this in post 1).

Table from DAX
DateRef = CALENDAR(“01/01/2016”,TODAY())
Measures:
MaxDate = MAX(DateRef[Date])
MinDate = MIN(DateRef[Date])
We don’t need to relate DateRef (although we can, and I usually directly link it to my attendance table). All we need are MaxDate and MinDate which we’ll dynamically set using a date slider on the field DateRef[Date].

Historical Memberships
Once you have this set up you can write a measure for counting students who were on roll between your two dates.

StudentsOnRoll = CALCULATE(COUNTROWS(Students),
FILTER(Enrolments,AND(Enrolments[StartDate]<=[MaxDate],OR(Enrolments[EndDate]>=[MinDate],ISBLANK(Enrolments[EndDate])))))

CALCULATE allows us to perform an operation within the context of additional filters we supply (note that unless you say otherwise filters that exist from your report/page/slicers/row context will also apply).

Crucially for our purposes here, those filters can be applied to related tables and passed the table we are calculating. So our filter for enrolments that fall within our date range is passed to the students to whom those enrolments belong.

Single Date Filter
If you’re not interested in a range but only students on roll on a particular date, then change your slicer type to Before and use MaxDate in place of MinDate in the measure.

2 Calculating PP Eligibility
Pupil Premium  Eligibility (or any other changeable contextual factor) can be worked out in exactly the same way provided you have a table with studentids, start and end dates. We can use our existing on roll measure as the base (so we don’t have to type out the on roll filter again). Hence:

PPStudents = CALCULATE([StudentsOnRoll],
FILTER(PPDates,AND(PPDates[StartDate]<=[MaxDate],OR(PPDates[EndDate]>=[MinDate],ISBLANK(PPDates[EndDate]))))
)

Now moving the date slicer will show in this measure a count of students who were on roll and eligible for the PP.

If you want to see who the kids are then just create a table with the data you want from Students and add the PPStudents measure – by default it will only show those where the measure is not blank (ie PP = true).

Calculating Non PP Eligibility
How about the reverse case – students who are not eligible for the PP at a particular point in time. We can work this out using a couple of new formulas CALCULATETABLE – which works just CALCULATE but instead of returning a single value from a filter context it returns a table. And EXCEPT. Except takes two tables as arguments and gives you all the rows from the first (‘left’) table that don’t appear on the second (‘right’) table.

NotPPStudents =
CALCULATE([StudentsOnRoll],
EXCEPT(CALCULATETABLE(Students,FILTER(Enrolments,AND(Enrolments[StartDate]<=[MaxDate],OR(Enrolments[EndDate]>=[MinDate],ISBLANK(Enrolments[EndDate]))))),
CALCULATETABLE(Students,FILTER(PPDates,AND(PPDates[StartDate]<=[MaxDate],OR(PPDates[EndDate]>=PPDates[StartDate],ISBLANK(PPDates[EndDate]))))))
)

3 Date Sensitive Filtering
This is all fine if we know in advance what data we want to show – but what about slicers to allow our users to filter on date sensitive factors? You might think we could create calculated columns using our measures and slice on them but that won’t work because calculated columns are worked out without reference to slicer values – so they wouldn’t respond dynamically to our Min and Max date values.

There is a fix for this but, as we’ll see, it won’t let you go wild with the number of slicers you can place. Basically what we’re going to do is creating a floating table a bit like DateRef and refer to the SELECTEDVALUE from that in measure logic.
Create a table from the modelling tab:

PPSwitch = DATATABLE("PP",STRING,
            {
                {"Y"},
                {"N"}
            }
)

That’s a dead simple, 1 column table with possible values Y or N. We don’t need to relate it to anything, just stick it on the canvas in a slicer. The function SELECTEDVALUE returns the value from a column if it is filtered to a single value, otherwise it returns the alternative result.

So the formula SELECTEDVALUE(PPSwitch[PP],”All”) will return Y/N if we select them in the slicer, if neither are selected it will return All.

We can then create a measure:
SelectableStds = SWITCH(SELECTEDVALUE(PPSwitch[PP],"ALL"),"Y",[PPStudents],"N",[NotPPStudents],"All",[StudentsOnRoll])

The logic is pretty simple with only three outcomes, but adding more will obviously increase exponentially the number of conditions/measures you would need (e.g. having Y/N/All for SEN would mean building in IF statements to identify 9 separate outcomes. Hence the impracticality of having multiple slicers with this method.
Here’s the file







Comments

Popular posts from this blog

Covid-19 Monitoring

Attainment 8 in BI - Part 1

Subject - Class - Pupil Table