DAX code not working with config variable used in a measure - powerbi

I have a table (named Proto) in power-bi desktop as shown below (with 4 columns & around 30k rows).
I created a measure with the following DAX code. Here, ProtoVal is a table of single column containing unique values of protocol (like SSL, DNS etc). Based on the user selected protocol, i am filtering the above table to contain rows only for the selected protocol.
ProtoTotBytes =
VAR SelectedProto = SELECTEDVALUE(ProtoVal[Protocol])
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
RETURN CALCULATE(SUM(Proto[total_bytes]), temp1)
The above DAX code works fine. Now in addition to SelectedProto, i wanted to add one more config variable numIP (TopN-IP's being a table of single column containing numerical values 5,10,15,20 etcTopN-IP's = GENERATESERIES(5, 30, 5)) where i want to take only the top 'numIP' rows from table temp1. Wrote the code below for that. This works whenever i change the value of SelectedProto but doesn't change when i change numIP ? Can anyone please let me know whey its sensitive to one config variable while it is ignoring another ?
ProtoTotBytes =
VAR numIP = SELECTEDVALUE('TopN-IP''s'[TopN-IP's])
VAR SelectedProto = SELECTEDVALUE(ProtoVal[Protocol])
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
VAR temp2 = TOPN(numIP, temp1, [total_bytes], DESC)
RETURN CALCULATE(SUM(Proto[total_bytes]), temp2)

It does exactly what you told it to do, look at your code:
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
VAR temp2 = TOPN(numIP, temp1, [total_bytes], DESC)
in the first line you use FILTER, this is correct, you are filtering
in the second line you are using TOPN, this is only sorting. I believe your intent was, was a filter based on your selection so also here you need to use FILTER.
VAR temp2 = FILTER(temp1, numIP = VALUE(RIGHT(Proto[networkIpAddress],1)))
In this filter I compare the last digit of the networkIp with the numIP(s) selected by the user

Related

Can I dynamically derive Dax Filters from "dissecting"a criteria field in my database?

I have a database table that contains records, where each record has a criteria attribute. This criteria attribute can hold anywhere between 1-n criteria that I'd like to apply as filters on a different table.
This looks something like:
message.status:::eq:::submitted;;;message.count:::ge:::5
but could also be only
message.count:::ge:::5
What I'd like to do in DAX, is take that string and translate it into dynamic Filter attributes. So I somehow need to split the string based on ;;;, and then disect each section into the target (e.g. message[count]), the operator (e.g. ge --> >=) and the value (e.g. 5).
So in the end the following DAX snippet should be added to my Calculate 1 or more times:
example measure = CALCULATE(
COUNTROWS('message),
FILTER (
ALL('message'),
--- line below should be dynamically injected
message[count] >= 5
),
I'm struggling with how to create a loop (is this even possible in PBI?), and then even with a single string... hoe to filter based on this.
Thanks
You can try to build new table for splited message.
Table 2 =
var _splitby = ";;;"
var _string = SELECTCOLUMNS(ADDCOLUMNS(VALUES('Table'[message]),"pathx", SUBSTITUTE([message],_splitby,"|")),"pathx",[pathx])
var _generate = GENERATE(_string, GENERATESERIES(1, PATHLENGTH([pathx])))
var _GetVal = SELECTCOLUMNS(_generate, "Msg", PATHITEM([pathx], [Value]))
return
_GetVal
If you have always message.count:::ge::: like string at the end, you can follow these steps in Power Query-
Step 1: Duplicate you message column
Step-2: apply split on new duplicated column using string message.count:::ge::: and you will have a new column with last Numeric value from your original text.
Step-3: you can now apply filter on the new column.
Sample Output-

PowerBI: Aggregate Measure correctly by condition on DATEDIFF

I have the following Table:
BaseTable
It represents processes with a certain category.
And there is also a Date Table over column TIMESTAMP.
I would like to show a Measure based on another Measure that calculates the Date-Difference until the selected Date.
So first this is how I calculate the Date-Difference:
AGE =
VAR SELECTED_DATE = CALCULATE(MAX(DATUM[Date]), ALLSELECTED(DATUM))
VAR STARTDATE_PROCESS = Calculate(MAX(Workflow[MIN_TIMESTAMP]),DATUM[Date]<=MAX(DATUM[Date]), ALL(DATUM[Date]))
RETURN
DATEDIFF(STARTDATE_PROCESS,SELECTED_DATE,DAY)
Now I want to use a Measure which depends on the result of AGE, like
NEW = IF([AGE]<=3,CALCULATE(COUNT(Workflow[PROCESS]),DATUM[Date]<=MAX(DATUM[Date]),ALL(DATUM)))
or
OLD = IF([AGE]>3,CALCULATE(COUNT(Workflow[PROCESS]),DATUM[Date]<=MAX(DATUM[Date]),ALL(DATUM)))
The Measures AGE, OLD and NEW look like that with the Base Table:
Measures
As you can see the aggregation is not working correctly:
Result_Wrong
But it should be like that
Result_Correct
Any idea how to fix that?
Thank you!
So the problem is that the subtotal is calculated at a whole different context, and because your Age measure is based on the MAX(Workflow[MIN_TIMESTAMP]) that won't take into account that there can be multiple processes.
To do what you want, you need to change the New and Old measures to perform an aggregation per process and then return the result of that. Something like this:
New_agg =
VAR tbl = ADDCOLUMNS(CALCULATETABLE(VALUES(Workflow[Process]), ALL('Date')), "age", [Age], "count_process", CALCULATE(COUNT(Workflow[Process]), ALL('Date')))
RETURN SUMX(tbl, IF([age]<=3, [count_process]))
Demo File
Let me know if below solution is working
Unfortunately I am unable to generate the dummy data that you have been using, so Created my own data for developing the solution.
Now from this data I have calculated the difference of dates and put it as Age
Now to get the count of process for the condition like yours, I have created two formulas and the result is:
Logic I followed here is, instead of creating measure I have created columns and took the sum of those columns which will give the data you need as sum of those columns.
Column for New:
New = IF((Sheet1[Age]) > 20, 1,0)
Column for Old:
Old = IF((Sheet1[Age]) < 20, 1,0)
Now place both formulas in "Values" and take sum as the aggregation.
Final result is

IF condition in DAX is creating Cartesian Join on rows

Dax formula without If condition works fine, but as soon as I add an IF condition rows start multiplying. I believe it's doing Cartesian Product.
My requirement is simple. I need to show only those rows in which Sickness[Start_Date]>LASTDATE(Test[Date])
The complete formula is -
Measure =
var val = CALCULATE(MAX(Sickness[Start_Date]),FILTER(Sickness,Sickness[Start_Date]>LASTDATE(Test[Date])),ALL())
return
IF(val = BLANK(),0,1)
I have 3 separate tables Emp_data, Test and Sickness.
To replicate this scenario, Please follow the below steps:
1st Step : Create table Emp_data
Emp_data = DATATABLE("Emp_no",INTEGER,"Name",STRING,{{101,"A"},
{102,"B"},
{103,"C"},
{104,"D"},
{105,"E"},
{106,"F"},
{107,"G"},
{108,"I"},
{109,"J"},
{110,"K"},
{111,"L"},
{112,"N"},
{113,"M"},
{114,"O"},
{115,"P"},
{116,"Q"},
{117,"R"},
{118,"S"},
{119,"T"},
{120,"U"}
})
create table : Test
Test = DATATABLE("Emp_No",INTEGER,"Date",DATETIME,"Result",INTEGER,{{101,"3/10/2020",1},
{101,"3/13/2020",2},
{102,"3/11/2020",1},
{103,"3/12/2020",2},
{104,"3/13/2020",1},
{105,"3/14/2020",1},
{106,"3/15/2020",2},
{107,"3/16/2020",1},
{108,"4/20/2020",1},
{109,"4/21/2020",2},
{110,"4/22/2020",2},
{111,"4/23/2020",1},
{112,"4/24/2020",1},
{113,"4/25/2020",2},
{114,"4/26/2020",1},
{115,"4/27/2020",2},
{116,"5/5/2020",1},
{117,"5/5/2020",1},
{118,"5/5/2020",1},
{119,"5/5/2020",1},
{120,"5/5/2020",2}
})
Create table Sickness
Sickness = DATATABLE("Emp_no",INTEGER,"Start_Date",DATETIME,"End_Date",DATETIME,"Sickness_Code",INTEGER,{{101,"2/12/2020","2/12/2020",30},
{101,"3/10/2020","3/15/2020",50},
{101,"3/20/2020","3/30/2020",50},
{101,"4/5/2020","4/10/2020",40},
{102,"3/11/2020","3/11/2020",50},
{107,"3/1/2020","3/2/2020",30},
{107,"3/15/2020","3/20/2020",50},
{107,"3/21/2020","3/31/2020",40},
{112,"4/20/2020","4/30/2020",50},
{112,"5/1/2020","5/15/2020",50},
{116,"4/1/2020","4/15/2020",30},
{116,"5/3/2020","5/15/2020",50},
{116,"5/16/2020","5/26/2020",50},
{116,"5/27/2020","5/29/2020",40}}
)
Second Step is to create relationship between these 3 tables. Emp_Data and Test table have one to many relationship. I changed the filter direction to BOTH. Thinking may be this will resolve the issue. Create relation many to many between the tables Test and Sickness. The image is attached
The output is as follows :
If I remove the IF condition my out is what I need :
Can someone help me in understanding this behavior of Power BI. This looks very strange. Why row count is increasing after applying IF condition. Thanks in advance
It's because you assigned a 0 value to all blank values in your Sickness data table. Once your remove the if statement, Power BI only shows data rows that do not return a blank value.
To fix your issue try this updated meassure:
Measure =
VAR val = CALCULATE(MAX(Sickness[Start_Date]),FILTER(Sickness,Sickness[Start_Date]>LASTDATE(Test[Date])),ALL())
VAR OneZero = IF(ISBLANK(val),0,1)
RETURN
IF(HASONEVALUE(Sickness[Emp_no],OneZero)

How to create a new column from the select of the distinct values of two columns with Power Query Editor in Power Bi

I need to insert in a new column the distinct values of two columns using the Power Query Editor Power Bi.
Any ideas enter image description hereguys?
Here you go:
let
Source = SomeTable
firstCol = Source[FirstColumn],
secondCol = Source[SecondColumn],
thirdCol = List.Sort(List.RemoveNulls(List.Distinct(List.Combine( {firstCol, secondCol})))),
#"TableResult" = Table.FromColumns({firstCol, secondCol, thirdCol}, {"First","Second","Combined"})
in
#"TableResult"
This basically converts your first and second columns into lists, and combines them into one new list. Next, it transforms the new list a bit to match your requirements -- first by getting just the distinct values, then dropping any null values, and lastly sorting it in ascending order.
Once that's done, we can take advantage of Table.FromColumns and create a table from our three lists.
That should get you where you're going.
Thanks Ryan.
My requirement was to create a distinct list of IP addresses from one of the columns in a Table.
Here's the code that worked for me.
= let
Source = #"TABLENAME",
firstCol = #"TABLENAME"[Client Ip],
IP = List.Distinct(firstCol),
#"DistinctIP" = Table.FromColumns({IP}, {"IP"})
in
#"DistinctIP"

Find difference between two rows by usind Dax in Power BI

I have three column one is Id(ID is same) 2nd col is amount and third is date, I want difference between two rows(amount)
As you want to have the previous value of the date where the ID is equal, you can use the following:
Add a column,
Column4 =
var baseFilter = FILTER(DiffRows;DiffRows[Column1] = EARLIER(DiffRows[Column1]))
var selectDate = CALCULATE(LASTDATE(DiffRows[Column3]);baseFilter;
FILTER(baseFilter; DiffRows[Column3] < EARLIER(DiffRows[Column3])))
return
DiffRows[Column2] - CALCULATE(sum(DiffRows[Column2]);baseFilter;
FILTER(baseFilter; DiffRows[Column3] =selectDate))
First I create a basefilter to ensure the IDs are same.
Next I select the date whcih is the previousdate within the set of same ids
Last I use this date, to filter the correct value out of the rows.
End result: