简体   繁体   English

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

[英]Google Apps Script run time very slow when protecting multiple ranges

Currently, I have a Google Script where I have to protect multiple ranges for multiple people across multiple sheets in one worksheet. 目前,我有一个Google脚本,其中必须保护一个工作表中多个工作表中多个人的多个范围。

Here is the code I have right now: 这是我现在拥有的代码:

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
        ]);
    };

  };
};

Understandably, the code takes a very long time. 可以理解,代码需要长时间。

What I'm trying to figure out is how to reduce the number of getRange() calls I make throughout the script. 我想弄清楚的是如何减少我在整个脚本中进行的getRange()调用的次数。 From what I understand, that slows down a script tremendously. 据我了解,这极大地减慢了脚本的运行速度。

I tried var protection = range[0][0].protect().setDescription(protectionDescription); 我尝试了var protection = range[0][0].protect().setDescription(protectionDescription); , after defining var range as sheet.getRange(1,1,62,16) but it gives the error Cannot read property "0" from undefined . 在将var range定义为sheet.getRange(1,1,62,16)但给出了错误无法从undefined读取属性“ 0”

Is there anyway to speed up this function? 无论如何,有没有要加快此功能? Right now, I'm doing one sheet at a time (each sheet takes about 5 minutes). 现在,我一次只做一张纸(每张纸大约需要5分钟)。

EDIT: Here is the updated (and much faster code) for anyone that cares (thanks BMcV): 编辑:这是任何关心的人(感谢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]);
        }
    }
}

There are a few things which may help make the script more efficient and most likely, faster. 有几件事可以帮助使脚本更高效,并且更有可能更快。

Take advantage of hoisting . 利用吊装的优势。 In many areas of this script, variables are defined multiple times. 在此脚本的许多区域中,变量被多次定义。 It would be better to do this: 这样做会更好:

var number = 1; // Some code here involving number
number = 10;    // notice no var at the start!

This function should also be split up into a few helper functions. 此功能也应分为几个辅助功能。 This will help make your code more readable and easier to maintain. 这将有助于使您的代码更具可读性并且更易于维护。

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());
    }
}

This way, at least you don't have to write the code again and again. 这样,至少您不必一次又一次地编写代码。 This concept is called DRY (Don't Repeat Yourself). 这个概念称为DRY(不要重复自己)。 Whenever possible, move repetitive code to a separate function. 只要有可能,请将重复代码移至单独的函数。 Now, it will be easier to find ways to improve the performance. 现在,将更容易找到提高性能的方法。

One thing that may help would be to move the spreadsheet definition outside of the loop. 可能有帮助的一件事是将电子表格定义移出循环。 Currently, SpreadsheetApp.getActiveSpreadsheet() is called 30 times and only needs to be called 1 time. 当前, SpreadsheetApp.getActiveSpreadsheet()被调用30次,仅需要被调用1次。

The main thing would be to simplify the function generally. 主要的事情是一般地简化功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM