UNIQUE formula in Google Sheets for multiple ranges - if-statement

I have a list of participants in column A. A full employee list in column B. I want to get the list of non-participants in column C. Basically 'B-A' but in list form.
'January' is the participants list:

try:
=FILTER(A:A; NOT(COUNTIF(B:B; A:A)))

It is always an added challenge to write formulas when we don't have access to actual date. But based on what I can see, try this formula in the top cell of any empty column:
=ArrayFormula({"My Header"; FILTER(R2:R,ISERROR(VLOOKUP(TRIM(R2:R),TRIM(T2:T),1,FALSE)))})
You can change "My Header" to something meaningful.
The next part means "FILTER in anything in the range R2:R that cannot be found [i.e., ISERROR(VLOOKUP(...))] in T2:T."
TRIM is used just to account for any accidental/stray spaces that may occur in either list, since that would result in no match if one or the other had extra space.
If this does not do what you expect, please share a link to a sample spreadsheet.

Related

Split a column of lists into multiple columns in PowerBI

I have imported a JSON file into PowerBI and it contains a column in which the values are of type "List". I am looking to expand that column into multiple columns.
Specifically, the data contains a Sprint Name, the start date and the end date of the sprint, along with some other values associated with each sprint.
Trying to use "Expand to new rows" duplicates each sprint instance, creating a table that looks like this, duplicating each sprint instance multiple times for each associated value:
Sprint Name Value
JAN(S1Dev) 2019-01-01
JAN(S1Dev) 2019-01-13
JAN(S1Dev) {attribute}
JAN(S1Dev) {attribute}
JAN(S2Dev) 2019-01-14
JAN(S2Dev) 2019-01-31
JAN(S2Dev) {attribute}
JAN(S2Dev) {attribute}
FEB(S1Test) 2019-02-01
FEB(S1Test) 2019-02-15
... ...
I would like to do something similar to the "expand" feature, which instead creates a new column with each attribute rather than a new row. This is currently vastly increasing the size of my table for no reason, while also making the data practically un-useable. Any help would be appreciated, cheers!
I have found a very simple solution to this, but as it took me some time to figure it out I will answer my own question instead of deleting it to help others in the future...
Upon importing the JSON data into PowerBI first select "Convert to Table" to view the data as a table with editable properties.
Next, click the arrows pointing away from each other at the top of the column of Lists, and select "Extract Values".
Select a delimiter to use for concatenating values, I am choosing a comma since I know that the data contained within the list does not have any commas in it. If your data contains commas within it, choose something else. Similarly, if your data contains one of the delimiters, do not choose that as the delimiter.
It should now display a comma-separated list where it previously displayed "List" in orange text.
Now, right-click on the column and select "Split Column" then choose "By Delimiter"
Select the delimiter that you previously chose, and under "split at" select "Each occurrence of the delimiter" then click OK.
Your column should now be split into multiple columns based on the list!

How to populate a VLOOKUP with a dynamic range in Google Sheets?

I have a file that needs to look up the team name (on a tab called "Parse") of an employee on a tab called "Roster". This can be done with a simple array Vlookup, however, the issue is that each week, we add a row to the Roster tab because employees sometimes move around.
I have already done the majority of legwork by using a MAX/FILTER/COLUMN, LEN formula to determine what the last column is in the Roster tab. I have also created a range that will provide me with the actual range needed for the VLookup. For example: If the last column in Roster is "G", I already have a formula that populates "'Roster'!A2:G", which is the range I would need for my Vlookup. If the last row in Roster is "P", then the formula shows "'Roster'!A2:P".
The formula that gives me the range, as I described in the examples, lives in cell F2 on the Parse tab.
So the hard part is done. All I need to know now is, when writing my Vlookup, how can I have the formula reference the actual contents of cell F2 in the Parse tab instead of thinking the lookup range is cell F2. Here's a visual:
Cell F2 in the Parse tab reads: 'Roster'!A2:G (because as of now, column G is the last column with data. this is correct).
My VLookup is VLOOKUP($A2,$F$2,7,FALSE). However, I want my Vlookup to say VLOOKUP($A2,'Roster'!A2:G,7,FALSE).
Is it possible to have the formula reference what is IN cell F2 instead of referencing just "F2"?
I hope this made sense. It's the end of my workday and I'm very tired.
try something like:
=VLOOKUP(A2, INDIRECT("Roster!A2:"&
SUBSTITUTE(ADDRESS(1, MAX(IF(Roster!1:1<>"", COLUMN(Roster!1:1), )), 4), 1, )),
MAX(IF(Roster!1:1<>"", COLUMN(Roster!1:1), )), 0)

