如何避免删除名称时发生的 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;
现在我们得到了Assignment
sheet中的相关范围。查看 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++;
}
}
}
所用图片仅来自示例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;
现在我们得到了Assignment
sheet中的相关范围。查看 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++;
}
}
}