I have a fact table with transactions (sales and product numbers), and a second list of 'required product numbers'. This list is dynamic and can change every time I use the report. I want to filter my fact table so I only keep those products that are in the product list. Is there a way to pass the values in the list as filter argument in the Table.SelectRows statement?
So that next time, when the values change in the list, they are all passed to the filter argument?
Solved! Go to Solution.
Not sure how this is the correct answer. Executing this results in:
Expression.Error: We cannot convert a value of type List to type Table.
I tried doing the same thing and it produces as I have a list I am using to try and filter a table in the same way. Other examples mention trying to using a query parameter instead--seems like it is much more laborious than it should be.
Hello--sorry I missed this somehow--happy to oblige though!! Here is a code snippett below which should give you what you want:
For those that have trouble with List.Contains, you might need Table.Contains instead.
Had the same requirement for a project using Power Query for Excel. The table containing the values to be passed to the filter was in a table on an Excel sheet, so end users could update the values as needed. I created a query to reference that table, "tblAgents" with a header value of "AgentID." To help understand the syntax, let's assume the table that I want to filter has a column of "AgentIdentifier."
Here's the code that works for me:
#"Filtered Rows" = Table.SelectRows(Source, each Table.Contains(tblAgents, [AgentID = [AgentIdentifier]]))
The initial solution does work. Here are some details to make it work.
In Power Query, you must load a table containing your facts (lots of rows) and an other table containing the filter criterias (a few rows). Your Filter table must be converted to a List. The filter table will contain only one column, right-click on the column header and select Drill Down: the filter table is now a List.
List.Contains already includes the notion of "any". The function will go through each row in the fact table (in a specified field) and look for any of the values listed in the Filter List.
List.ContainsAny must be used to compare two lists, not a applicable for the example listed above.
Here is an example using BOTH functions:
My Fact Table named CRM contains 3 fields: Client, Date, Message
My Filter Table named Filter contained 1 field with 2 entries: "waiting" and "pending".
The Filter Table was drilled down to become a List.
The Message field contains different entries such as
- waiting for call back
You must select New Source > Blank Query and type the following:
= Table.SelectRows(CRM, each List.Contains(Filter, [Message]))
The resulting table will contain all 3 fields from CRM table, and only the rows where the Message value is an exact match (this is case-sensitive) to either :
If I want my filter to look into any of the words listed in a Message, I can transform each entry under Message into a "list" with Text.Split function. I will use " " (space) as a delimiter, therefore a Message value like "waiting for call back" will become a list of those 4 words.
= Table.SelectRows(CRM, each List.ContainsAny(Filter,Text.Split([Message]," ")))
The resulting table will contain all 3 fields from CRM table, and only the rows where the Message value contains either "waiting" or "pending" :
"waiting for call back"
Julie at Daxel.ca, offering training in Ottawa, Canada