0
votes

Using the code below I'm able to look through multiple sheets in a spreadsheet to find the first value that equals the selected cell. The only problem with this bit is: The cell with the value found is highlighted yellow, but the cell with the value found isn't selected. See code below for hopping through sheets. I can't get my head around this :)

Funny thing is that the code for highlighting and selecting a value does work when I'm not hopping through the list of sheets, see the best answer: Find value in spreadsheet using google script

function SearchAndFind() {

//determine value of selected cell
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();

//create array with sheets in active spreadsheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();

//loop through sheets to look for value
for (var i in sheets) {

 //Set active cell to A1 on each sheet to start looking from there
  SpreadsheetApp.setActiveSheet(sheets[i])
  var sheet = sh.getActiveSheet();
  var range = sheet.getRange("A1");
  sheet.setActiveRange(range);

//set variables to loop through data on each sheet
  var activeR = cell.getRow()-1;
  var activeC = cell.getColumn()-1;
  var data = sheets[i].getDataRange().getValues()
  var step = 0

//loop through data on the sheet  
  for(var r=activeR;r<data.length;++r){
    for(var c=activeC;c<data[0].length;++c){
      step++
      Logger.log(step+' -- '+value+'  =  '+data[r][c]);
      if(data[r][c]==''||step==1){ continue };
      if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
         sheet.getRange(r+1,c+1).activate().setBackground('#ffff55');
        return;
      }
    }
  }
 }

}
1
Have you considered the fact that your code looks for the search item only in rows and columns greater than the active row/column. For example, if you have the word 'Test' in B3 and the same word 'Test' is in A1 of another sheet, it won't be found and therfore no highlighting and moving of cursor will happenSrik
Also remove everything that sets an active-something. Its unnecesary and much slower. you dont need to change the active sheet or range to read or write to it.Zig Mandel
@ZigMandel you are right, but thats my lack of experience in more 'complex' codingLone Programmer
@Srik You are right, but doesn't my code 'fix' that problem before it starts to loop through data on each sheet?Lone Programmer

1 Answers

0
votes

This code is able to search across multiple sheets, it is obviously based on your published code but uses a memory (scriptProperties) to keep the search value 'alive' when changing from one sheet to the next one and to know when to search for it. It has 2 non-optimal aspects : 1° you have to keep searching up to the last occurrence before you can begin a new search. 2° : when it switches from sheet n to sheet n+1 it first selects cell A1 before finding the value occurrence.

I guess it should be possible to get rid of these issues but right now I don't find how :-) Maybe the approach is simply not the best, I started from a simple one sheet script modified and complexified... that's usually not the best development strategy (I know), but anyway, it was a funny experiment and a good logic exercise ... Thanks for that.

function SearchAndFind() {

  //determine value of selected cell
  var sh = SpreadsheetApp.getActiveSpreadsheet();
  var ss = sh.getActiveSheet();
  var cell = ss.getActiveCell();
  var value = cell.getValue();
  if(ScriptProperties.getProperty('valueToFind')!=''){value = ScriptProperties.getProperty('valueToFind')};

  //create array with sheets in active spreadsheet
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets()
  var sheetNumber = sheets.length;
  var currentSheet = ss.getIndex()-1;
  Logger.log(currentSheet);

  //loop through sheets to look for value
  for (var i = currentSheet ; i<sheetNumber ; ++i ){
    Logger.log('currentSheet = '+i)
    //Set active cell to A1 on each sheet to start looking from there
    SpreadsheetApp.setActiveSheet(sheets[i])
//    sheets[i].getRange(1,1).activate();
    //set variables to loop through data on each sheet
    var activeR = cell.getRow()-1;
    var activeC = cell.getColumn()-1;
    var data = sheets[i].getDataRange().getValues()
    var step = 0;

    //loop through data on sheet  
    for(var r=activeR;r<data.length;++r){
      for(var c=activeC;c<data[0].length;++c){
        step++
          Logger.log('sheet : '+i+'    step:'+step+'   value '+value+'  =  '+data[r][c]);
        if(data[r][c]==''||(step==1&&i==currentSheet)){ continue };
        if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
          sheets[i].getRange(r+1,c+1).activate().setBackground('#ffff55');
          ScriptProperties.setProperty('valueToFind',value);
        return;
        }
      }
    }
      cell = sheets[i].getRange(1,1);

  }  
  ScriptProperties.setProperty('valueToFind','');
  Logger.log('reset');
}