如何避免删除名称时发生的 VLOOKUP 错误?

How can I avoid a VLOOKUP Error that occurs when I delete a name?

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

这些名字被赋予了特定的值,它们在同一行。这些名称在名为输入数据的工作sheet 中定义!

如果我现在从输入数据作品sheet中删除像 Green、John 这样的名字,那么我在另一个作品sheet(评估)中会出现以下错误。 (超过40人访问此作品sheet并随机删除姓名)在本评估工作sheet中,值通过以下公式评估:


=ARRAY_CONSTRAIN(ARRAYFORMULA(SUM(IF((IF($B="dontcare",1,REGEXMATCH(Assignment!$E:$E7,$B &"*")))*(IF($B="dontcare",1,(Assignment!$E:$E7=$B)))*(IF($B="dontcare",1,(Assignment!$D:$D7=$B)))*(IF($B="dontcare",1,(Assignment!$F:$F7=$B)))*(IF($B="dontcare",1,(Assignment!$B:$B7=$B))),(Assignment!S:S7)))), 1, 1)

评价出现如下错误sheet: 错误: 在计算 VLOOKUP 期间,未找到值 "Green, John"。

如何避免这个错误?是否可以使用从分配 sheet 中删除不在输入数据 sheet 中的名称的宏来避免此错误?您对代码有什么想法吗?也许是公式或宏? 示例 sheet 及解释:https://docs.google.com/spreadsheets/d/1OU_95Lhf6p0ju2TLlz8xmTegHpzTYu4DW0_X57mObBc/edit#gid=1763280488

如果您想做的是确保在 sheet 中删除存在不正确值的行,您可以在 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.

时执行

之后我们从事件对象

中检索点差sheet
  var spreadsheet = e.source;

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

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

现在我们对另一个做同样的事情 sheet(Input Data):

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

注意:这里我没有得到指定的列,因为我假设全名不会在任何其他列中重复。但是如果你想要,你可以获得指定的范围,就像我在 Assignment.

所做的那样

之后我们想在 Assignment 范围内查找 Input Data sheet 范围内不存在的特定值,您应该尝试 TextFinder

作业中的每个名字 you should create a TextFinder. I have also forced to make a 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++;
    }
  }
}