Forum Discussion
Filter values from one table in another without relationship DAX
- 2 years ago
Hi talespin Please see the solution below. As you mentioned earlier creating a measure using the formula wasn't the right way and creating a role and applying RLS was the right approach. Since no one was able to provide a RLS DAX query for this requirement we have itself come up with a DAX solution to achieve the requirement. Please see below.
1.) All semi-colon values in DIM_ACT columns must be replaced by "|" symbol for this formula to work. Either change the source data or create a calculated column to replace ";" with "|".
2.) Eliminated DIM_USER table and brought in EMAIL ID column to DIM_ACT table itself.
3.) There is only 1 record for a single user in DIM_ACT under a single GROUP.
4.) Create a ROLE in Manage roles and apply below DAX under FACT_ACTUALS table. Using the below DAX , when the user logs in he will be able to see only the values separated using "|" in the respective columns of DIM_ACT and when ALL is present in any of the columns, he will be able to see all the values available in FACT ACTUALS./* FILTER DIM_ACT TO FETCH THE RECORD HAVING ONLY THE LOGGED IN USER EMAIL ID & VALUES ASSIGNED UNDER LEVEL COLUMN */
&& [LEVEL]
IN(
VAR _LEV =
MAXX (
FILTER
( 'DIM_ACT',
[EMAIL ID] = USERPRINCIPALNAME () ),
'DIM_ACT'[_LEV]
)/* TAKE THE PATH LENGTH OF LEVEL COLUMN. THIS IS DONE BECAUSE THERE COULD BE N NUMBER OF VALUES SEPARATED BY | SYMBOL IN DIM_ACT TABLE
AND WE NEED TO SEPARATE THEM AS INDIVIDUAL VALUES */VAR _LEVLEN = PATHLENGTH (_LEV )
/* CREATE A VIRTUAL TABLE WITH COLUMN NAME LEVLIST HAVING THE LIST OF LEVEL COLUMN VALUES */
VAR _LEVTABLE = ADDCOLUMNS ( GENERATESERIES ( 1, _LEVLEN ), "LEVLIST", PATHITEM ( _LEV, [Value] ) )
/* SELECT THE COLUMN VALUES AND PASS THE VALUES TO LIST */
VAR _LEV_list = SELECTCOLUMNS ( _LEVTABLE, "LEVEL", [LEVLIST] )
/* ADD ALL THE LEVEL VALUES FROM FACT_ACTUALS. THIS IS FOR A USER WHO HAS VALUE "ALL" ASSIGNED TO HIM UNDER LEVEL IN DIM_ACT TABLE */
VAR _ALLFACTLEV = ADDCOLUMNS ( VALUES ( FACT_ACTUALS[LEVEL] ), "ALL", "ALL" )
/* RETURN ONLY THE VALUES ASSIGNED IN LEVEL COLUMN IN DIM_ACT FROM FACT TABLE FOR LOGGED IN USER OR RETURN ALL THE VALUES FROM FACT TABLE WHEN THE LEVEL COLUMN IS PROVIDED AS ALL */
RETURN
SELECTCOLUMNS
(
FILTER ( _ALLFACTLEV, [LEVEL] IN _LEV_LIST || [ALL] IN _LEV_LIST ),
[LEVEL]
)
)
&& [LABEL]
IN (
VAR _LAB =
MAXX (
FILTER ( 'DIM_ACT', [EMAIL ID] = USERPRINCIPALNAME () ),
'DIM_ACT'[LABEL]
)
VAR _LABLEN = PATHLENGTH ( _LAB )
VAR _LABTABLE =
ADDCOLUMNS ( GENERATESERIES ( 1, _LABLEN ), "LABLIST", PATHITEM ( _LAB, [Value] ) )
VAR _LAB_LIST =
SELECTCOLUMNS ( _LABTABLE, "LABEL", [LABLIST] )
VAR _ALLFACTLAB =
ADDCOLUMNS ( VALUES ( FACT_ACTUALS[LABEL] ), "ALL", "ALL" )
RETURN
SELECTCOLUMNS (
FILTER ( _ALLFACTLAB, [LABEL] IN _LAB_LIST || [ALL] IN _LAB_LIST ),
[LABEL]
)
)&& [SOURCE] IN ------ Similarly repeat the above code for other columns in DIM_ACT
Thank you for your immediate reply. However when I tried to create a new measure using the above query it says "Multiple columns cannot be converted to scalar value". I think its because my DIM_ACT contains multiple rows with same ID & LEVEL. It works while creating a New Table but when I tried to include additional filter using USERPRINCIPALNAME(), it throws below error. Could you pls suggest a way around ?
If your DIM_ACT table contains multiple rows with the same ID and LEVEL combination, it can cause issues when trying to create a measure that expects a scalar value. In such cases, you might need to aggregate or summarize the data to ensure that a single value is returned for each combination of ID and LEVEL.
Here's how you can modify the DAX formula to aggregate the data from DIM_ACT before filtering FACT_ACTUALS:
Filtered_FACT_ACTUALS =
FILTER(
FACT_ACTUALS,
COUNTROWS(
SUMMARIZE(
DIM_ACT,
DIM_ACT[ID],
DIM_ACT[LEVEL],
DIM_ACT[LABEL],
DIM_ACT[SOURCE],
DIM_ACT[CC],
DIM_ACT[ORG]
)
& FILTER(
DIM_ACT,
DIM_ACT[LEVEL] = FACT_ACTUALS[LEVEL] &&
DIM_ACT[LABEL] = FACT_ACTUALS[LABEL] &&
DIM_ACT[SOURCE] = FACT_ACTUALS[SOURCE] &&
DIM_ACT[CC] = FACT_ACTUALS[CC] &&
DIM_ACT[ORG] = FACT_ACTUALS[ORG] &&
DIM_ACT[USER] = USERPRINCIPALNAME()
)
) > 0
)
In this modified formula, we use the SUMMARIZE function to aggregate the data from DIM_ACT based on the columns ID, LEVEL, LABEL, SOURCE, CC, and ORG. This helps in ensuring that only unique combinations of these columns are considered.
Then, we apply the filter conditions to both the aggregated data and the original DIM_ACT table. Additionally, I've included a filter condition based on the USERPRINCIPALNAME() function to filter rows based on the logged-in user.
This approach should help you avoid the "Multiple columns cannot be converted to scalar value" error and apply additional filtering based on the logged-in user.
If this post helps, then please consider Accepting it as the solution to help the other members find it more quickly.
In case there is still a problem, please feel free and explain your issue in detail, It will be my pleasure to assist you in any way I can.
- varung88992 years ago
Helper II
Thank you. It says Syntax error while trying this code. Not sure if I am doing something incorrectly. Please see my exact requirement below with table structure below.
DIM_ACT
EMAIL ID LEVEL LABEL SOURCE CC ORG LOC [email protected] 100;A20;K40 XKG;TBF 1 E250;V365 25;36 ALL [email protected] 100;A20;K40 XKG;TBF ALL E250;V365 25;36 ALL [email protected] ALL ALL ALL E250;V365 25;36 ALL [email protected] ALL ALL 2 E250;V365 ALL ALL [email protected] 300:J99 TUT 2 ALL 58 ALL [email protected] 300 DUC 2 ALL 45 300;450 FACT ACTUALS contains columns LEVEL, LABEL,SOURCE,CC,ORG,LOC,SALES,STOCK.
When [email protected] is logged in, I would like to see the matching column values in FACT_ACTUALS as defined in DIM_ACT. In the above table I have a single record for each user. I think when I transform columns using Delimiters then each user has multiple records creating issues hence I will not perform any transformation and keep DIM_ACT as above. My queries are 1.) Is it possible to pass all these column values ([LEVEL] & [LABEL] & [SOURCE] & [CC] & [ORG] from DIM_ACT individually using DAX and match respective columns in FACT_ACTUALS table ? Values in columns of DIM_ACT are separated by semicolon and I need to match one by one in respective columns in FACT_ACTUALS because FACT_ACTUALS will only have individual values under LEVEL and not values separated by semi-colon.
2.) FACT table does not have values as ALL hence I would like to filter those columns having value as ALL meaning it should display all the available values under this column (no filter should be applied to this column). Eg: for user SDK@abc,com, he should see all the LEVEL = 100 & A20 & K40 and labels should only be those values under LEVEL and not all the values from FACT_ACTUALS. There will be only Table visualization displaying all the columns in FACT_ACTUALS. When user logins he should see only those values assigned in DIM_ACT and not all the values under LEVEL & other columns mentioned. Hope using [LABEL] & [LEVEL] & [SOURCE] & [CC] & [ORG] & [LOC] will accomplish this but not for ALL values.
3.) In future If I plan to create slicers for LEVEL, LABEL, SOURCE,CC, ORG,LOC columns can I display only assigned values in DIM_ACT to the user (not all values from FACT_ACTUALS (like a hierarchical filter) to filter FACT_ACTUALS. All columns are Text format. Please let me know for any clarification. Appreciate all your help so far. TIA.