我的最终目标是here,但由于我没有得到回复,我开始从零开始学习东西(无论如何最好)。基本上,我想要一个可以识别错误并修复错误的脚本
那么,第一部分是能够识别错误。有没有办法使用Google Script识别单元格中是否有错误,并返回特定的消息?或者我只需要做一个if / else表示“如果单元格值为'#N / A',请执行此操作”,加上“如果单元格值为'#ERROR',请执行此操作”,继续执行各种错误?。基本上我想要ISERROR(),但是在剧本中
答案 0 :(得分:2)
使用辅助函数抽象出恶意:
function isError_(cell) {
// Cell is a value, e.g. came from `range.getValue()` or is an element of an array from `range.getValues()`
const errorValues = ["#N/A", "#REF", .... ];
for (var i = 0; i < errorValues.length; ++i)
if (cell == errorValues[i])
return true;
return false;
}
function foo() {
const vals = SpreadsheetApp.getActive().getSheets()[0].getDataRange().getValues();
for (var row = 0; row < vals.length; ++row) {
for (var col = 0; col < vals[0].length; ++col) {
if (isError_(vals[row][col])) {
Logger.log("Array element (" + row + ", " + col + ") is an error value.");
}
}
}
}
在辅助函数中使用Array#indexOf
:
function isError_(cell) {
// Cell is a value, e.g. came from `range.getValue()` or is an element of an array from `range.getValues()`
// Note: indexOf uses strict equality when comparing cell to elements of errorValues, so make sure everything's a primitive...
const errorValues = ["#N/A", "#REF", .... ];
return (errorValues.indexOf(cell) !== -1);
}
如果/当使用Array#includes
升级Google Apps脚本时,这将是比Array#indexOf
更好的选择。
答案 1 :(得分:1)
更新:2020年3月25日
@tehhowch表示“如果/当Google Apps脚本使用Array#includes升级时,那将是比Array#indexOf更好的选择。” 。
Array.includes现在可以在Apps脚本中运行,并且与indexOf
相比,可以预期提供了一种更加简单的方法。
此示例与先前的答案有所不同,它使用特定范围来表明不需要循环遍历每个单元格。实际上,此答案将适用于任何范围长度。
答案的两个关键方面是:
function foo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourcename = "source_sheet";
var source = ss.getSheetByName(sourcename);
var sourcerange = source.getRange("A2:E500");
var sourcevalues = sourcerange.getValues();
// define the error values
var errorValues = ["#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A","#ERROR!"];
// loop though the columns
for (var c = 0;c<5;c++){
// create an array for the column
var columnoutput = sourcevalues.map(function(e){return e[c];});
// loop through errors
for (var errorNum=0; errorNum<errorValues.length;errorNum++){
// get the error
var errorvalue = errorValues[errorNum]
// Logger.log("DEBUG: column#:"+c+", error#:"+e+", error value = "+errorvalue+", does col include error = "+columnoutput.includes(errorvalue));
// if the error exists in this column then resposnse = true, if the error doesn't exist then response = false
if (columnoutput.includes(errorvalue) != true){
Logger.log("DEBUG: Column#:"+c+", error#:"+errorNum+"-"+errorvalue+" - No ERROR");
} else {
Logger.log("DEBUG: column#:"+c+", error#:"+errorNum+"-"+errorvalue+"- ERROR EXISTS");
}
}
}
return;
}
答案 2 :(得分:0)
我有一个类似的问题,并使用getDisplayValue()而不是getValue()来解决
尝试类似的东西:
function checkCells(inputRange) {
var inputRangeCells = SpreadsheetApp.getActiveSheet().getRange(inputRange);
var cellValue;
for(var i=0; i < inputRangeCells.length; i++) {
cellValue = inputRangeCells[i].getDisplayValue();
if (cellValue=error1.....) { ... }
}
}
显示值应该给您显示给用户的内容,而不是#ERROR!
答案 3 :(得分:0)
更短的是,在 [vals] 数组上使用嵌套的 forEach(),然后检查单元格值是否与具有 indexOf 的 [errorValues] 数组的值匹配。这比 for 循环快...
function foo() {
const errorValues = ["#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A","#ERROR!"];
const vals = SpreadsheetApp.getActive().getSheets()[0].getDataRange().getValues();
vals.forEach((val,row) => { val.forEach((item, col) => {
(errorValues.indexOf(item) !== -1) ? Logger.log("Array element (" + row + ", " + col + ") is an error value.") : false ;
});
});
}