在使用基于日期的谷歌脚本自动删除之前删除一系列单元格的保护

问题描述 投票:0回答:1

我正在尝试制作一个自定义轮班封面Google表格,人们可以在其中添加他们需要覆盖的轮班,然后其他人可以选择轮班。作为其中的一部分,我编写了两段谷歌脚本代码。第一个自动保护用户输入的每个单元格,因此除所有者或原始编辑者之外的任何人都无法删除或更改班次封面和时间。当单元格被清除时,此脚本还会删除对单元格的保护。第二个脚本会自动删除所有已经过去的班次封面,以保持工作表整洁。 这两个脚本单独工作都很好,但它们一起导致了一个我似乎无法解决的问题。当自动删除脚本在每天结束时自动运行时,单元格的保护规则将被保留,但由于这些单元格不再存在,它们仅在保护列表中显示为“#REF”。这不会立即造成任何问题,但随着时间的推移,将会有数百个问题堆积起来,我认为这可能会导致一些问题。有没有一种方法可以让删除脚本在删除所选单元格之前删除它们的所有保护? 我所说的“#REF”

自动保护代码:

function onEdit(e){
if (e.value == null){
  let prot = SpreadsheetApp.getActiveSheet().getProtections(SpreadsheetApp.ProtectionType.RANGE);
  for (let i in prot){
    if (prot[i].getRange().getA1Notation() == e.range.getA1Notation())
      prot[i].remove();
  }
} else {
  let protection = e.range.protect();
  protection.removeEditors(protection.getEditors());
  if (protection.canDomainEdit())
    protection.setDomainEdit(false);
}
}

自动删除代码:

function deleterow() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var numRows = sheet.getLastRow()-1;
var dataRange = sheet.getRange(startRow, 2, numRows);
var data = dataRange.getValues();
var today = new Date();
today.setHours(0,0,0,0);
for (i = data.length-1; i > -1; i--) {
  var row = data[i];
  var sheetDate = new Date(row);
  sheetDate.setHours(0,0,0,0);
  if (today > sheetDate) {
    var range = sheet.getRange(i+3,2,1,15);
    range.deleteCells(SpreadsheetApp.Dimension.ROWS)
  }
} 

}

理想情况下,我希望自动删除代码来删除单元格及其保护,或者是否有办法让另一个脚本删除任何 #REF 的保护也可以。

google-sheets google-apps-script google-sheets-formula
1个回答
0
投票

我相信您的目标如下。

  • 当通过函数
    deleterow()
    删除单元格时,您想要删除受保护的范围。
  • 从您的
    onEdit
    和您的图像来看,每个受保护的范围始终是一个单元格。

如果我的理解是正确的,那么下面的修改如何?在此修改中,您的

deleterow
已被修改。

修改后的脚本:

function deleterow() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var p = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  var obj = p.reduce((o, e) => {
    var range = e.getRange();
    var k = `${range.getRow()}_${range.getColumn()}`;
    o[k] = o[k] ? [...o[k], e] : [e];
    return o;
  }, {});
  var startRow = 3;
  var numRows = sheet.getLastRow() - 1;
  var dataRange = sheet.getRange(startRow, 2, numRows);
  var data = dataRange.getValues();
  var today = new Date();
  today.setHours(0, 0, 0, 0);
  for (i = data.length - 1; i > -1; i--) {
    var row = data[i];
    var sheetDate = new Date(row);
    sheetDate.setHours(0, 0, 0, 0);
    if (today > sheetDate) {
      var range = sheet.getRange(i + 3, 2, 1, 15);
      var rowStart = range.getRow();
      var rowEnd = rowStart + range.getNumRows() - 1;
      var colStart = range.getColumn();
      var colEnd = colStart + range.getNumColumns() - 1;
      for (var r = rowStart; r <= rowEnd; r++) {
        for (var c = colStart; c <= colEnd; c++) {
          var k = `${r}_${c}`;
          if (obj[k]) {
            obj[k].forEach(e => e.remove());
          }
        }
      }
      range.deleteCells(SpreadsheetApp.Dimension.ROWS);
    }
  }
}

运行此脚本时,在

range.deleteCells(SpreadsheetApp.Dimension.ROWS);
之前,当单元格
sheet.getRange(i + 3, 2, 1, 15)
受到保护时,这些单元格将被删除。但是,在这种情况下,从你的问题来看,它假设受保护的范围是单个单元格。请注意这一点。

示例脚本:

关于

if there is a way to have another script that deletes any protections which are #REF that would work too.
,当你想删除
#REF!
的保护范围时,下面的示例脚本怎么样?

function sample() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var p = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  p.forEach(e => {
    if (e.getRange().getA1Notation() == "#REF!") {
      e.remove();
    }
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.