Google Apps 脚本在保护多个范围时运行时间非常慢

Google Apps Script run time very slow when protecting multiple ranges

本文关键字:范围 运行时间 非常 Apps 脚本 保护 Google      更新时间:2023-09-26

目前,我有一个Google脚本,我必须在一个工作表中的多个工作表中为多个人保护多个范围。

这是我现在的代码:

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"。

有没有办法加快这个功能?现在,我一次做一张纸(每张纸大约需要 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]);
        }
    }
}
有一些

事情可能有助于使脚本更高效,并且很可能更快。

利用吊装。 在此脚本的许多区域中,变量被多次定义。最好这样做:

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 次。

最主要的是一般简化功能。