Using Power BI to report who HASN'T logged on - powerbi

A little bit of a newbie with Power BI DAX code. I have a log database that has two tables, Connections, and Employees. The two tables have a one-to-many relationship on sEmailAddress. The following DAX code that creates metrics works well in that I get a count of my employees that connect via VPN and I can get a list of those that connect via VPN
sVPN Count =
CALCULATE (
DISTINCTCOUNT ( Connections[sEmailAddress] ),
FILTER ( Connections, Connections[sTarget] = "VPN" ),
FILTER ( Connections, Connections[sEvent] = "User Logon" )
)
sVPN Users =
CALCULATETABLE (
DISTINCT ( Connections[sEmailAddress] ),
FILTER ( Connections, Connections[sTarget] = "VPN" ),
FILTER ( Connections, Connections[sEvent] = "User Logon" )
)
I am trying to find a method that can provide me a list of employees that DON'T login on any given day.

You are created a Calculated Column/ Measure, but you put calculation that is returning a table of value. If you need only a list of email, then put your code to "New Table". Then just add this newly created column to your visual.
If you need to show this with additional data, then you can create a column with a flag (1/0) based on your relationship.
pseudo using IF
Flag = IF(isblank('left side of relationship'), 1,0)

One approach would be to add a calculated column to your employee table where you use the [sVPN Count] measure you've already defined. Then you can identify the employees who haven't logged in by seeing which rows have blank or zero values in that column.
As msta42a notes, a measure can only return a single value, not a table. (This is the reason for the error you are getting.)

Related

Setting Row level security with multiple columns in Power BI

I am trying to create a filter for target table having country code column. I want to give access to people with logged in upn either in AdditionalOwner or OwnerEmail with countrycode
AdditionalOwner has emails separated by commas, Number of emails in additionalowner column is not fixed also it may have values from OwnerEmail column. So Please help me in giving RLS in this scenario
Please find my column structure
CountryCode
AdditionalOwner
OwnerEmail
AU
test1#test.com,test2#test.com
test2#test.com
Here is the DAX I have used for Owner Email
[Country Code] = LOOKUPVALUE(
UserRoles[CountryCode],
UserRoles[OwnerEmail],UserPrincipalName())
Please help me in adding RLS for AdditionalOwner column too
You may want to try using something like OR, IF, and CONTAINSSTRING in your managed role. I've included an example for you to test below. For transparency, I did not test this but this is where I would start to solve this.
OR (
UserRoles[CountryCode] =
IF(
CONTAINSSTRING ( UserRoles[AdditionalOwner], UserPrincipalName() )
, UserRoles[CountryCode], BLANK() )
, UserRoles[CountryCode] = LOOKUPVALUE(
UserRoles[CountryCode],
UserRoles[OwnerEmail], UserPrincipalName())
)

RLS filter with multiple values assigned?

