查找单元格匹配值和 Return 行号

Find Cell Matching Value And Return Rownumber

员工 sheet 包含单元格 C2 中员工的姓名。员工的姓名也应在数据 sheet 上 B3:B153.

范围内

如何获取数据 sheet 中与员工姓名匹配的单元格的行号?

我尝试了以下脚本,但它似乎不起作用。

  var Sheet = SpreadsheetApp.getActive();
  var Employeesheet = Sheet.getSheetByName('Employee')
  var DataSheet = Sheet.getSheetByName('Data');
  var Column = Sheet.getRange(3,2,151,1);
  var Values = column.getValues(); 
  var Row = 0;

  while ( Values[Row] && Values[Row][0] !=(EmployeeSheet.getRange(2,3,1,1).getValue()) ) {
    Row++;
  }

  if ( Values[Row][0] === (EmployeeSheet.getRange(2,3,1,1).getValue()) ) 
    return Row+1;
  else 
    return -1;

  }

这里是代码

function rowOfEmployee(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var employeeName = sheet.getRange("C2").getValue();
  for(var i = 0; i<data.length;i++){
    if(data[i][1] == employeeName){ //[1] because column B
      Logger.log((i+1))
      return i+1;
    }
  }
}

当您要执行此类查找时,最好使用 sheet.getDataRange().getValues() 检索数据,因为在这种情况下,您将获得 table 值的数据是比较快的。当您使用标准 EmployeeSheet.getRange(2,3,1,1).getValue() 实际上,您每次查询电子表格时都会检索一个需要更多时间处理的对象。

在我的示例中,我只进行了一次查询来检索所有数据,而不是 n 次查询每次检索一个数据。

史蒂芬

我更喜欢在 sheet 打开时将所有值加载到数组中一次,然后使用 Array.indexOf() 查找匹配字符串的索引。我认为此解决方案的执行时间将少于其他解决方案。

function updateValues(){
  dataRangeSearch = activeSheet.getRange(1,1,activeSheet.getLastRow());
  dataSearch = dataRangeSearch.getValues().reduce(function (a, b) {
    return a.concat(b);
  });;
}
updateValues();

function findValue(fieldName){
  var row = dataSearch.indexOf(fieldName);
  if (row == -1){ // Variable could not be found
    SpreadsheetApp.getUi().alert('I couldn\'t find field name "'+fieldName+'"');
    return "";
  } else {
    return activeSheet.getRange(row+1,2).getValue(); //Return the value of the field to the right of the matched string
  }
}

由于Google App Script 是一个JavaScript 平台,我可以想到另外两种获取行索引的方法。它可能会快一点,因为这些是内置的 Array 方法。

方法一:使用Array.prototype.forEach()

function getRowIndexUsingforEach(){
  let term = 'user-1700@example.com';
  var data = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1, 1, 2000).getValues();
  data.forEach((val, index) => {
     if(val == term){
         Browser.msgBox(index+1); //because Logger.log() takes too long
     }               
  })
}

方法二:使用Array.prototype.findIndex()

function getRowUsingfindIndex(){
  let term = 'user-1700@example.com';
  let data = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1, 1, 2000).getValues();
  let row = data.findIndex(users => {return users[0] == term});  
  Browser.msgBox(row+1); //because Logger.log() takes too long
}

为了看哪种方法更快,我运行这两种方法和公认的答案的方法对一列22000行数据进行了几次。下面列出了平均值:

  • 使用for loop(来自接受的答案):2.66ms
  • 使用 Array.prototype.forEach:11.75 毫秒
  • 使用 Array.prototype.findIndex:2.00 毫秒

我想 Array.prototype.forEach 并不是要找到匹配项的索引; Array.prototype.findIndex 正是为此而设计的

我今天遇到了这个问题,我找到了一个本地方法来完成这项工作。

这是测试它是否适合您的代码片段:

  var spreadsheet = SpreadsheetApp.getActive();
  var tosearch = "your text to search";
  var tf = spreadsheet.createTextFinder(tosearch);
  var all = tf.findAll();
  
  for (var i = 0; i < all.length; i++) {
    Logger.log('The sheet %s, cell %s, has the value %s.', all[i].getSheet().getName(), all[i].getA1Notation(), all[i].getValue());
  }