简体   繁体   English

查找单元格匹配值并返回行号

[英]Find Cell Matching Value And Return Rownumber

The employee sheet contains the name of the employee in cell C2.员工工作表在单元格 C2 中包含员工的姓名。 The name of the employee should also be on the data sheet in the range B3:B153.员工姓名也应出现在数据表的 B3:B153 范围内。

How can I get the rownumber of the cell on the data sheet that matches the employee name?如何获取数据表上与员工姓名匹配的单元格的行号?

I tried the following script but it doesn't seem to work.我尝试了以下脚本,但似乎不起作用。

  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;

  }

Here the code这里的代码

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;
    }
  }
}

When you want to perform this kind of lookup it is better to retrieve data with sheet.getDataRange().getValues() because in this case you will get data as a table of values this is faster.当您想要执行此类查找时,最好使用 sheet.getDataRange().getValues() 检索数据,因为在这种情况下,您将获得作为值表的数据,这会更快。 When you use the standard EmployeeSheet.getRange(2,3,1,1).getValue() in fact you retrieve an object which need more time to be processed and each time you query the spreadsheet.当您使用标准的 EmployeeSheet.getRange(2,3,1,1).getValue() 实际上,您检索的对象需要更多时间来处理,并且每次查询电子表格时。

In my exemple I made only one query to retrieve all data instead n query to retrieve one data each time.在我的示例中,我只进行了一次查询来检索所有数据,而不是每次进行 n 次查询来检索一项数据。

Stéphane斯蒂芬妮

I faced this problem today and I found a native method to do the job.我今天遇到了这个问题,我找到了一种本地方法来完成这项工作。

Here is the snippet to test if it works for you:这是测试它是否适合您的代码段:

  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());
  }

Since Google App Script is a JavaScript platform, I can think of two more methods to get the row index.由于 Google App Script 是一个 JavaScript 平台,所以我可以想到另外两种方法来获取行索引。 It may be a bit faster because these are built-in Array methods.它可能会快一点,因为这些是内置的 Array 方法。

Method 1: using Array.prototype.forEach()方法一:使用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
     }               
  })
}

Method 2: using Array.prototype.findIndex()方法二:使用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
}

To see which method will be faster, I ran these two methods and the accepted anwer's method over a column of 22000 rows of data several times.为了查看哪种方法会更快,我在 22000 行数据的列上多次运行这两种方法和公认的 anwer 方法。 The averages are listed below:平均值如下所示:

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

I guess Array.prototype.forEach is not meant to find the index of a match;我猜Array.prototype.forEach不是为了找到匹配的索引; it is Array.prototype.findIndex that is designed for this purpose Array.prototype.findIndex就是为此目的而设计的

I prefer loading all values into an array once when the sheet is opened, and then using Array.indexOf() to look up the index of the matched string.我更喜欢在打开工作表时将所有值加载到数组中,然后使用 Array.indexOf() 查找匹配字符串的索引。 I think this solution will have less execution time than other solutions.我认为此解决方案的执行时间将少于其他解决方案。

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
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM