简体   繁体   English

Google Sheets Apps脚本处于“编辑”状态时,从受保护范围中删除编辑器的速度非常慢/未完成

[英]Google Sheets Apps Script On Edit Remove Editors From Protected Range Very Slow / Not Completing

I am relatively new to Google Apps Script and am having difficulties with my code below. 我是Google Apps脚本的新手,在下面的代码中遇到了困难。 Basically, it is bound to a sheet that acts as a workflow. 基本上,它绑定到充当工作流程的工作表。 I use the installed onEdit trigger, it loops through to see what cells have changed, then either timestamps, sends an email, or protects a range, given the cells that are changed. 我使用已安装的onEdit触发器,它会循环查看哪些单元格发生了更改,然后根据给定的单元格更改时间戳,发送电子邮件或保护范围。

I am running into the time stamp not always persisting, the email not always sending, and, the protection taking forever. 我遇到的时间戳记不总是持久存在,电子邮件也不是总是发送,并且保护永远存在。

Are there any more efficient ways to do this? 有没有更有效的方法来做到这一点?

function onEditFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();

  // CHECKS FOR CHANGE IN "UPDATES" SHEET ONLY
  if (sheet.getSheetName() == "Updates") {
    var activeRange = sheet.getActiveCell();
    var activeRow = activeRange.getRow();
    var activeColumn = activeRange.getColumn();

    var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Updates');
    var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('LookUps');

    var email = Session.getActiveUser().getEmail();
    var timestamp = new Date();

    var itemAttributes = sheet.getRange(activeRow, 1,activeRow,19).getValues();

  // CHECKS FOR CHANGE IN ITEM COLUMN (A)
    // if column A clear out the other cells
    if (activeColumn == 1) { 
      var r = sheet.getActiveRange();

      // CHECKS IF NUMBER OF ROWS INDICATES A PASTED RANGE
      // if pasted range is more than one row in size, then loop through and do validation on all impacted rows
      if (r.getNumRows() > 1) {  
        SpreadsheetApp.getActiveSpreadsheet().toast('Updating.....please wait.', 'Status', -1);
        var l = r.getNumRows()
        sheet.getRange(activeRow, 2, l, 13).clearContent();
        for (var x = 0; x < l; x++) {
          var ac = activeRow + x
          if(ss.getRange(ac, 1).getvalue != '') {
            sheet.getRange(ac, 12).setValue(email);
          }
          ss.getRange(ac, 1).copyTo(sss.getRange('G1'), {contentsOnly:true})    
          var dynamicList = sss.getRange('G2:G15');   // set to your sheet and range
          var arrayValues = dynamicList.getValues();
          var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(arrayValues);
          ss.getRange(ac, 2).setDataValidation(rangeRule); // set range to your range

          //SpreadsheetApp.flush();
          var NewItemCheck = sss.getRange('G2').getValues()
          if (NewItemCheck == "" && ss.getRange(ac, 1).getvalue != '') {
            sheet.getRange(ac, 10).setValue("NEW ITEM") 
          }
        }  // END FOR LOOP THROUGH ROWS OF RANGE

        SpreadsheetApp.getActiveSpreadsheet().toast('DONE', 'Status', 2);
      }  // END IF RANGE IS GREATER THAN 1 ROW
      else
      {
        sheet.getRange(activeRow, 2, 1, 13).clearContent();
        if(itemAttributes[0][0] != '') {
          sheet.getRange(activeRow, 12).setValue(email);
        }
        sss.getRange('G1').setValue(itemAttributes[0][0]);
        var dynamicList = sss.getRange('G2:G15');
        var arrayValues = dynamicList.getValues();
        var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(arrayValues);
        ss.getRange(activeRow, 2).setDataValidation(rangeRule);
        //SpreadsheetApp.flush();
        var NewItemCheck = sss.getRange('G2').getValues()
        if (NewItemCheck == "" && itemAttributes[0][0] != '') {
          sheet.getRange(activeRow, 10).setValue("NEW ITEM") 
        }
      }
    }

  // CHANGE IN Vendor Name / ID - LOC COLUMN (B)
    if (activeColumn == 2) {
      // if column B in Sheet UPDATES is changed, update adjacent drops downs
      sheet.getRange(activeRow, 5).clearContent();
      sss.getRange('H1').setValue(itemAttributes[0][1])

      var dynamicList = sss.getRange('H2:H15');

      var arrayValues = dynamicList.getValues();
      var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(arrayValues);
      ss.getRange(activeRow, 5).setDataValidation(rangeRule);

      var a = itemAttributes[0][1].slice(-9);
      var b = a.split(" ");
      var c = itemAttributes[0][1].slice(-2);

      var vendLocCombo = [[b,c]];
      var vendLocComboRange = ss.getRange(activeRow, 3, 1, 2);
      vendLocComboRange.setValues(vendLocCombo);
    } 

    // SUBMITTED
    if (activeColumn == 11 && itemAttributes[0][10] ){
      // if column K in Sheet UPDATES is changed to TRUE (checked), email
      // cost analysts in var CostEmail, and protect submitted info
      sheet.getRange(activeRow, 13).setValue(timestamp);
      SpreadsheetApp.flush();

      var Prange = sheet.getRange('A'+activeRow+':M'+activeRow);
      var protection = Prange.protect().setDescription('SubmitLock A'+activeRow+':M'+activeRow);
      protection.removeEditors(protection.getEditors());
      protection.addEditors(['emailhere.com','emailhere.com']);

      if (protection.canDomainEdit()) {
        protection.setDomainEdit(false);
      }
    }

    // COMPLETED
    if (activeColumn == 15 && itemAttributes[0][14]) {
      // if column O in Sheet is changed to TRUE (checked) then user email and timestamp columns Q and R 
      sheet.getRange(activeRow, 17).setValue(email);
      SpreadsheetApp.flush();
      sheet.getRange(activeRow, 18).setValue(timestamp);
      SpreadsheetApp.flush();
      var Prange = sheet.getRange('N'+activeRow+':S'+activeRow);
      var protection = Prange.protect().setDescription('CompleteLock N'+activeRow+':S'+activeRow);
      protection.removeEditors(protection.getEditors());
      protection.addEditors(['emailhere.com','emailhere.com']);

      if (protection.canDomainEdit()) {
        protection.setDomainEdit(false);
      }
    }

    // DENIED
    if (activeColumn == 16 && itemAttributes[0][15]) {
      // if column P in Sheet is checked (true) send email to original submitter in column M
      sheet.getRange(activeRow, 17).setValue(email);
      sheet.getRange(activeRow, 18).setValue(timestamp);

      var Prange = sheet.getRange('O'+activeRow+':T'+activeRow);
      var protection = Prange.protect().setDescription('CompleteLock O'+activeRow+':T'+activeRow);
      protection.removeEditors(protection.getEditors());
      protection.addEditors(['emailhere.com','emailhere.com']);

      if (protection.canDomainEdit()) {
        protection.setDomainEdit(false);
      }

      var DeniedEmailAddress = itemAttributes[0][11];
      var message = "  Comments :     "+itemAttributes[0][13];
      var subject = "[Denied - Contracted Cost Request] "+itemAttributes[0][0];

      MailApp.sendEmail(DeniedEmailAddress, subject, message,{
          name: 'Contracted Cost Update',
          attachments: []
      });

      sheet.getRange(activeRow, 19).setValue("X");
    }
  }
}

