【问题标题】:How to ignore already protected sheets with script?如何用脚本忽略已经受保护的工作表?
【发布时间】:2021-05-18 02:49:02
【问题描述】:

每天创建 2-3 张,但至少要制作一张 这些范围正在保护 ["B3:U27", "W3:AP27", "B29:U33", "W29:AP33"]

我将 42 个范围减少到这 4 个范围以使其更快,但仍然 在 1 分钟内它可以保护大约 8 个文件问题是在几个月内它可以增长超过 100 个文件 这将使我达到 6 分钟的超时限制,并且会中断脚本。

这是我目前正在使用的脚本。 我想知道是否可以通过某种方式对其进行修改以忽略已经受保护的工作表?

function main(){ //Main function to run
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  var disregard = ["List", "Data", "Template"]; //ADD SHEET NAMES HERE THAT YOU WANT TO BE DISREGARDED

  for(var x=0; x<sheets.length; x++){
    if(disregard.some(data => sheets[x].getName().includes(data))){ 
      //E.g. Disregard any sheet names added on the "disregard" array
    }else{
      unlockCertainRanges(sheets[x]);
    }
  }
}

function unlockCertainRanges(currentSheet){ //Function to unlock certain ranges on your spreadsheet
  var sheet = currentSheet;
  // Remove all range protections in the spreadsheet
  var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  for (var i = 0; i < protections.length; i++) {
    var protection = protections[i];
    protection.remove();
  }

  var protection = sheet.protect();
  //restrict editors to owner
  protection.getRange().getA1Notation();
  var eds = protection.getEditors();
  protection.removeEditors(eds);

  //set unprotected ranges
  var ranges = protection.getUnprotectedRanges();
  var data = ["B3:U27", "W3:AP27", "B29:U33", "W29:AP33"]; // ADD YOUR RANGES HERE
  data.forEach(res => { //LOOPS INTO EVERY ARRAY CONTAINING SPECIFIC RANGES
    ranges.push(sheet.getRange(res));
    protection.setUnprotectedRanges(ranges); //REMOVES THE PROTECTION ON THE RANGE
  });
}

它可以是已经受到保护的东西,或者上面有挂锁不能触摸吗?
我试图找到一种方法来检索已受保护的工作表的名称。
我的意思是 getSheetName() 之类的东西,但适用于受保护的对象。

或者如果这个描述已经有这样的保护,可以把它放在例外中?

setDescription('已经保护');

我没有太多的编码经验;我找到了a very similar question,但我并没有看懂很多代码

有人有想法吗?

【问题讨论】:

  • 可以看Sheet.getProtections()
  • @MetaMan 如果你是这个意思,删除这个部分也会重新扫描// Remove all range protections in the spreadsheet var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE); for (var i = 0; i &lt; protections.length; i++) { var protection = protections[i]; protection.remove(); }
  • 您的问题是“如何使用脚本忽略已受保护的工作表?”您可以查看每个工作表是否具有保护,并且只返回没有保护的工作表的名称。

标签: google-apps-script google-sheets


【解决方案1】:

我相信@MetaMan 的简单含义是,您需要首先检查工作表是否包含受保护的范围。请参阅下面的代码。

代码:

function main() {
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  // Get list of sheets protected
  var protections = SpreadsheetApp.getActiveSpreadsheet().getProtections(SpreadsheetApp.ProtectionType.SHEET);
  var protectedSheets;
  // If protections isn't set, initialize as empty array
  if (protections)
    protectedSheets = protections.map(protection => protection.getDescription());
  else
    protectedSheets = [];

  var disregard = ["List", "Data", "Template"]; //ADD SHEET NAMES HERE THAT YOU WANT TO BE DISREGARDED

  for (var x = 0; x < sheets.length; x++) {
    if (disregard.some(data => sheets[x].getName().includes(data))) {
      //E.g. Disregard any sheet names added on the "disregard" array
    } else {
      // If protectedSheets doesn't include the name, process the sheet
      if (!protectedSheets.includes(sheets[x].getName()))
        unlockCertainRanges(sheets[x]);
    }
  }
}

function unlockCertainRanges(currentSheet) {
  Logger.log("\"" + currentSheet.getName() + "\" is being processed");
  var sheet = currentSheet;
  var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);

  for (var i = 0; i < protections.length; i++) {
    var protection = protections[i];
    protection.remove();
  }

  // set names of sheets as description for future checks
  var protection = sheet.protect().setDescription(currentSheet.getName());
  //restrict editors to owner
  protection.getRange().getA1Notation();
  var eds = protection.getEditors();
  protection.removeEditors(eds);

  //set unprotected ranges
  var ranges = protection.getUnprotectedRanges();
  var data = ["B3:U27", "W3:AP27", "B29:U33", "W29:AP33"]; // ADD YOUR RANGES HERE
  data.forEach(res => { //LOOPS INTO EVERY ARRAY CONTAINING SPECIFIC RANGES
    ranges.push(sheet.getRange(res));
    protection.setUnprotectedRanges(ranges); //REMOVES THE PROTECTION ON THE RANGE
  });
}

// function to delete all existing protections
function deleteAllProtections() {
  var protections = SpreadsheetApp.getActiveSpreadsheet().getProtections(SpreadsheetApp.ProtectionType.SHEET);
  protections.forEach(protection => protection.remove());
}

注意:

  • 请注意,第一次运行需要运行deleteAllProtections(),因此所有工作表第一次将没有保护。成功运行现在将跳过那些有保护的工作表。

参考:

【讨论】:

  • 你所写的,贯穿一切并增加了保护。没有跳过任何内容。
  • 嗨@ÁdámHegedüs,我很抱歉,因为我误解了你的意图。请参阅上面的编辑答案。我使用 ScriptProperties 来存储工作表的名称。然后在调用函数之前检查工作表名称是否存在。如果名称在那里,那么它将跳过工作表。请注意,第一次运行需要初始化属性,所以它需要第一次进入所有工作表。
  • 嗨@NaziA 没问题英语不是我的第一语言,所以翻译对我来说是个问题。你写 // 设置范围来保护......但对我来说,正是这些范围应该从保护中释放(首先保护工作表,然后释放指定范围的保护)你能否在编辑中包括它会如何看起来我是否应该解除这些范围的保护? “B3:U27”、“W3:AP27”、“B29:U33”、“W29:AP33”
  • 嗨@ÁdámHegedüs,我已经修改了编辑部分。请注意,我只是在两者之间添加了您的代码。保护解除后,预计不会再次访问这些表。对不起,如果我误解了,因为帖子实际上并不是代码所说的。思路是一样的,处理完一张sheet后,下一次后续运行不会再处理这张sheet。
  • 对我来说它只运行了大约 1 秒,什么也没做
猜你喜欢
  • 1970-01-01
  • 2018-03-11
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 2021-05-02
  • 2011-06-27
  • 1970-01-01
相关资源
最近更新 更多