如何避免在删除名称时出现VLOOKUP错误?

时间:2019-12-05 15:16:57

标签: google-apps-script google-sheets formula

所使用的图片仅来自示例表!我的基本问题是我有一个名为“工作分配”的列表,其中出现了名称(下拉列表)。对于位置(在工作表中),我使用以下公式:=IF(C2<>"",VLOOKUP(C2,'Input Data'!C$3:D$7,2,FALSE),"")

Assignment

这些名称被分配了某些值,它们在同一行中。名称在称为输入数据的工作表中定义!

Input Data

如果现在从“输入数据”工作表中删除诸如Green,John之类的名称,则在另一个工作表(评估)中会出现以下错误。 (有40多个人可以访问此工作表并随机删除名称)在此评估工作表中,值通过以下公式进行评估:

Evaluation
Project Overview

=ARRAY_CONSTRAIN(ARRAYFORMULA(SUM(IF((IF($B$2="dontcare",1,REGEXMATCH(Assignment!$E$3:$E$577,$B$2 &"*")))*(IF($B$3="dontcare",1,(Assignment!$E$3:$E$577=$B$3)))*(IF($B$4="dontcare",1,(Assignment!$D$3:$D$577=$B$4)))*(IF($B$5="dontcare",1,(Assignment!$F$3:$F$577=$B$5)))*(IF($B$6="dontcare",1,(Assignment!$B$3:$B$577=$B$6))),(Assignment!S$3:S$577)))), 1, 1)

以下错误出现在评估表中: 错误: 在对VLOOKUP进行评估时,未找到“ Green,John”值。

ERROR

如何避免此错误?可以通过一个宏从输入数据表中删除不在工作表中的名称来避免该错误吗?您对代码有任何想法吗?也许是公式,还是宏? 带有说明的示例工作表:https://docs.google.com/spreadsheets/d/1OU_95Lhf6p0ju2TLlz8xmTegHpzTYu4DW0_X57mObBc/edit#gid=1763280488

1 个答案:

答案 0 :(得分:1)

如果要执行的操作是确保在值不正确的情况下删除工作表中的行,则可以在 Apps脚本中尝试以下操作:

function onEdit(e) {
  var spreadsheet = e.source;

  var assignment = spreadsheet.getSheetByName("Assignment");
  var assignmentRange = assignment.getDataRange();
  var assignmentNames = assignment.getRange(3, 2, assignmentRange.getNumRows());

  var inputData = spreadsheet.getSheetByName("Input Data");
  var inputDataRange = inputData.getDataRange();

  var i = 1;
  while(assignmentNames.getNumRows() > i){
    var currentCell = assignmentNames.getCell(i, 1);
    var txtFinder = inputDataRange.createTextFinder(currentCell.getValue());
    txtFinder.matchEntireCell(true);
    if(!txtFinder.findNext()){
      assignment.deleteRow(currentCell.getRow())
    }else{
      // We are only steping when no elements have been deleted
      // Otherwise we would skip rows due to shifting in row deletion
      i++;
    }
  }
}


说明

onEdit是Apps脚本中的特殊功能名称,它将在每次parent sheet is modified时执行。

然后,我们从事件对象中检索电子表格

  var spreadsheet = e.source;

现在,我们在Assignment表中获得了相关范围。查看getDataRange documentation的用法,以避免检索不必要的单元格值。从这个范围中,我们实际上得到了我们感兴趣的特定列。

  var assignment = spreadsheet.getSheetByName("Assignment");
  var assignmentRange = assignment.getDataRange();
  var assignmentNames = assignment.getRange(3, 2, assignmentRange.getNumRows());

现在,我们对其他工作表(Input Data)做同样的事情:

  var inputData = spreadsheet.getSheetByName("Input Data");
  var inputDataRange = inputData.getDataRange();

注意:在这里,我没有得到指定的列,因为我假设全名不会在其他任何列中重复。但是,如果您愿意,可以像我在Assignment所做的那样获得指定的范围。


此后,我们要查找Assignment表中不存在的Input Data范围内的特定值,则应尝试使用TextFinder

对于作业you should create a TextFinder中的每个名称。我还不得不制作一个whole cell match

  var i = 1;
  while(assignmentNames.getNumRows() > i){
    var currentCell = assignmentNames.getCell(i, 1);
    var txtFinder = inputDataRange.createTextFinder(currentCell.getValue());
    txtFinder.matchEntireCell(true);

如果txtFinder找到一个值,则findNext()将得出true。另一方面,当txtFinder找不到值时,它将是null并被评估为false。

    if(!txtFinder.findNext()){
      assignment.deleteRow(currentCell.getRow())
    }else{
      // We are only stepping forward when no elements have been deleted
      // Otherwise we would skip rows due to shifting in row deletion
      i++;
    }
  }
}