EDITS: 编辑:

function onEditFunction(e) {

  if (e.source.getActiveSheet().getSheetName() == "Updates") {
    // CHECKS FOR CHANGE IN "UPDATES" SHEET ONLY

    var sheet = e.source.getActiveSheet();
    var protectionDescription;
    var protectedRange;
    var i;
    var protection;

    var removeEditorsArray = 
["group1@email.com","group2@email"];

    var activeColumn = e.range.getColumn();

    switch(activeColumn){
        case 1: //Item
            changeItem(e, sheet, activeColumn);
            break;
        case 2: //Vendor Name/ID - Loc 
            changeVendor(e, sheet, activeColumn);
            break;
        case 11: //SUBMIT check box
            changeSubmit(e, sheet, activeColumn, protectionDescription, protectedRange, removeEditorsArray);
            break;
        case 15: //COMPLETE check box
            changeComplete(e, sheet, activeColumn);
            break;
        case 16: //DENIED check box
            changeDenied(e, sheet, activeColumn);
            break;
    }
  }
}


function changeSubmit(e, sheet, activeColumn, protectionDescription, protectedRange, removeEditorsArray){
    // if column K in Sheet UPDATES is changed to TRUE (checked), enter a  timestamp and protect submitted info 

    var activeRow = e.range.getRow();
    var timestamp = new Date();
    var removeLen = removeEditorsArray.length

    sheet.getRange(activeRow, 13).setValue(timestamp);  

    protectedRange = 'A'+activeRow+':M'+activeRow;
    protectionDescription = 'SubmitLock A'+activeRow+':M'+activeRow;

    protectRanges(sheet, protectionDescription, protectedRange, removeEditorsArray)
}

