数组跳过工作表中的行/删除重复项并出现循环问题
我才开始使用 Apps Script 几个月,通常我可以弄清楚为什么它会给我错误消息。但是这个最新的问题让我完全不知所措,我找不到任何在这里问过类似问题的人。
我有一段非常简单的代码,它从电子表格中检索数据,循环遍历它以删除一些值,然后再将其粘贴回另一张工作表。但是,循环一直抛出错误“TypeError:无法读取未定义的属性‘0’”。
经过一番挖掘,我想我找到了问题所在——我从工作表中提取的数组比它应该的少了 3 行。
所以
var refArray = sheet.getRange("F5:F").getValues();
的长度为 65,即使工作表中有 68 行。
但真正让我困惑的是,当我运行
var len = refArray.length
时,它返回 68!因此,由于缺乏更好的术语,这使我的循环感到困惑,因为它找不到最后 3 个项目,并且我收到上述错误(至少我是这么认为的)。
我尝试使用
var refArray = sheet.getRange(1,6,sheet.getMaxRows(),1)
提取数据,但这也只是跳过了最后 3 行。没有特别的原因会跳过这些行,有时它只跳过 2 行,所以我不认为问题出在我的数据中……
如果有帮助,我可以分享我的工作表和脚本的模型,我不知道为什么会这样做或如何修复它!
已经感谢大家了。
编辑
我可能一直在找错方向,因为我只是试图在另一张工作表中复制该问题,并且数组似乎被正确提取,但是当它开始循环时错误再次出现。正如我所说,我只是涉足 Apps Script,所以我的循环非常简单。我只想在下面添加完整的序列,看看是否有人能发现错误:
var s = SpreadsheetApp.getActive();
var sheet = s.getSheetByName("Sheet1");
var sheet2 = s.getSheetByName("Sheet2");
function test() {
// get archive Array
var archiveArray = sheet2.getRange("A3:A").getValues();
console.log("Array Check: "+archiveArray[0][0]);
// get ref Array to loop through
var refArray = sheet.getRange("F2:F").getValues();
console.log("Array Check: "+refArray[0][0]); // length 29
var len = refArray.length;
console.log(len); // length 29
for ( var l = len - 1; l > 0; l--){
for( var a = 0; a < archiveArray.length; a++) {
if ( archiveArray[a][0] == refArray[l][0] ) {
refArray.splice(l,1); // remove all duplicates
}
}
}
console.log("New array:"+refArray);
我建议使用
array.includes()
方法并创建一个新数组,而不是更改现有数组:
使用循环:
var archiveArray = ['a', 'b', 'c', 'd'];
var refArray = ['a', 'b', 'e', 'f'];
var new_refArray = [];
for (var val of refArray) {
if (!archiveArray.includes(val)) new_refArray.push(val)
}
console.log(new_refArray); // output [ 'e', 'f' ]
或使用过滤器:
var archiveArray = ['a', 'b', 'c', 'd'];
var refArray = ['a', 'b', 'e', 'f'];
var new_refArray = refArray.filter(val => !archiveArray.includes(val));
console.log(new_refArray); // output [ 'e', 'f' ]
最终代码可以是这样的:
var s = SpreadsheetApp.getActive();
var sheet = s.getSheetByName("Sheet1");
var sheet2 = s.getSheetByName("Sheet2");
function test() {
var archiveArray = sheet2.getRange("A3:A").getValues()
.flat().filter(String); // convert 2D into 1D and remove empty elements
var refArray = sheet.getRange("F2:F").getValues()
.flat().filter(String); // convert 2D into 1D and remove empty elements
var new_refArray = refArray.filter(val => !archiveArray.includes(val));
console.log(new_refArray);
}
注意:如果您想将结果数组粘贴回工作表,它应该是 2D 数组。您可以通过以下方式将平面数组转换为 2D 数组:
new_refArray = new_refArray.map(x => [x]); // [a,b,c] --> [[a],[b],[c]]
由于
.splice
删除了一个元素,请相应调整索引
l
:
refArray.splice(l,1);
--l;//adjust index by 1