如果找不到匹配项(GAS),如何在下一个空单元格中插入字符串?

时间:2020-10-13 06:08:01

标签: javascript google-apps-script

我修改了Find position of a cell containing a specific string中@Alan Wells给出的代码,但我不知道为什么它仍将匹配的字符串插入下一个空单元格。它应该仅在在values数组中声明的整个数据范围中找不到匹配项的情况下插入。请在下面帮助修改我的代码。谢谢。

function findValueInRange () {
  var ss=SpreadsheetApp.openById('THE_SHEET_ID').getSheetByName('staff'),
      theLastColumn = ss.getLastColumn(),
      theLastRow = ss.getLastRow(),
      lastrow=theLastRow,
      name='Dahlia';
  var values = ss.getRange(1,1,theLastRow,theLastColumn).getValues();

  var i=0,rownum=0,thisRow,colvalue,whatToFind = name,j=0;

  for(i=0;i<values.length;i++) {
    thisRow = values[i];
    for (j=1;j<thisRow.length;j++) {
      colvalue = thisRow[j];
      switch(colvalue){
        case whatToFind :Logger.log("The string is in row: "+(i+1)+" and column: "+(j+1));break;
        case '' : Logger.log("just blank");break;
        default : // when no found match
           var lrow=NextCellRng(theLastColumn);//a custom fn to get the last non-blank row number of the last column only
           ss.getRange(lrow,theLastColumn-1).setValue(name); //insert name in the next cell range
           ss.getRange(lrow,theLastColumn).setValue('attended'); // insert status next to the name
           break;
      }
    }
  }
}

这是我需要参考查找字符串的电子表格:-
lookupsheet
该电子表格存储了两列数据,即名称和状态“有人值守”。我想利用电子表格空间达到行和列的最大限制,因此一旦到达第一列的最大行,它就应该在下一个列中继续,依此类推。因此,当找不到新插入的数据时,数据和搜索范围将随之增加。它应该能够增长,直到工作表可以处理的最大行数和最大列数为止。在这个问题中,我们假设已达到最大行数(5行),这就是为什么要填充下一行的原因。 每当在googleform中输入名称时,我的自定义函数就应该能够首先进行验证:-

  1. 从响应表中获取值(在此问题中,“大丽花”用于抽样测试)
  2. 在查找表中搜索名称。如果存在,则返回列和行号,并返回循环。但是,如果没有,请在下一个空白单元格中插入名称,然后退出循环

但是我注意到的是,无论名称是否存在,该名称仍然会被插入。更糟糕的是,我意识到插入过程对于同一最后一列是一个无限循环。当我无意中在脚本上单击“关闭”时,必须在Project触发器仪表板上终止它。
如果找不到名称“大丽花”,则更新后的工作表应如下所示:-
expectedoutput

2 个答案:

答案 0 :(得分:1)

break语句中的switch表达式只会跳出开关,而不会中断for循环

因此,即使成功(在一个单元格中)找到了一个名称,该函数仍将继续循环遍历其他单元格,并将该名称插入不包含该名称的所有单元格中。

  • 您需要做的是引入一个反映布尔值的全局布尔值
  • 找到名称后-将布尔值设置为true
  • 在每次内部循环迭代结束时检查布尔值是否为true
  • 一旦它是true(已经找到名称)-就会退出for循环
  • 退出for循环后找不到值-继续插入值
  • 如果在工作表中找到该值,则将不会运行设置该值的代码块,因此在完成完整迭代之前已退出该功能

示例:

  var found = false;
  for(i=0;i<values.length;i++) {
    thisRow = values[i];
    for (j=0;j<thisRow.length;j++) {
      colvalue = thisRow[j];
      Logger.log(colvalue);
      switch(colvalue){
        case whatToFind :
          Logger.log("The string is in row: "+(i+1)+" and column: "+(j+1));
          found = true;
          break;
        case '' : 
          Logger.log("just blank");
          break;
        default : // when no found match
          Logger.log("default");
          break;
      }
      if(found==true){
        break;
      }
    }
  }
  var lrow=NextCellRng(theLastColumn);//a custom fn to get the last non-blank row number of the last column only
  ss.getRange(lrow,theLastColumn-1).setValue(name); //insert name in the next cell range
  ss.getRange(lrow,theLastColumn).setValue('attended'); // insert status next to the name

答案 1 :(得分:0)

非常感谢@ziganotschka,因为他的回答以某种方式使我认识到如何在找到搜索字符串后真正退出该函数,如果找不到则作为新数据插入。我们需要使用return命令,只是必须将其放在代码的右行。所以,这是我修改后的代码,并回答了我需要的内容:-

function findValueInRange () {
  var ss=SpreadsheetApp.openById('THIS_SHEET_ID').getSheetByName('staff'),
      theLastColumn = ss.getLastColumn(),
      theLastRow = ss.getLastRow(),
      lastrow=theLastRow,
      name='Dahlia';
  var values = ss.getRange(1,1,theLastRow,theLastColumn).getValues();
  var i=0,rownum=0,thisRow,colvalue,whatToFind = name,j=0;
  
  for(i=0;i<values.length;i++) {
    thisRow = values[i];
    for (j=0;j<thisRow.length;j++) {
    //for (j=1;j<=lastrow;j++) {
      colvalue = thisRow[j];
      switch(colvalue){
        case whatToFind :Logger.log("The string is in row: "+(i+1)+" and column: "+(j+1));return;
        case '' : Logger.log("just blank");break;
        default : Logger.log("default"); break;// when no found match
      }
    }
  }
  var lrow=NextCellRng(theLastColumn);//a custom fn to get the last non-blank row number of the last column only
  ss.getRange(lrow,theLastColumn-1).setValue(name); //insert name in the next cell range
  ss.getRange(lrow,theLastColumn).setValue('attended'); // insert status next to the name 
}