function protectRanges(sheet, protectionDescription, protectedRange, removeEditorsArray) {

    var i=0;
    var Len = removeEditorsArray.length;

    protectedRange = sheet.getRange(protectedRange);
    protectionDescription = protectedRange.protect().setDescription(protectionDescription);

    for (i; i < Len; i++) {
        protectionDescription.removeEditor(removeEditorsArray[i]);
    }
}

Thanks to your help @tehhowch and @Vytautas, I was able to come up with a very efficient code, but did have to change the protection to a warning only, which is fine for the purposes of the sheet. 多亏了@tehhowch和@Vytautas的帮助,我才能够提出一个非常有效的代码,但确实必须将保护更改为仅警告,这对于工作表而言是很好的。

Please see below: 请看下面:

function onEditFunction(e) {

  if (e.range.getSheet().getSheetName() == "Updates") {
    // CHECKS FOR CHANGE IN "UPDATES" SHEET ONLY

    var protectedRange;
    var protectionDescription;

    var sheet = e.range.getSheet();
    var activeColumn = e.range.getColumn();

    switch(activeColumn){
        case 1: //Item
            changeItem(e, sheet, activeColumn);
            break;
        case 2: //Vendor Name/ID - Loc 
            changeVendor(e, sheet, activeColumn);
            break;
        case 11: //SUBMIT check box
            changeSubmit(e, sheet);
            break;
        case 15: //COMPLETE check box
            changeComplete(e, sheet, activeColumn);
            break;
        case 16: //DENIED check box
            changeDenied(e, sheet, activeColumn);
            break;
    }
  }
}

function changeSubmit(e, sheet){
    // if column K in Sheet UPDATES is changed to TRUE (checked), enter a timestamp and protect submitted info 

    var activeRow = e.range.getRow();
    var timestamp = new Date();
    var l = e.range.getNumRows();

    if (l > 1){ // if pasted range is more than one row in size, then loop through and do validation on all impacted rows
      SpreadsheetApp.getActiveSpreadsheet().toast('Updating.....please wait.', 'Status',-1);
      }

    for (var x = 0; x < l; x++) {
          sheet.getRange(activeRow + x, 13).setValue(timestamp);
//          SpreadsheetApp.flush();

          protectedRange = 'A'+(activeRow + x) +':M'+(activeRow + x);
          protectionDescription = 'SubmitLock A'+(activeRow + x)+':M'+(activeRow + x);
          protectRanges(sheet, protectionDescription, protectedRange);
        }
    if (l > 1){ // if pasted range is more than one row in size, then loop through and do validation on all impacted rows
      SpreadsheetApp.getActiveSpreadsheet().toast('DONE', 'Status',2);
      }
}

function changeComplete(e, sheet, activeColumn){
  // if column O in Sheet is changed to TRUE (checked) then user email and timestamp columns Q and R 

    var activeRow = e.range.getRow();

    var newData = [];

    var email = Session.getActiveUser().getEmail();
    var timestamp = new Date();

    newData = [[email],[timestamp]];


    sheet.getRange(activeRow, 17, activeRow, 18).setValues(newData);


    protectedRange = 'N'+activeRow+':S'+activeRow;
    protectionDescription = 'CompleteLock N'+activeRow+':S'+activeRow;
    protectRanges(sheet, protectionDescription, protectedRange);
}

function changeItem(e, sheet, activeColumn){

    var activeRow = e.range.getRow();

    var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Updates');
    var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('LookUps');

    var email = Session.getActiveUser().getEmail();

    var l = e.range.getNumRows();
    var itemAttributes = sheet.getRange(activeRow, 1,(activeRow + l - 1),19).getValues();

    if (l > 1){ // if pasted range is more than one row in size, then loop through and do validation on all impacted rows
      SpreadsheetApp.getActiveSpreadsheet().toast('Updating.....please wait.', 'Status',-1);
      }

        for (var x = 0; x < l; x++) {
          if(itemAttributes[x][0] != ''){
            sheet.getRange(activeRow + x, 2,l, 13).clearContent(); // clears out row if new entry for item id
            sheet.getRange(activeRow + x, 12).setValue(email);  // stamps user in created by column
            }

        sss.getRange('G1').setValue(itemAttributes[x][0]);
        var dynamicList = sss.getRange('G2:G15');
        var arrayValues = dynamicList.getValues();
        var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(arrayValues);
        ss.getRange(activeRow + x,2).setDataValidation(rangeRule);

          var NewItemCheck = sss.getRange('G2').getValues()

          if (NewItemCheck == "" && itemAttributes[x][0] != '') {
            sheet.getRange(activeRow + x, 10).setValue("NEW ITEM") 
            }
          }

    if (l > 1){ // if pasted range is more than one row in size, then loop through and do validation on all impacted rows
      SpreadsheetApp.getActiveSpreadsheet().toast('DONE', 'Status',2);
      }
}