I need to filter my Power BI report by the App IDs associated with the current user (using the USERPRINCIPALNAME function). So I have three tables in my model, DimApp, DimUser, and FactRegisters, where a User_Id may be related to 1 or more App_Ids in my Fact table.
DimApp table
DimUser table
FactRegister table
As you can see in FactRegisters table there are two App_Ids (3 and 1) for User_Id 201. The following is the DAX rule defined in App_Id column from DimApp table to filter the data:
VAR userId =
LOOKUPVALUE (
DimUser[User_Id],
DimUser[Email], USERPRINCIPALNAME()
)
VAR app =
LOOKUPVALUE (
FactRegisters[Application_Id],
FactRegisters[User_Id], userId
)
RETURN DimApplication[Application_Id] IN {app}
Verifying the DAX expression doesn't return an error, however, when I choose to "View as" that role I'm not able to see the data in the visuals. The error states: "Couldn't load the data for this visual. An error was encountered during the evaluation of the row-level security expression defined in table DimApp. A table of multiple values was supplied where a single value was expected."
Cannot display the visual viewing as role
However, when a single App_Id is associated with the User_Id, I'm able to visualize the data on the report visuals using the same DAX rule. Here is how FactRegisters table looks like when User_Id 201 has a single App_Id (3) associated:
FactRegisters table when User_Id with single App_Id
User_Id with a single App_Id visual
Now I'm I able to visualize data in the report. This is not a suitable case scenario as a User_Id can have many App_Ids.
I also tried the following static DAX rule in my App_Id column from DimApp just to test and pass multiple values to that column, and I succeed in visualizing data for multiple App_Ids:
DimApplication[Application_Id] IN {1,3}
Static RLS with multiple values by App_Id column
But this is not the goal (it's not dynamic). The goal is to visualize the data from all the Apps associated with the current user. Is it possible? Can't I pass more than one value to a column while filtering in RLS?
[Application_Id] IN
CALCULATETABLE(
VALUES('FactRegister'[Application_Id]),
FILTER ('FactRegister',
'FactRegister'[User_Id] = LOOKUPVALUE (DimUser[User_Id], DimUser[Email],USERPRINCIPALNAME())
)
)

How to filter a dimension based on RLS applied to another dimension?

Assume I have 2 dimension tables and 1 fact table.
DimUser
DimClients
DimCompany
FactSales
All the dims have a 1:M relation with filter flowing from the 1 -> M side.
Assume I have configured RLS filter on DimUser ([Username] = USERNAME()) so that the user of the report can see his own data based on email address, so user can see his own record entry in DimUser. Thus it will auto filter the FactSales also, effectively the user will be able to see only his sales.
However the user can see all clients and companies in the slicer. I want to setup filter on the DimClients and DimCompany so that the user can see only clients and conpanies for which he has made sales. How can I achieve this?
For example:
How to apply RLS to the DimClients and DimCompany so that it will filter only those ClientIds that appear in the sales table based on dynamic filter [Username] = USERNAME() applied on the DimUsers table?
The other option is to enable bidirectional filtering but this is not allowed for multiple tables.
You can create a measure that looks like this:
UserFlag =
CONTAINSSTRING (
CONCATENATEX ( FactSales, RELATED ( DimUsers[UserEmail] ), "," ),
USERNAME()
)
Create your RLS role and add this filter to each dimension.
[UserFlag] = True()
The result: If a row from a dimension is related to a fact row that is in turn related to the DimUser row whose email matches USERNAME(), then the measure returns 'True.' And so RLS is filtering only to those rows.

Power BI - Show only data that belongs to the required selection (And Logic)

I have a table like this
Role Skills Resource
Data Analyst R A
Data Analyst Python A
Data Analyst SQL B
Business Analyst SQL A
My Skills are on filter. I have multiple visuals on the dashboard.
And If I select SQL and Python then the results of both Data Analyst and Business Analysts are getting displayed in the visual.
But, I want it to display only the Data Analyst results because only Data Analyst has all the selected skills.
To achieve this, I think of creating a measure and putting it on visual level filter in each of the visual might help.
Update :- If I select SQL here, I get 2 distinct resources on my card visual which is relevant to resources, but If I select SQL and Python - I get 0 Resources on my card visual which is relevant to resources and 1 role count which is relevant to roles on the Role measure.
Kindly help me with creating that measure.
Perhaps someone will suggest a more elegant way to do it; I came up with the following ideas.
Create a measure (I'll call your table "Data"):
Has All Selected Skills
=
VAR
Selected_Skills = ALLSELECTED ( Data[Skills] )
VAR
Role_Skills = CALCULATETABLE ( VALUES ( Data[Skills] ), ALL ( Data[Skills] ) )
VAR
Missing_Skills = COUNTROWS ( EXCEPT ( Selected_Skills, Role_Skills ) )
RETURN
IF ( NOT ( Missing_Skills ), 1 )
If the measure is placed in a visual against Roles, it'll produce the following results:
The way this code works:
First, we store all selected skills in a variable "Selected_Skills";
Second, we store all skills available for a role in a variable "Role_Skills". We must use ALL(Data[Skill]) to ignore the skill slicer selections;
Third, since both variables above are tables, we can use EXCEPT function to find how they are different. Here, we tell DAX to find what records in Selected_Skills don't exist in Role_Skills. Store the result in a variable "Missing_Skills".
Finally, if Missing_Skills is zero, it means that the role has all selected skills, and we flag it as 1 (although you might use True/False, etc).
The problem I see with this approach is that if Skill selector has no selection (shows "all skills"), then the formula might return blank for all roles, and all your visuals will be blank. Technically, it's correct - it's essentially saying that no roles have all skills. But if that's not the behavior you want, consider a slightly modified approach:
Missing Skills Count
=
VAR
Selected_Skills = ALLSELECTED ( Data[Skills] )
VAR
Role_Skills = CALCULATETABLE ( VALUES ( Data[Skills] ), ALL ( Data[Skills] ) )
VAR
Missing_Skills = COUNTROWS ( EXCEPT ( Selected_Skills, Role_Skills ) )
RETURN
Missing_Skills + 0
The formula uses the same logic, only returns the number of missing skills per role, instead of a true/false status. It will allow you to show a list of skills, sorted by the number of missing skills vs the selected skill set:
You can still use it to filter your visuals; the advantage is that it's never blank, even if all skills are selected:
It also gives you a capability to see what roles are the closest to meeting the requirement, even if none matches it perfectly; might be a desirable feature.
Final note: in all these reports, I have no subtotals and totals, assuming that they are not important. If you do need them, then the formulas might need to be modified to meet your requirements for the totals (depending on what you want to show there).

PowerBI DAX get COUNT DISTINCT with GROUP BY , see SQL query below

I have got this following SQL query that gives me the correct value from the database.
SELECT
SUM( DISTINCT_ORDER_NUMBERS )
FROM
(
SELECT STORE_KEY,
COUNT( DISTINCT TRANSACTION_NUM ) AS DISTINCT_ORDER_NUMBERS,
DATE_KEY,
TRANSACTION_TYPE_KEY
FROM Pos_Data
GROUP BY STORE_KEY,
DATE_KEY,
TRANSACTION_TYPE_KEY
)
AS A
I am however facing challenges writing a DAX formula for a measure in Power BI Here is what I have tried so far but I get an error.
Total Number Of Orders
VAR _TotalOrders =
SUMMARIZE('Pos_Data',
'Pos_Data'[STORE_KEY],
'Pos_Data'[DATE_KEY],
'Pos_Data'[TRANSACTION_TYPE_KEY],
"DISTINCT_ORDER_NUMBERS",
DISTINCTCOUNT('Pos_Data'[TRANSACTION_NUM]))
RETURN SUM(_TotalOrders[DISTINCT_ORDER_NUMBERS])
Please assist
The SUM function expects a base table rather than a calculated table.
Try this instead:
VAR _TotalOrders =
SUMMARIZE('Pos_Data',
'Pos_Data'[STORE_KEY],
'Pos_Data'[DATE_KEY],
'Pos_Data'[TRANSACTION_TYPE_KEY],
"DISTINCT_ORDER_NUMBERS",
DISTINCTCOUNT('Pos_Data'[TRANSACTION_NUM]))
RETURN SUMX(_TotalOrders, [DISTINCT_CHECK_SEQ])
Edit: If the difference you mentioned is related to nulls, then try this in place of DISTINCTCOUNT.
COUNTAX( DISTINCT( 'Pos_Data'[TRANSACTION_NUM] ), 'Pos_Data'[TRANSACTION_NUM] )
The COUNTAX function (as opposed to COUNTX) does not count nulls.