Forum Discussion
Query editor replacing values based on another column
- 9 years ago
You are right. I was confusing Table.ReplaceValues with Table.TransformColumns. :smileyembarrassed:
My solution works though, but the code you are looking for:
#"Replaced Value" = Table.ReplaceValue(#"Replaced OTH",each [Gender],each if [Surname] = "Manly" then "Male" else [Gender],Replacer.ReplaceValue,{"Gender"})Edit: it seems you switched "old" and "new" in your cide.
I just got this working for multiple columns with the following line:
= Table.ReplaceValue(#"Expanded TS opps", null, each if [Sales Stage] = "Closed" then "Closed" else "Absent",Replacer.ReplaceValue,{"SP Status", "TS Status"})
This is part of a list of potential projects we might work on. This list is physically repeated in two other places, on our Sharepoint and in our timesheet system, and I wanted to check they line up to some degree. I've merged my queries, now I wanted to check where there's a null value in the Sharepoint or Timesheet system lists, if the project's closed on the master list, consider it closed, otherwise mark it as absent.
So what this is doing, blow by blow:
= Table.ReplaceValue( <- we're replace some values here
#"Expanded TS opps", <- this is just the name of the previous step. Yours will be different.
null, <- find null values to replace
each if [Sales Stage] = "Closed" then "Closed" else "Absent", <- check what the master list status is, and respond accordingly ...
Replacer.ReplaceValue,{"SP Status", "TS Status"}) <- ... in these two columns
I hope that's clear enough.
mattlancs, how to skip specifying an else?
I.e. i want to replace the value of a column if another column = something. Else leave everything as is.
- mattlancs7 years agoAdvocate II
Hi gk2go,
If you want it to stay the same as before, you can replace it with itself, so you put the same column name in as the one you're using the replace function on.
For example, in my table of employees, this line goes through the ContractedHours and looks for people with a JobTitle of "Admin". Then, if they're full time (i.e. have ContractedHours = 40) then replace that 40 with 100, otherwise leave it as it is.
= Table.ReplaceValue(#"Capitalized Each Word", 40, each if [JobTitle] = "Admin" then 100 else [ContractedHours], Replacer.ReplaceValue,{"ContractedHours"})
Step by step:
= Table.ReplaceValue( <- summoning the replace-some-values function
#"Capitalized Each Word", <- the name of the previous step, yours will be different
40, <- the number we're going to replace
each if [JobTitle] = "Admin" then 100 else [ContractedHours], <- here's the key bit: after the "else", replace it with the ContractedHours i.e. replace it with itself i.e. don't change anything
Replacer.ReplaceValue,{"ContractedHours"}) <- which column we're doing the replacement in.
Hope that's clear.
Cheers,
Matt
- gk2go7 years agoHelper III
Thank you mattlancs, that worked in indeed.
Can you perhaps help me apply this to this other case:
I have a path and a host columns, i want to find and remove all host substrings from the path.
So if [path] contains [host] then replace [host] in [path], else leave [path] as is.
How would you accomplish that?
- mattlancs7 years agoAdvocate II
Hi gk2go,
That's an excellent puzzle, thank you! I've come up with a solution, though I will say it's well outside my comfort zone so it's perhaps not the most beautiful/efficient version. It seems to work from here though...
Because I don't know quite what your data looks like, I've had to assume that the [Host] could appear anywhere within the [Path], but it might be that it always appears at the end or at the beginning. In that case, you could trim a section out of the following formula to simplify it a bit.
= Table.ReplaceValue(#"Added Custom", each [Path], each if Text.Contains([Path],[Host]) = true then Text.Start([Path], Text.PositionOf([Path], [Host])) & Text.End([Path], Text.Length([Path]) - Text.PositionOf([Path], [Host]) - Text.Length([Host])) else [Path], Replacer.ReplaceText,{"Path"})
Using my now-established notation:
= Table.ReplaceValue(#"Added Custom", <- the usual start, calling to do a replacement then namechecking the row before
each [Path], <- here's a new bit to me: this is going to replace every entry in [Path], not just specific lines.
each if Text.Contains([Path],[Host]) = true then <- first step is to test if the [Path] contains the [Host]. If so...
Text.Start([Path], <- this function says we want to take the first few characters of what's in [Path].
Text.PositionOf([Path], [Host])) <- you have to say how many characters, and you find that out by telling it the position of [Host] in [Path]. I'd have expected you'd need to put a -1 in here (because you want one less character than where [Host] appears) but apparently not!
& <- So up to this point you've got everything from [Path] before where [Host] appears. But we also need everything afterwards. If [Host] only appears at one end, you only need either the two lines before or after this ampersand. This is just here to glue together the before and after. If you wanted to replace [Host], not just remove it, then you could add something else here then another & afterwards.
Text.End([Path], <- next up is what comes at the end of the [Path], after the [Host]. So this function is saying we want the end of the [Path].
Text.Length([Path]) - Text.PositionOf([Path], [Host]) - Text.Length([Host])) <- I don't know of an elegant way to do this - the number of characters we want is the total length of [Path] minus the number of characters before the [Host] minus the length of the [Host] itself. It's like trying to calculate how long you spent eating dessert: it's the time you spent eating the whole meal minus the time you spent on the starter minus the time you spent on the main course.
else [Path], <- this is going back to the 'each if' line earlier - just put the [Path] value back if [Path] didn't contain [Host] in the first place.
Replacer.ReplaceText,{"Path"}) <- finally, as before, which column we're doing the replacement in.
Hopefully that's some help and will either work or inspire you to come up with an even tidier solution!
Cheers,
Matt
- Anonymous6 years agoNot applicable
Hey Matt,
I'm getting an error I don't see anywhere else in this thread.
I'm applying the solution as follows:
= Table.ReplaceValue(#"Replaced Value1", each [mycode], each if [othercode] = "K0606" then "RR" else [mycode],Replacer.ReplaceValue{"mycode"})
And it is returning this error:
Expression.Error: We cannot apply indexing to the type Function.
Details:
Value=[Function]
Index=mycodeAny idea how to resolve this?
Thanks,
Sean
- mattlancs6 years agoAdvocate II
Anonymous
Hiya,
It looks like there's a comma missing after the last ReplaceValue. Fingers crossed that's all it is!
= Table.ReplaceValue(#"Replaced Value1", each [mycode], each if [othercode] = "K0606" then "RR" else [mycode],Replacer.ReplaceValue,{"mycode"})
Cheers,
Matt