function changeVendor(e, sheet, activeColumn){
     // if column B in Sheet UPDATES is changed, update adjacent drops downs

    var activeRow = e.range.getRow();

    var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Updates');
    var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('LookUps');

    var itemAttributes = sheet.getRange(activeRow, 1,activeRow,19).getValues();

    sheet.getRange(activeRow, 5).clearContent();

    sss.getRange('H1').setValue(itemAttributes[0][1])

    var dynamicList = sss.getRange('H2:H15');

    var arrayValues = dynamicList.getValues();
    var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(arrayValues);
    ss.getRange(activeRow,5).setDataValidation(rangeRule);

    var a = itemAttributes[0][1].slice(-9);
    var b = a.split(" ");
    var c = itemAttributes[0][1].slice(-2);

    var vendLocCombo = [[b,c]];
    var vendLocComboRange = ss.getRange(activeRow, 3, 1, 2);
    vendLocComboRange.setValues(vendLocCombo);
} 

function changeDenied(e, sheet, activeColumn){
  // if column P in Sheet is checked (true) send email to original submitter in column M

    var activeRow = e.range.getRow();

    var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Updates');
    var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('LookUps');

    var email = Session.getActiveUser().getEmail();
    var timestamp = new Date();

    var itemAttributes = sheet.getRange(activeRow, 1,activeRow,19).getValues();

      sheet.getRange(activeRow, 17).setValue(email);
      sheet.getRange(activeRow, 18).setValue(timestamp);

    protectedRange = 'N'+activeRow+':S'+activeRow;
    protectionDescription = 'CompleteLock N'+activeRow+':S'+activeRow;
    protectRanges(sheet, protectionDescription, protectedRange);

    var DeniedEmailAddress = itemAttributes[0][11];
    var message = "  Comments :     "+itemAttributes[0][13];
    var subject = "[Denied - Contracted Cost Request] "+itemAttributes[0][0];

    MailApp.sendEmail(DeniedEmailAddress, subject, message,{
        name: 'Contracted Cost Update',
        attachments: []
        });

    sheet.getRange(activeRow, 19).setValue("X");
}

function protectRanges(sheet, protectionDescription, protectedRange) {

    protectedRange = sheet.getRange(protectedRange);
    protectionDescription = protectedRange.protect().setDescription(protectionDescription);
    protectionDescription.setWarningOnly(true);
    SpreadsheetApp.flush();
}

暂无
暂无

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

相关问题 如何从受保护的单元格中删除编辑器或永久保护Google表格中的单元格 - How to Remove Editors from Protected Cells or Permanently Protect Cells in Google Sheets Google 表格:通过受保护的表格和范围中的脚本添加编辑器 - Google Sheets: Add editors via script in Protected Sheet and Ranges Google Apps脚本-是否可以通过脚本更新受保护的范围? - Google Apps Script - Is it possible to update a protected range from a script? 谷歌应用程序脚本非常非常慢 - google apps script very very slow 取消选中Google Apps脚本宏中的受保护范围 - Uncheck view protected range from Google Apps Script macro 如果输入日期已经存在于 Google 表格的受保护范围内,如何避免阻止执行 Apps 脚本代码 - How to avoid a block of Apps Script codes execution if an input date is already there in a protected range in Google Sheets 动态添加编辑器或删除编辑器Google表格 - Add editors or remove editors Google sheets dynamically Google Sheets Apps 脚本,从命名范围返回随机项目 - Google Sheets Apps Script, return random item from named range 使用 Google Apps 脚本在 Google 网站中添加/删除编辑器 - Add/Remove editors in Google sites using Google Apps Script Google Sheet App Script 保护范围并允许基于电子邮件的编辑,但从编辑权限中排除少数列 - Google Sheet App Script Protect Range & Allow Editors Based on Email But Exclude Few Columns From Edit Rights
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM