The A column is first name and the B column is last name in the spreadsheet I'm manipulating. In the other sheet it's the full name(but not necessarily just firstname + lastname)
HC is the spreadsheet I need to get the data from. This code will work if the person has a unique first name that is the same in both sheets : =VLOOKUP(""&A2&"",HC!$C$1:$I$400,7,False) but this isn't enough in my case. The *s known as wildcards check if this string is contained in another string regardless of it's position.
I tried =VLOOKUP(""&A5&" "&B5&"",HC!$C$1:$I$400,7,False) but that means the two strings have to occur one after the other. I need it to return if search_key1 is contained within the string regardless of accents(á or a) or case (A or a) and the same for search_key2 e.g. the string could be "Seárch_key1 kdslfj SEARCH_KEY2 akldfj" and this would return True and then give the 7th column.
function VLOOKUP2(search_key1,search_key2,range,index){
//is search_key1 contained in one of the cells in the range if so is search_key2 also contained in one of the cells in the range regardless of capitilization and diacritical marks
// return the column specified by the index parameter
}
I know you're asking for a custom function, but I think you could do this with two existing vlookup functions.
If your data on sheet HC looks like this:
Then on your lookup sheet, try this in cell C1 (deleting everything below):
=arrayformula({"Result";if(A2:A<>"",iferror(iferror(vlookup("*"&A2:A&"*"&B2:B&"*",{HC!C:I},7,0),vlookup("*"&B2:B&"*"&A2:A&"*",{HC!C:I},7,0)),),)})
HELP NOTES
The inital vlookup tries to match "*"&A2:A&"*"&B2:B&"*" in {HC!C:I}. {} is used to create an array.
If not, then the iferror tries another vlookup to match "*"&B2:B&"*"&A2:A&"*".
Another iferror deals with no match, removing #N/A.
Then the if(A2:A<>"" only tries the above formula if there is a corresponding value in the same row, in Col A.
The final array {} places "Result" at the top of the column, with the main formula below. After the heading text, ; forces a return in the array.
Within the vlookup, 0 denotes false. 1 would be true.
Related
In Google Sheets "Apps Script" i defined a custom function that receives a format, and some values, then replaces the values into the format's placeholders and return it.
function PRINT_DETAILS(format, productName, quantity) {
/* format expects a string with placeholders like: "{productName} {quantity}"
product: expects a string
quantity: expects an integer
*/
}
In the Products "table" there are the following columns: name, quantity, price, etc.
Each of those have their own named range.
I defined a "print" column where i call the function like this:
= PRINT_DETAILS("{productName} {quantity}"; Products.Name; Products.Quantity)
The problem is that my function is receiving the whole named range, and not just the cell value of the same row.
i.e. im receiving all the products names and all the products quantities...
I successfully used named ranges as cell values in lot of ways: adding them, in "IF" conditions, concat operator "&", etc.
Even in standard functions calls.
Thats why i believe there would be a way to do the same in custom functions.
I wouldnt like to sacrifice readability using cell references like A1 or something.
So im looking for a way to constrain arguments, or get my desired values in a non too-hacky way.
Also if we could get a look into Google Sheets source code, maybe those standard functions are also implemented in JavaScript and they have this already solved.
Description
Excel has a feature where a value of a named range can be passed to a custom formula corresponding to the row the formula is in. Unfortunately Google Sheets does not have the feature. Instead you need to get the row number toof the formula.
Note that this assumes the named ranges start in row 1 and the formulas are on that same row in any sheet.
Thanks to Mike Steelson I have modified the script slightly to improve the script. But not the screeen shot.
=PRINT_DETAILS("{productName} {quantity}",Products.Name,Products.Quantity)
Screen shots
Script
function PRINT_DETAILS(format,productName,quantity) {
try {
var row = SpreadsheetApp.getActiveRange().getRow();
return [productName[row-1],quantity[row-1]];
}
catch(err) {
return err.message;
}
}
Reference
https://support.google.com/docs/thread/92023000?authuser=0&hl=en
I have tried many formulas but i am still not able to get what i want. I need help to write an APP SCRIPT code for it. The problem is that I have to match two data sets and return the value of the adjacent cell. I want the sheet to pick a value from first cell of first row from a sheet and match it to entire cells of a row from other sheet (in the same workbook) and then paste the value which was being matched, infront of the cell which matches it. Now the problem is that my data sets are not equal so i can not use vlookup, i want to match and how much percentage it is matching. So highest percentage should be considered as a match. Kindly visit this link for an example in google sheet. [https://docs.google.com/spreadsheets/d/1u_-64UvpirL2JHpgA--GDa263wVb2idIhIYZlFnX2xQ/edit?usp=sharing]
There are a variety of ways to do this sort of partial matching, depending on the real data and how sophisticated you need to match logic to be.
Let's start with the simplest solution first. Did you know you can use wildcards in VLOOKUP? See Vlookup in Google Sheets using wildcards for partial matches.
So for your example data, add a column C to "Set 1" with the formula:
=VLOOKUP("*" & A2 & "*",'Set 2'!A1:A5,1,FALSE)
Obviously, this method fails if "Baseball bat" was supposed the be results for "Ball" instead of "Ballroom". VLOOKUP will simply return the first result that matches. This method also ignores case sensitivity. Finally, this method only works for appending data to set 1 from set 2, not the other way around. Without knowing more about the actual dataset, it's hard to give a solid solution.
I want to understand how the reduce functions are used in Crossfilter. Namely, the
reduceAdd(p,v){...}
reduceRemove(p,v){...}
and
reduceInitial(p,v){...}
in
group.reduce(reduceAdd, reduceRemove, reduceInitial);
From Crossfilter's API reference, I understand that the p and v arguments represent the group and dimension value respectively.
From what I understand, the return value of the reduce functions determine what the groupValue should be changed to after the element is added or removed from the group. Is this correct?
Also, what is the reduceInitial function for?
That is correct, if you substitute "bin value" for "groupValue" in what you wrote.
A group is made of an array of bins; each bin is a key-value pair. For every group, all rows of the data supplied to crossfilter will "fall into" one bin or another. The reduce functions determine what happens when a row falls into a bin, or is removed from it because the filters changed.
Crossfilter determines which bin any row falls into by using using the dimension value accessor and the group value function.
When are reduction functions called?
When a crossfilter initializes a new group, it adds all the currently matching rows of the data to all the groups. The group determines a key for each row by using the dimension value accessor and the group value function. Then it looks up the bin using that key, and applies the reduceAdd function to the previous bin value and the row data to produce the new bin value.
When any filter on any dimension of the crossfilter changes value, some rows will stop matching and some rows will start matching the new set of filters. The rows that stop matching are removed from the matching bin using the reduceRemove function, and the rows that start matching are added using the reduceAdd function.
When a row is added, some groups may not already have a bin which matches the key for that row. At that point a new bin must be initialized and at that point the group calls reduceInitial to get the user-specified blank value for the bins of that group.
Crossfilter's group.reduce compared to Array.reduce
The reduceAdd and reduceRemove functions are similar to the functions you would pass to Javascript's Array.reduce function. The first parameter p takes the previous value of the bin, and the second paramter v takes the current row data being considered.
In contrast to Array.reduce, in group.reduce
values can be removed as well as added
the initial value is produced by the reduceInitial function instead of being passed to reduce
it doesn't perform the aggregation immediately; instead you are supplying functions that will get called whenever filters change or data is added or removed
I have the results from Google place details. I would like to parse the phone number out of it. How could I do so? I am using OpenRefine and using fetching column on the basis of another column.
Here is an example of Google Place JSON.
As you can see, "formated_phone_number" is a direct child of "result". In Open Refine, you can extract this element using the following GREL formula:
value.parseJson().result.formatted_phone_number
If there are more than one phone number, use a for loop to iterate over the array. The syntax in Open refine is:
forEach(value.parseJson().result, x, x.formatted_phone_number)
(x is a variable name, you can use it or what you want instead.)
The result will be an array. Since an Open Refine column can only display strings, numbers and dates, you must convert the array to string using the join function (and a delimiter of your choice).
forEach(value.parseJson().result, x, x.formatted_phone_number).join('::')
How would I go about writing a custom function in Google Sheets that retrieves a value if the text in a cell in the same row equals what's identified in the function.
For example: If I have a bunch of values from a form, a function that'll allow me to identify the full range of where to look, the column that the number values are contained in, and the text I want the function to look for in the given range.
It's a bit confusing to just describe it. I'll make an example sheet and post it here.
Have you looked into MATCH?
If I understand the question, you could do something like:
MATCH(A1, A2:A100, 1)
Where A1 is your key, A2:A100 is your range, and 1 is the search type.
https://support.google.com/docs/answer/3093378