Fuzzy match on google sheets

I'm trying to fuzzy match two columns in google sheets, i've tried numerous formulas but I think it's going to come down to a script to help out.
I have a column with product ID's e.g.
E20067
and then I have another sheet with another column which has image url's relating to this product code such as
http://wholesale.test.com/product/E20067/web_images/E20067.jpg
http://wholesale.test.com/product/E20067/high_res/E20067.jpg
http://wholesale.test.com/product/E20067/high_res/E20067-2.jpg
What I'm wanting to do is "fuzzy" match both of these columns for their product ID, and then create a new column for each match. So it would have the product ID then on the same row in multiple columns each product image URL - like the image below:
Is there a way to do this in google sheets using a script or a formula?
In Google sheets there are a few powerful 'regex' formulas.
Suppose, you have ID list in column A, and URL list in column B
Then use formula:
=REGEXEXTRACT(B1,JOIN("|",$A$1:$A$3))
It will match one of ID's. Drag the formula down to see the result as in picture above.
See more info here
Old thread but, in case you find yourself here, search for my Google Sheets add-on called Flookup. It should do exactly what you want.
For this case, you can use this function:
Flookup (lookupValue, tableArray, lookupCol, indexNum, threshold, [rank], [range])
The parameter details are:
lookupValue: the value you're looking up
tableArray: the table you want to search
lookupCol: the column you want to search
indexNum: the column you want data to be returned from
threshold: the percentage similarity below which data shouldn't be returned
rank: the nth best match (i.e. if the first one isn't to your liking)
range: choose to return the percentage similarity or row number for each match
You can find out more at the official website (examples and such).
Please note that, whereas the OP appears to want the whole list of possible matches, Flookup will only return one result at a time.
Flookup can now return a list of all possible matches through its LRM mode.
Try the following. I am assuming the product codes are in Sheet1 and the URLs are in Sheet2. Both in column A:
=iferror(transpose(FILTER(Sheet2!$A$2:$A,Search("*"& A2 &"*",Sheet2!$A$2:$A))))
Copy down.
If you want to show the image instead of the url try:
=arrayformula(image(iferror(transpose(FILTER(Sheet2!$A$2:$A,Search("*"& A2 &"*",Sheet2!$A$2:$A))))))

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

Searching for unmatched ntheames when comparing spreadsheets

In one spreadsheet I have 3 columns with a first and last name of a person combined. In the 2nd spreadsheet, I have column a = first name and column b = last name.
I want to know which names in spreadsheet one cannot be found in spreadsheet two. I also need to verify the data to make sure that the formula was accurate on finding the correct lookup.
Do I have to combine my columns in spreadsheet 2 to make the first and last name in the same column to make this work?
Which formula would you use for either scenario?
Use this:
=ISNA(MATCH($A1&" "&$B1,Sheet2!$A:$A,FALSE)))
Where (in order):
A1 is the first name column in Sheet1
B1 is the last name column in Sheet1
Sheet2 is the sheet that has the data stored as names separately
$A:$A is the rows that have the two names together
FALSE is because it's an exact match
This will return FALSE if the element does not exist, and TRUE if it does
You can also use:
=VLOOKUP($A1&" "&$B1,Sheet2!$A:$D,3,FALSE)
If you want to retrieve data for a match.
Finally, if you need to do your lookups the other way, take a look at this thread for some ideas on how to split the string into two pieces.