Counting the number of time a dynamic category appeaed - powerbi

I hope you are all doing well,
I am stuck at a problem and can't find a ways out. I have a sample table with shops name, target and date. Based on the target a dax measure is written which which will define the category for that particular shop.
for example if I select date between 1 december, 20222 to 2 decemeber 2022 than the category of  a1 store will be "D" however if choose date upto 3 december , 2022 the category of a1 store will be "A".   Following dax is used to assign the category.
Category =
var t1 = sum('Table'[Target])
return
if(t1 >=15 ,"A", if(t1<15 && t1>=10, "B", if(t1>10 && t1<=5, "C","D")))
Now I want to count the total number of stores fall in a specefic category based show the total against those stores with respect to the chosen date and show blank in total for category and for count. 
The output should be like this.
Kindly help
To create dax measure based on my requirements mentioned before.

Related

IF 'AND-OR' ISFILTERED combination in DAX giving problems

Below is the sample dataset
The data has two slicers ( date and category ) shown below
I am writing a DAX Statement to multiply the sum(values) * 10 only if the date range is in the current year 2023.
The StartYear gives the start of the current year, firstD gives the lowest date from the date slicer.
Formula =
var new = sum(Test[Value]) * 10
var startyear = DATE(YEAR(TODAY()),1,1)
var firstD = CALCULATE( MIN( Test[Date]), ALLSELECTED(Test[Date]) )
return if( ISFILTERED(Test[Categories]) && firstD >= startyear, new, 0 )
Now when I filter dates to 2023, the total value should be 2300 but it shows as 0
However the DAX works when I select A or B
If we remove the ISFILTERED function then, it gives wrong value, the expected value is 0 because the start date is in 2022, but it shows 650
let me know if that is the right syntax
It looks like you are not using a separate calendar table to handle this, which you need!
In your very last example you have set your slicer to some time late 2022, but the minimum value of 'Test'[Date] for your selected category is in year 2023. Hint: set the slicer to e.g. 2022-12-14, this will include a 2022-date for Category A in your data.
Your measure behaves exactly how it is supposed to, in other words!
To fix this, you need to do the following:
Create a calendar table in your model, this should contain contiguous dates, which is necessary for the filtering method you want
Establish a relationship between the calendar table and existing Test table.
Use the date column from your new calendar table in your slicer and as date reference in your measure
Exactly how to create a calendar table is thoroughly documented on Google, I recommend you search and find an article or video you understand for implementing this.
Lastly: Your use of ISFILTERED in this measure seems strange, since you mention nowhere the requirement of only showing a number if the column you are testing filtering on is filtered, if that makes sense.. :-) The way you describe your calculation, you only need to check whether the selected date range starts in current year.

Power BI - Filtering model on latest version of all attributes of all dimensions through DAX

