How to use contains and replace in power query together? - powerbi

I am trying to add a step in power query to replace any value "?" with UNKNOWN, but I need to add some sort of conditional or contains statement, and have not been able to figure out how to make it work.
Here is a sample of what the city values look like
and if I use something like this:
= Table.ReplaceValue(#"Uppercased Text","?","UNKNOWN",Replacer.ReplaceText,{"City"})
it will give results like
but I just want it to displace "UNKNOWN" once. I have been trying to combine the below with an if statement or contains, but not been able to make it work correctly.

If statement like this should work:
#"Replace" = Table.ReplaceValue(#"Uppercased Text", each [City], each if Text.Contains([City], "?") then "UNKNOWN" else [City], Replacer.ReplaceValue, {"City"})

Related

Conditionally Filtering Out Rows based on 2 Parameters in w/ Power Query

I have a table similar to the one attached below:
What I would like to do, using power query, is conditionally filter out (remove) rows where CenterNum = 1101 and DepCode = 257. I figured Table.SelectRows() would work but it doesn't and the query just returns, this table is empty. The #"Expanded AccountLookup" ,in my formula below, is referencing the power query applied step before the one I am trying to create. I'm hoping to get some input on how to remove rows based on these two paramters.
= Table.SelectRows(#"Expanded AccountLookup", each [CostCenterNumber] = "1111001" and [NoteTypeCode] = "257")
Thank you!
You didn’t post a screenshot so it is hard to tell if the column format is text or numerical but try removing the quotes around the numbers
= Table.SelectRows(#"Expanded AccountLookup", each [CostCenterNumber] = 1111001 and [NoteTypeCode] = 257)
If that doesn't work, check the actual column names against what you are using, especially for case (upper/lower) and leading/trailing spaces. The best way to do that is to temporarily rename it, and look at the code for the "from name"

PowerBI: Filter Using URL Query String Parameter in report

I applied advance filter in PowerBI desktop, It is working. Similarly, I want to apply "Contains" or "In" operator to filter a report using URL Query String Parameter. I want to filter with delimitated value. "eq" operator is working but "in/contains" operator is not working.
I tried like this:
lstReportFilter.Add(string.Format("&filter=Sheet1/TPId in |181|"));
I have taken reference from here: https://learn.microsoft.com/en-us/power-bi/collaborate-share/service-url-filters
Can you please correct me on what I am doing wrong here?
UPDATE:
I also tried with round bracket, but still its not working. The column have data with pipes, so I need to include pipe while filtering.
lstReportFilter.Add(string.Format("&filter=Sheet1/TPId in (|181|)"));
lstReportFilter.Add(string.Format("&filter=Sheet1/TPId in ('|181|')"));
PowerBI column data
IN Operator expects a comma seperated list of primitive values or a expression
eg:
~/Products?$filter=Name in ('Milk', 'Cheese')
~/Products?$filter=Name in RelevantProductNames
~/Products?$filter=ShipToAddress/CountryCode in MyShippers/Regions
~/Products?$filter=Name in Fully.Qualified.Namespace.MostPopularItemNames
It seems like your use case is the first example, but if you don't have multiple values you can simply use the EQ Operator
like: filter=Sheet1/TPId eq |181|
Reference:
https://learn.microsoft.com/odata/webapi/in-operator
https://learn.microsoft.com/power-bi/collaborate-share/service-url-filters

Passing a Dynamic List of Values into Table.Combine

I have a relatively simple issue, which seems as if it should be achievable, but I have tried absolutely everything with no success.
Here is the situation:
Using Power Query inside Excel I would like to be able to combine multiple queries (lets call these: Query1, Query2 and Query3) into one single query using the Table.Combine function.
The only catch is that the list of queries I will be combining will be dynamic and dependant on another query (lets call this: QueryList)
For example, under certain circumstances QueryList will be:
Query1
Query2
Query3
and under some other condtions QueryList may simply be:
Query1
Query3
What I would like to do is to be able to parse the value of QueryList into the Table.Combine Function:
eg. Table.Combine(#"QueryList")
and thereby allow dynamic consolidation of queries
Whats happening is that I am getting an error that states:
Expression.Error: We cannot convert the value "Query1" to type Table.
Details:
Value=Query1
Type=Type
Update:
I have tried variations of Table.ToList, using { } to create a list, TableFromlist, all with no success (normally errors complain about not being able to comvert from text to list or to table etc.
Thanks in advance for the help.
If your QueryList would be {Query1, Query2} then Table.Combine(QueryList) would work.
Apparently, your QueryList is {"Query1", "Query2"}.
So the strings must be converted to tables, which can be done using Expression.Evaluate. As second parameter, you must supply a record with all possible queries, so the formula becomes, for Query1, Query2, Query3:
= Table.Combine(List.Transform(QueryList, each Expression.Evaluate(_, [Query1 = Query1, Query2 = Query2, Query3 = Query3])))

How to search multiple strings in a string?

I want to check in a powerquery new column if a string like "This is a test string" contains any of the strings list items {"dog","string","bark"}.
I already tried Text.PositionOfAny("This is a test string",{"dog","string","bark"}), but the function only accepts single-character values
Expression.Error: The value isn't a single-character string.
Any solution for this?
This is a case where you'll want to combine a few M library functions together.
You'll want to use Text.Contains many times against a list, which is a good case for List.Transform. List.AnyTrue will tell you if any string matched.
List.AnyTrue(List.Transform({"dog","string","bark"}, (substring) => Text.Contains("This is a test string", substring)))
If you wished that there was a Text.ContainsAny function, you can write it!
let
Text.ContainsAny = (string as text, list as list) as logical =>
List.AnyTrue(List.Transform(list, (substring) => Text.Contains(string, substring))),
Invoked = Text.ContainsAny("This is a test string", {"dog","string","bark"})
in
Invoked
Another simple solution is this:
List.ContainsAny(Text.SplitAny("This is a test string", " "), {"dog","string","bark"})
It transforms the text into a list because there we find a function that does what you need.
If it's a specific (static) list of matches, you'll want to add a custom column with an if then else statement in PQ. Then use a filter on that column to keep or remove the columns. AFAIK PQ doesn't support regex so Alexey's solution won't work.
If you need the lookup to be dynamic, it gets more complicated... but doable you essentially need to
have an ID column for the original row.
duplicate the query so you have two queries, then in the newly created query
split the text field into separate columns, usually by space
unpivot the newly created columns.
get the list of intended names
use list.generate method to generate a list that shows 1 if there's a match and 0 if there isn't.
sum the values of the list
if sum > 0 then mark that row as a match, usually I use the value 1 in a new column. Then you can filter the table to keep only rows with value 1 in the new column. Then group this table on ID - this is the list of ID that contain the match. Now use the merge feature to merge in the first table ensuring you keep only rows that match the IDs. That should get you to where you want to be.
Thanks for giving me the lead. In my own case I needed to ensure two items exist in a string hence I replaced formula as:
List.AllTrue(List.Transform({"/","2017"},(substring) => Text.Contains("4/6/2017 13",substring)))
it returned true perfectly.
You can use regex here with logical OR - | expression :
/dog|string|bark/.test("This is a test string") // retruns true

retrieveing substring using regular expression?

My friend they are like ummm file name which has specific format should be written with like first year (YY) then month (MM) then that sequential number (SEQ) and stored in database and I have to check that all files are exist with same year and same month so...
I'm using regex to catch theses parts to check that concept... and thanks for your help
I'm using the where clause to filter records then I use substr to catch these part I told you about so the query will be something like that..
Select substr(column_name1,4,4),substr(column_name1,0,2),substr(column_name1,2,2),
into seqvar,yearvar,dayvar
from table1
where regex_like (FILENAME,'(CDR-)([1-9][0-9]{0,3})(_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{4}_UK1\.FCDR)
is it best way and fastest to do something like that ??
or using like clause insted of regex at where cluase are better ??
please all your opinion with that case
If you want only the part/group you have mentioned , use this :
`/\((.*?)\)/`
try this in your firebug
var str = 'CDR-([1-9][0-9]{0,3})_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{4}_UK1\.FCDR';
var res = /\((.*?)\)/.exec(str);
console.log(res[1]);
will output : [1-9][0-9]{0,3}
if you want output like ([1-9][0-9]{0,3})
use : /(\(.*?\))/
Since oracle doesn't support lookaheads, maybe it will be easyer to use REGEXP_REPLACE
May look like this:
select regexp_replace(FILENAME, '(CDR-)([1-9][0-9]{0,3})(_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{4}_UK1\.FCDR)', '\2')
from ....