脚本无法删除被过滤器隐藏的行
Script fails to delete a row which is hidden by a filter
我有一个带有 table 的 google 电子表格,其中 headers 激活了过滤器,以便能够隐藏一些行以仅查看一组相关数据。我开发了一个 Apps 脚本,它遍历 table 的行以复制一些数据并删除一些与模式匹配的行。
问题是脚本生成错误并且日志显示已达到执行时间限制。我耐心地调试了脚本,发现它在尝试删除被过滤器隐藏的行时失败了。正常吗?或者,它是 Apps 脚本中的错误吗?
我创建了一个简单的测试电子表格,其中包含如上所述的 table 和一个重现该问题的更简单的 Apps 脚本。该脚本将值从第一列复制到第三列,如果在第二列中找到字符 'c',则删除一行。我在电子表格中添加了三个按钮:第一个执行前一个脚本,第二个删除第三列中的数据,第三个在 table 的末尾添加一行字符 'c' 在第二列。您可以访问文档 here.
测试脚本代码如下:
function CopyValues() {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
let row = 4;
while(sheet.getRange(row,1).isBlank() == false){
let character = sheet.getRange(row,2).getValue();
if (character=='c') {
sheet.deleteRow(row);
} else {
let id = sheet.getRange(row,1).getValue();
sheet.getRange(row,3).setValue(id);
row++;
}
}
}
我相信你的目标如下。
- 您想减少脚本的处理成本。
在你的脚本中,做如下修改怎么样?
修改后的脚本:
function CopyValues() {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
let row = 4;
// I modified below script.
const range = sheet.getRange(row, 1, sheet.getLastRow() - 3, 2);
const values = range.getValues().reduce((ar, [a, b]) => {
if (b != "c") ar.push([a, b, a]);
return ar;
}, []);
range.clearContent().offset(0, 0, values.length, values[0].length).setValues(values);
// If you want to update the range of the basic filter, please use the following script.
var filter = sheet.getFilter();
if (filter) {
var newRange = filter.getRange().offset(0, 0,values.length + 1, values[0].length);
filter.remove();
newRange.createFilter();
}
}
- 在您的脚本中,
getValue
和 setValue
在循环中使用。这样的话,工艺成本就变高了。
- 在这个修改中,首先,检索值并过滤值,然后将值放入sheet。从而降低了脚本的处理成本。
参考文献:
我有一个带有 table 的 google 电子表格,其中 headers 激活了过滤器,以便能够隐藏一些行以仅查看一组相关数据。我开发了一个 Apps 脚本,它遍历 table 的行以复制一些数据并删除一些与模式匹配的行。
问题是脚本生成错误并且日志显示已达到执行时间限制。我耐心地调试了脚本,发现它在尝试删除被过滤器隐藏的行时失败了。正常吗?或者,它是 Apps 脚本中的错误吗?
我创建了一个简单的测试电子表格,其中包含如上所述的 table 和一个重现该问题的更简单的 Apps 脚本。该脚本将值从第一列复制到第三列,如果在第二列中找到字符 'c',则删除一行。我在电子表格中添加了三个按钮:第一个执行前一个脚本,第二个删除第三列中的数据,第三个在 table 的末尾添加一行字符 'c' 在第二列。您可以访问文档 here.
测试脚本代码如下:
function CopyValues() {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
let row = 4;
while(sheet.getRange(row,1).isBlank() == false){
let character = sheet.getRange(row,2).getValue();
if (character=='c') {
sheet.deleteRow(row);
} else {
let id = sheet.getRange(row,1).getValue();
sheet.getRange(row,3).setValue(id);
row++;
}
}
}
我相信你的目标如下。
- 您想减少脚本的处理成本。
在你的脚本中,做如下修改怎么样?
修改后的脚本:
function CopyValues() {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
let row = 4;
// I modified below script.
const range = sheet.getRange(row, 1, sheet.getLastRow() - 3, 2);
const values = range.getValues().reduce((ar, [a, b]) => {
if (b != "c") ar.push([a, b, a]);
return ar;
}, []);
range.clearContent().offset(0, 0, values.length, values[0].length).setValues(values);
// If you want to update the range of the basic filter, please use the following script.
var filter = sheet.getFilter();
if (filter) {
var newRange = filter.getRange().offset(0, 0,values.length + 1, values[0].length);
filter.remove();
newRange.createFilter();
}
}
- 在您的脚本中,
getValue
和setValue
在循环中使用。这样的话,工艺成本就变高了。 - 在这个修改中,首先,检索值并过滤值,然后将值放入sheet。从而降低了脚本的处理成本。