I have a model that's comprised of multiple tables containing, for every ID, multiple rows with a valid_from and valid_to dates.
This model has one table in that is linked to every other table (a table working as both a fact and a dimension).
This fact has bi-directional cross filtering with the other tables.
I also have a date dimension that is not linked to any other table.
I want to be able to calculate the sum of a column in this table in the following way:
If a date range is selected, I want to get the sum of the latest value per ID from the fact able that is before the max selected date from the date dimension.
If no date is selected, I want to get the sum of the current version of the value per ID.
This comes down to selecting the latest value per ID filtered on the dates.
Because of the nature of the model (bi-directional with the fact/dimension table), I want to have the latest version of any attribute from any dimension selected in the visual.
Here's an data example and the desired outcome:
fact/dimension table:
ID
Valid_from
Valid_to
Amount
SK_DIM1
SK_DIM2
1
01-01-2020
05-12-2021
50
1234
6787
1
05-13-2021
07-31-2021
100
1235
6787
1
08-01-2021
12-25-2021
100
1236
6787
1
12-26-2021
12-31-2021
200
1236
6787
1
01-01-2022
12-31-9999
200
1236
6788
Dimension 1:
ID
SK
Valid_from
Valid_to
Name
1
1234
10-20-2019
06-01-2021
Name 1
1
1235
06-02-2021
07-31-2021
Name 2
1
1236
08-01-2021
12-31-9999
Name 3
Dimension 2:
ID
SK
Valid_from
Valid_to
Name
1
6787
10-20-2019
12-31-2021
Name 1
1
6788
01-01-2022
12-31-9999
Name 2
My measure is supposed to do the following:
If no date is selected than the result will be a matrix like the following:
Dim 1 Name
Dim 2 Name
Amount Measure
Name 3
Name 2
200
If July 2021 is selected than the result will be a matrix like the following:
Dim 1 Name
Dim 2 Name
Amount Measure
Name 2
Name 1
100
So the idea here is that the measure would filter the fact table on the latest valid value in the selected date range, and then the bi-directional relationships will filter the dimensions to get the corresponding version to that row with the max validity (last valid row) in the selected range date.
I have tried to do the following two DAX codes but it's not working:
Solution 1: With this solution, filtering on other dimensions work and I get the last version in the selected date range for all attributes of all used dimensions. But the problem here is that the max valid from is not calculated per ID, so I only get the max valid from overall.
Amount Measure=
VAR _maxSelectedDate = MAX(Dates[Dates])
VAR _minSelectedDate = MIN(Dates[Dates])
VAR _maxValidFrom =
CALCULATE(
MAX(fact[valid_from]),
DATESBETWEEN(fact[valid_from], _minSelectedDate, _maxSelectedDate)
|| DATESBETWEEN(fact[valid_to], _minSelectedDate, _maxSelectedDate)
)
RETURN
CALCULATE(
SUM(fact[Amount]),
fact[valid_from] = _maxValidFrom
)
Solution 2: With this solution, I do get the right max valid from per ID and the resulting number is correct, but for some reason, when I use other attributes from the dimensions, it duplicates the amount for every version of that attribute. The bi-directional filtering does not work anymore with Solution 2.
Amount Measure=
VAR _maxSelectedDate = MAX(Dates[Dates])
VAR _minSelectedDate = MIN(Dates[Dates])
VAR _maxValidFromPerID =
SUMMARIZE(
FILTER(
fact,
DATESBETWEEN(fact[valid_from], _minSelectedDate, _maxSelectedDate)
|| DATESBETWEEN(fact[valid_to], _minSelectedDate, _maxSelectedDate)
),
fact[ID],
"maxValidFrom",
MAX(fact[valid_from])
)
RETURN
CALCULATE(
SUM(fact[Amount]),
TREATAS(
_maxValidFromPerID,
fact[ID],
fact[valid_from]
)
)
So if somebody can explain why the bi-directional filtering doesn't work anymore that will be great, and also, more importantly, if you have any solution to have both the latest value per ID and still keep filtering on other attributes, that would be great!
Sorry for the long post, but I thought it's best to give all the details for a complete understanding of my issue, this has been picking my brain since few days now and I'm sure I'm missing something stupid but I turned to this community for help because I cannot seem to be able to find a solution!
Thank you very much in advance for any help!
Seems to be workable with a dummy model. I didn't got the point how filter ID, so if it creates a problem let me know how you handle ID. Then I changed fact to facts as fact is a function. Also, I'm not sure about the workability of the measure at your real model. Hope you will give some feedback.
Amount Measure =
VAR ValidDate=
calculate(
max(facts[Valid_to])
,ALLEXCEPT(facts,facts[ID])
,facts[Valid_to]<=MAX(Dates[Date])
)
Return
CALCULATE(
SUM(facts[Amount])
,TREATAS({ValidDate},facts[Valid_to])
)

Power BI: Fill gaps between two dates, exclude dates outside range

So I am looking to display payments from individual donors over a time period between their first donation, and today's date.
To fill gaps in a visual representation of donations over time, I use a calendar table and select ‘show items with missing data.’
My issue is that if a donor first donated in 2005 the fact that the calendar table starts in 1980 means the graph shows an X axis date range starting that year. So it's showing a lot of time we know has no data.
How can I default the date range to start at the date of the first donation of the user ID passed to the report?
Tables: Calendar, Donations
One way to achieve this is to create a measure that checks to see if there are donations within the current filter context. For your chart this will be for the date and donor category selections, though this would work in any other filter context that relates to donations.
It will look similar to this:
Has Donations =
if(calculate(isempty(relatedtable(DonationsTable
)
)
)
,0
,1
)
You can then add this filter to the Filters on this visual section of the Filter Pane and check for where the value is 1, though make sure your date axis is set to continuous. This will return all dates between the oldest and newest donation.

Dax Finding date based on Criteria calculated Column

