Google Apps 脚本 运行 保护多个范围时时间很慢
Google Apps Script run time very slow when protecting multiple ranges
目前,我有一个 Google 脚本,我必须在一个作品中为多个 sheet 的多个人保护多个范围 sheet。
这是我现在拥有的代码:
function setPermissions () {
for (var number = 1; number < 30; number++) {
var n = number.toString();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(n);
var protectionDescription = 'Initial Sheet Protection - Script'
var protectedRangesArray = [
'A1:F5',
'G1:G4',
'H1:K5',
'L1:L2',
'M1:N5',
'A6:P8',
'A7:B61',
'A62:P62',
'O9:O61',
'F9:F11',
'A1:P2'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.removeEditors(protection.getEditors());
};
// = Everything else is repeated from here so you really only need to look at the above code.
var protectedRangesArray = [
'C9:E61',
'F12:F61',
'G9:H61',
'P9:P61',
'O3:P5'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
saEmail,
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
brEmail
]);
};
// =====
var protectedRangesArray = [
'K9:N61'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
bmEmail,
brEmail
]);
protection.removeEditors([
saEmail,
amEmail,
meEmail
]);
};
// =====
var protectedRangesArray = [
'G5:G5'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L3:L3'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L4:L4'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
amEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L5:L5',
'I9:J61'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
meEmail
]);
protection.removeEditors([
saEmail,
amEmail,
bmEmail,
brEmail
]);
};
};
};
可以理解,代码需要 非常 的时间。
我想弄清楚的是如何减少我在整个脚本中进行的 getRange()
调用次数。据我了解,这会极大地减慢脚本的速度。
我在将 var range
定义为 sheet.getRange(1,1,62,16)
后尝试了 var protection = range[0][0].protect().setDescription(protectionDescription);
,但出现错误 无法从未定义的 [= 中读取 属性“0” 34=]。
有什么加速这个功能的方法吗?现在,我一次做一个 sheet(每个 sheet 大约需要 5 分钟)。
编辑:这是为所有关心的人更新的(速度更快的代码)(感谢 BMcV):
function setPermissions() {
var worksheet = SpreadsheetApp.getActiveSpreadsheet();
var protectionDescription = 'Initial Sheet Protection - Script';
var protectedRangesArray = [];
var addEditorsArray = [];
var removeEditorsArray = [];
for (var number = 0; number < 30; number++) {
var sheet = worksheet.getSheetByName(number.toString());
protectedRangesArray = [
[//0
'A1:F5',
'G1:G4',
'H1:K5',
'L1:L2',
'M1:N5',
'A6:P8',
'A7:B61',
'A62:P62',
'O9:O61',
'F9:F11',
'A1:P2'],
[//1
'C9:E61',
'F12:F61',
'G9:H61',
'P9:P61',
'O3:P5'],
[//2
'K9:N61'],
[//3
'G5:G5'],
[//4
'L3:L3'],
[//5
'L4:L4'],
[//6
'L5:L5',
'I9:J61']
];
addEditorsArray = [
[], //0
[saEmail, amEmail, bmEmail, meEmail], //1
[bmEmail, brEmail], //2
[amEmail, bmEmail, meEmail], //3
[amEmail, bmEmail, meEmail], //4
[bmEmail, meEmail], //5
[meEmail] //6
];
removeEditorsArray = [
[saEmail, amEmail, bmEmail, brEmail, meEmail], //0
[brEmail], //1
[saEmail, amEmail, meEmail], //2
[saEmail, brEmail], //3
[saEmail, brEmail], //4
[saEmail, amEmail, brEmail], //5
[saEmail, amEmail, bmEmail, brEmail] //6
];
protectRanges(sheet, protectionDescription, protectedRangesArray, addEditorsArray, removeEditorsArray)
};
};
function protectRanges(sheet, protectionDescription, protectedRangesArray, addEditorsArray, removeEditorsArray) {
var i = 0, n,
len = protectedRangesArray.length,
range, protection;
for (i; i < len; i++) {
n = 0
for (n; n < protectedRangesArray[i].length; n++) {
range = sheet.getRange(protectedRangesArray[i][n]);
protection = range.protect().setDescription(protectionDescription);
protection.addEditors(addEditorsArray[i]);
protection.removeEditors(removeEditorsArray[i]);
}
}
}
有几件事可能有助于使脚本更高效,而且很可能更快。
充分利用 hoisting。在此脚本的许多区域中,多次定义变量。这样做会更好:
var number = 1; // Some code here involving number
number = 10; // notice no var at the start!
这个函数也应该拆分成几个辅助函数。这将有助于使您的代码更具可读性和更易于维护。
function protectRanges(sheet, protectionDescription, protectedRangesArray) {
var i = 0,
len = protectedRangesArray.length,
range, protection;
for (i; i < len; i++) {
range = sheet.getRange(protectedRangesArray[i]);
protection = range.protect().setDescription(protectionDescription);
protection.removeEditors(protection.getEditors());
}
}
这样至少不用再一遍又一遍的写代码了。这个概念叫做 DRY(不要重复自己)。只要有可能,将重复的代码移到一个单独的函数中。现在,将更容易找到提高性能的方法。
可能有帮助的一件事是将电子表格定义移到循环之外。目前SpreadsheetApp.getActiveSpreadsheet()
调用了30次,只需要调用1次。
主要是简化功能。
目前,我有一个 Google 脚本,我必须在一个作品中为多个 sheet 的多个人保护多个范围 sheet。
这是我现在拥有的代码:
function setPermissions () {
for (var number = 1; number < 30; number++) {
var n = number.toString();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(n);
var protectionDescription = 'Initial Sheet Protection - Script'
var protectedRangesArray = [
'A1:F5',
'G1:G4',
'H1:K5',
'L1:L2',
'M1:N5',
'A6:P8',
'A7:B61',
'A62:P62',
'O9:O61',
'F9:F11',
'A1:P2'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.removeEditors(protection.getEditors());
};
// = Everything else is repeated from here so you really only need to look at the above code.
var protectedRangesArray = [
'C9:E61',
'F12:F61',
'G9:H61',
'P9:P61',
'O3:P5'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
saEmail,
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
brEmail
]);
};
// =====
var protectedRangesArray = [
'K9:N61'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
bmEmail,
brEmail
]);
protection.removeEditors([
saEmail,
amEmail,
meEmail
]);
};
// =====
var protectedRangesArray = [
'G5:G5'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L3:L3'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
amEmail,
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L4:L4'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
bmEmail,
meEmail
]);
protection.removeEditors([
saEmail,
amEmail,
brEmail
]);
};
// =====
var protectedRangesArray = [
'L5:L5',
'I9:J61'
];
for (var i = 0; i < protectedRangesArray.length; i++) {
var range = sheet.getRange(protectedRangesArray[i]);
var protection = range.protect().setDescription(protectionDescription);
protection.addEditors([
meEmail
]);
protection.removeEditors([
saEmail,
amEmail,
bmEmail,
brEmail
]);
};
};
};
可以理解,代码需要 非常 的时间。
我想弄清楚的是如何减少我在整个脚本中进行的 getRange()
调用次数。据我了解,这会极大地减慢脚本的速度。
我在将 var range
定义为 sheet.getRange(1,1,62,16)
后尝试了 var protection = range[0][0].protect().setDescription(protectionDescription);
,但出现错误 无法从未定义的 [= 中读取 属性“0” 34=]。
有什么加速这个功能的方法吗?现在,我一次做一个 sheet(每个 sheet 大约需要 5 分钟)。
编辑:这是为所有关心的人更新的(速度更快的代码)(感谢 BMcV):
function setPermissions() {
var worksheet = SpreadsheetApp.getActiveSpreadsheet();
var protectionDescription = 'Initial Sheet Protection - Script';
var protectedRangesArray = [];
var addEditorsArray = [];
var removeEditorsArray = [];
for (var number = 0; number < 30; number++) {
var sheet = worksheet.getSheetByName(number.toString());
protectedRangesArray = [
[//0
'A1:F5',
'G1:G4',
'H1:K5',
'L1:L2',
'M1:N5',
'A6:P8',
'A7:B61',
'A62:P62',
'O9:O61',
'F9:F11',
'A1:P2'],
[//1
'C9:E61',
'F12:F61',
'G9:H61',
'P9:P61',
'O3:P5'],
[//2
'K9:N61'],
[//3
'G5:G5'],
[//4
'L3:L3'],
[//5
'L4:L4'],
[//6
'L5:L5',
'I9:J61']
];
addEditorsArray = [
[], //0
[saEmail, amEmail, bmEmail, meEmail], //1
[bmEmail, brEmail], //2
[amEmail, bmEmail, meEmail], //3
[amEmail, bmEmail, meEmail], //4
[bmEmail, meEmail], //5
[meEmail] //6
];
removeEditorsArray = [
[saEmail, amEmail, bmEmail, brEmail, meEmail], //0
[brEmail], //1
[saEmail, amEmail, meEmail], //2
[saEmail, brEmail], //3
[saEmail, brEmail], //4
[saEmail, amEmail, brEmail], //5
[saEmail, amEmail, bmEmail, brEmail] //6
];
protectRanges(sheet, protectionDescription, protectedRangesArray, addEditorsArray, removeEditorsArray)
};
};
function protectRanges(sheet, protectionDescription, protectedRangesArray, addEditorsArray, removeEditorsArray) {
var i = 0, n,
len = protectedRangesArray.length,
range, protection;
for (i; i < len; i++) {
n = 0
for (n; n < protectedRangesArray[i].length; n++) {
range = sheet.getRange(protectedRangesArray[i][n]);
protection = range.protect().setDescription(protectionDescription);
protection.addEditors(addEditorsArray[i]);
protection.removeEditors(removeEditorsArray[i]);
}
}
}
有几件事可能有助于使脚本更高效,而且很可能更快。
充分利用 hoisting。在此脚本的许多区域中,多次定义变量。这样做会更好:
var number = 1; // Some code here involving number
number = 10; // notice no var at the start!
这个函数也应该拆分成几个辅助函数。这将有助于使您的代码更具可读性和更易于维护。
function protectRanges(sheet, protectionDescription, protectedRangesArray) {
var i = 0,
len = protectedRangesArray.length,
range, protection;
for (i; i < len; i++) {
range = sheet.getRange(protectedRangesArray[i]);
protection = range.protect().setDescription(protectionDescription);
protection.removeEditors(protection.getEditors());
}
}
这样至少不用再一遍又一遍的写代码了。这个概念叫做 DRY(不要重复自己)。只要有可能,将重复的代码移到一个单独的函数中。现在,将更容易找到提高性能的方法。
可能有帮助的一件事是将电子表格定义移到循环之外。目前SpreadsheetApp.getActiveSpreadsheet()
调用了30次,只需要调用1次。
主要是简化功能。