Writing Google Javascript Similar To Vlookup
Solution 1:
in its simplest form and to see the working principle you could try this :
function findinB() {
var sh = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var last=ss.getLastRow();
vardata=sh.getRange(1,1,last,2).getValues();// create an array of data from columns A and Bvar valB=Browser.inputBox('Enter value to search in B')
for(nn=0;nn<data.length;++nn){
if (data[nn][1]==valB){break} ;// if a match in column B is found, break the loop
}
Browser.msgBox(data[nn][0]);// show column A
}
Solution 2:
I figured that @Serge's function can be made slightly more modular and might be worth sharing.
/*
Imitates the Vlookup function. Receives:
1. sheet - A reference to the sheet you would like to run Vlookup on
2. column - The number of the column the lookup should begin from
3. index - The number of columns the lookup should cover.
4. value - The desired value to look for in the column.
Once the cell of the [value] has been found, the returned parameter would be the value of the cell which is [index] cells to the right of the found cell.
*/
function vlookup(sheet, column, index, value) {
var lastRow=sheet.getLastRow();
vardata=sheet.getRange(1,column,lastRow,column+index).getValues();
for(i=0;i<data.length;++i){
if (data[i][0]==value){
returndata[i][index];
}
}
}
Any suggestions or improvements are appreciated. This could also be a good opportunity to start a repo for much needed Google Sheet API functions that are missing. I started a new repo which might someday turn into something more useful, if you're up to contributing your own custom made functions, please don't hesitate to PR.
Cheers!
Solution 3:
//~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`//--//Dependent on isEmpty_()// Script Look-up/*
Benefit of this script is:
-That google sheets will not continually do lookups on data that is not changing with using this function as it is set with hard values until script is kicked off again.
-Unlike Vlookup you can have it look at for reference data at any Column in the row. Does not have to be in the first column for it to work like Vlookup.
-You can return the Lookup to Memory for further processing by other functions
Useage:
var LocNum = SpreadsheetApp.openById(SheetID).getSheetByName('Sheet1').getRange('J2:J').getValues();
Lookup_(Sheetinfo,"Sheet1!A:B",0,[1],"Sheet1!I1","n","y");
//or
Lookup_(Sheetinfo,"Sheet1!A:B",0,[1],"return","n","n");
//or
Lookup_(Sheetinfo,"Sheet1!A:B",0,[0,1],"return","n","n");
//or
Lookup_(Sheetinfo,"Sheet1!A:B",1,[0],"return","y","n");
//or
Lookup_(Sheetinfo,"Sheet1!A:G",4,[0],"Database!A1","y","y");
//or
Lookup_(Sheetinfo,LocationsArr,4,[0],"return","y","y");
*/functionLookup_(Search_Key,RefSheetRange,SearchKey_Ref_IndexOffSet,IndexOffSetForReturn,SetSheetRange,ReturnMultiResults,Add_Note)
{
if(Object.prototype.toString.call(Search_Key) === '[object String]')
{
varSearch_Key = newArray(Search_Key);
}
if(Object.prototype.toString.call(IndexOffSetForReturn) === '[object Number]')
{
varIndexOffSetForReturn = newArray(IndexOffSetForReturn.toString());
}
if(Object.prototype.toString.call(RefSheetRange) === '[object String]')
{
varRefSheetRangeArr = RefSheetRange.split("!");
varRef_Sheet = RefSheetRangeArr[0];
varRef_Range = RefSheetRangeArr[1];
var data = SpreadsheetApp.getActive().getSheetByName(Ref_Sheet).getRange(Ref_Range).getValues(); //Syncs sheet by name and range into var
}
if(Object.prototype.toString.call(RefSheetRange) === '[object Array]')
{
var data = RefSheetRange;
}
if(!/^return$/i.test(SetSheetRange))
{
varSetSheetRangeArr = SetSheetRange.split("!");
varSet_Sheet = SetSheetRangeArr[0];
varSet_Range = SetSheetRangeArr[1];
varRowVal = SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(Set_Range).getRow();
varColVal = SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(Set_Range).getColumn();
}
var twoDimensionalArray = [];
for (var i = 0, Il=Search_Key.length; i<Il; i++) // i = number of rows to index and search
{
varSending = []; //Making a Blank Arrayvar newArray = []; //Making a Blank ArrayvarFound ="";
for (var nn=0, NNL=data.length; nn<NNL; nn++) //nn = will be the number of row that the data is found at
{
if(Found==1 && /^n$/i.test(ReturnMultiResults)) //if statement for found if found = 1 it will to stop all other logic in nn loop from running
{
break; //Breaking nn loop once found
}
if (data[nn][SearchKey_Ref_IndexOffSet]==Search_Key[i]) //if statement is triggered when the search_key is found.
{
var newArray = [];
for (var cc=0, CCL=IndexOffSetForReturn.length; cc<CCL; cc++) //cc = numbers of columns to referance
{
var iosr = IndexOffSetForReturn[cc]; //Loading the value of current ccvarSending = data[nn][iosr]; //Loading data of Level nn offset by value of ccif(isEmpty_(Sending)) //if statement for if one of the returned Column level cells are blank
{
varSending = "#N/A"; //Sets #N/A on all column levels that are blank
}
if (CCL>1) //if statement for multi-Column returns
{
newArray.push(Sending);
if(CCL-1 == cc) //if statement for pulling all columns into larger array
{
twoDimensionalArray.push(newArray);
varFound = 1; //Modifying found to 1 if found to stop all other logic in nn loopbreak; //Breaking cc loop once found
}
}
elseif (CCL<=1) //if statement for single-Column returns
{
twoDimensionalArray.push(Sending);
varFound = 1; //Modifying found to 1 if found to stop all other logic in nn loopbreak; //Breaking cc loop once found
}
}
}
if(NNL-1==nn && isEmpty_(Sending)) //following if statement is for if the current item in lookup array is not found. Nessessary for data structure.
{
for(var na=0,NAL=IndexOffSetForReturn.length;na<NAL;na++) //looping for the number of columns to place "#N/A" in to preserve data structure
{
if (NAL<=1) //checks to see if it's a single column return
{
varSending = "#N/A";
twoDimensionalArray.push(Sending);
}
elseif (NAL>1) //checks to see if it's a Multi column return
{
varSending = "#N/A";
newArray.push(Sending);
}
}
if (NAL>1) //checks to see if it's a Multi column return
{
twoDimensionalArray.push(newArray);
}
}
}
}
if(!/^return$/i.test(SetSheetRange))
{
if (CCL<=1) //checks to see if it's a single column return for running setValue
{
var singleArrayForm = [];
for (var l = 0,lL=twoDimensionalArray.length; l<lL; l++) //Builds 2d Looping-Array to allow choosing of columns at a future point
{
singleArrayForm.push([twoDimensionalArray[l]]);
}
SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(RowVal,ColVal,singleArrayForm.length,singleArrayForm[0].length).setValues(singleArrayForm);
}
if (CCL>1) //checks to see if it's a multi column return for running setValues
{
SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(RowVal,ColVal,twoDimensionalArray.length,twoDimensionalArray[0].length).setValues(twoDimensionalArray);
}
if(/^y$/i.test(Add_Note))
{
if(Object.prototype.toString.call(RefSheetRange) === '[object Array]')
{
SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(RowVal,ColVal,1,1).setNote("VLookup Script Ran On: " + Utilities.formatDate(newDate(), "PST", "MM-dd-yyyy hh:mm a") + "\nRange: Origin Variable" );
}
if(Object.prototype.toString.call(RefSheetRange) === '[object String]')
{
SpreadsheetApp.getActive().getSheetByName(Set_Sheet).getRange(RowVal,ColVal,1,1).setNote("VLookup Script Ran On: " + Utilities.formatDate(newDate(), "PST", "MM-dd-yyyy hh:mm a") + "\nRange: " + RefSheetRange);
}
}
SpreadsheetApp.flush();
}
if(/^return$/i.test(SetSheetRange))
{
return twoDimensionalArray
}
}
//~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`//~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`// Empty String CheckfunctionisEmpty_(string)
{
if(Object.prototype.toString.call(string) === '[object Boolean]') returnfalse;
if(!string) returntrue;
if(string == '') returntrue;
if(string === false) returntrue;
if(string === null) returntrue;
if(string == undefined) returntrue;
string = string+' '; // check for a bunch of whitespaceif('' == (string.replace(/^\s\s*/, '').replace(/\s\s*$/, ''))) returntrue;
returnfalse;
}
//~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`~,~`
Solution 4:
I'm still new to JavaScript and Google Script but this seems to work. And I'm sure there's a better way to limit the for-loop than data.length, but I don't know it.
function vlookup(row, col) {
var x=1, y=1;
var sheet = SpreadsheetApp.getActiveSheet();
vardata = sheet.getDataRange().getValues();
for(x=1; x<data.length; x++){
while(data[x][0]===row){
for(y=1; y<data.length; y++){
while(data[0][y]===col){
var result = data[x][y]
return result;
}
}
}
}
}
Solution 5:
I know I'm late to the party, but I built this script a while back. As expected, it's slow, but it performs vlookup as a script function. Range should be passed as a multidimensional array (array[row][col]). In Google Sheets you can place the cell range in the attributes and it will work:
function vlookupscript(search_key,range,index){
var returnVal = null;
for(var i in range) {
if(range[i][0] == search_key){
returnVal = range[i][(index-1)];
break;
}
}
return returnVal;
}
Post a Comment for "Writing Google Javascript Similar To Vlookup"