I couldn't find an answer for my issue elsewhere, so trying my luck here.
I have sales table and my final result should determine if there were sales made for same person in specific period of time, for example within 7 business days. for example:
For ID 123 I have to flag it that sale for products A,B,C where within specified period.
For ID 1234 only sales of products A and B meet the criteria product C was sold in irrelevant time frame.
I've created a date table with indicators that determine for each date if the date is a working day, but i am struggling to calculate the relevant last working day
For example: I need that for 01/01/2019 i will get 10/01/2019 date, based on NUMOFDAYS and FinalWorkday = TRUE, which basically means that i have to count NUMOFDAYS times TRUE statement for each date and return corresponding date.
After that step done I think that it would be pretty easy for me to determine if the sale for a person was made in specific time frame.
If someone can give me direction for that much appreciated
Thank you in advance
You could use a DateTable like this one:
I used the following DAX-expressions for the calculated columns:
nrDays = 7
isWorkDay = WEEKDAY('DateTable'[Date],2) < 6
rankWorkingDays = RANKX ( FILTER ( DateTable, DateTable[isWorkDay] = TRUE () ),
DateTable[Date] , , ASC )
LastWorkDay = LOOKUPVALUE ( DateTable[Date],
DateTable[isWorkDay], TRUE (),
DateTable[rankWorkingDays], DateTable[rankWorkingDays] + DateTable[nrDays])
This issue can be solved by the following, since three are non-working days/holidays we can filter them out via POWERQUERY, than add an Index Column and Another column Which is basically Index column + Number of days wanted, then simply merge duplicate of dates query on Index+number of days wanted column on Index column. And we get the correct date

DAX CALCULATE() doesn't seem to be overriding pivot filter

I am learning to use Power Pivot and write DAX and I am working through a book I bought written by Rob Collie and Avichal Singh called "Power Pivot and Power BI".
Early on it explains what happens when using CALCULATE() in a measure. A key point of understanding is explained as follows:
If a filter argument acts on a column that IS already on the pivot, it
will override the pivot context for that column
So in a simple table called "GSR" I have a series of invoices with an invoice date, a product and an amount. I have another column that converts all invoice dates to the last day of the month to gather them together. I have created a measure called "Total orders" that is counting the number of rows.
I have created a pivot of this data with:
Products in the rows
Month end in the columns (but I've actually chosen Month and Year from the automatic breakdown Power Pivot has done on my Month_End column)
Orders in the values
This pivot renders correctly.
Now the issue:
I've created two slicers that are feeding off two disconnected tables; one containing month numbers, and one containing years. Based on the selection from each of these I have a measure that creates a month end using the EOMONTH(DATE(),0). This measure is called "Comparison_Month_End".
I then have another measure called "Compare_Orders" that contains the following:
CALCULATE([Total orders],FILTER(GSR,GSR[Month_End]=[Comparison_Month_End]))
The point of all of this - this is meant to get the orders from the GSR where the month and year match the slicer selection. I want this value to appear in the pivot for every month selected i.e. not filtered by the pivot.
It doesn't work, however. This seems to me to be counter to what the book says, which is that if the filter in the measure is applied to a column on the pivot (in this case Month_End), the pivot filter is overriden. So, for example, if I have 31-Mar-18 in a column on my pivot and the comparison month end is 31-Jan-18, I would expect to see the January orders within "Compare_Orders" sitting next to the March orders, the February orders, the December orders and so on, but it only appears next to January.
To me this is doing exactly the same as an example in the book where there is a pivot with Year in the rows, Total Sales in column 1 and then 2002 sales in column 2. Column 1 shows sales for each year, column 2 shows the same sales figure (i.e. 2002 sales) against every row, even where the row year is 2001, 2003 or 2004. The 2002 Sales measure is using CALCULATE() summing Total Sales, filtering on "Sales[Year] = 2002".
Could anyone please explain why what I expected to happen doesn't seem to be happening please?
Thank you.
CALCULATE does indeed override the filter context when evaluating its first argument; using the rows provided to its second argument as the new filter context. However; CALCULATE does not alter the filter context when evaluating its second argument, and so pre-existing filters remain unless they are explicitly removed.
In FILTER(GSR,GSR[Month_End]=[Comparison_Month_End]), FILTER only iterates over rows of GSR that are present in the pre-existing filter context (the pivot context). To get all rows, use ALL:
CALCULATE([Total orders],FILTER(ALL(GSR),GSR[Month_End]=[Comparison_Month_End]))