在单元格中输入值时如何延迟单元格保护?

How to delay cell protection when value is entered in a cell?

我在第一次输入数据后使用了以下 OnEdit() 触发代码来锁定单元格:

 function LockCells(event){
 
  var range = event.range;

  var description = 'Protected';   // + stringDate;
  var protection = range.protect().setDescription(description);
  
  var me = Session.getEffectiveUser();
  protection.addEditor(me);
  protection.removeEditors(protection.getEditors());
  
  if (protection.canDomainEdit()) {
  protection.setDomainEdit(false);
}

}

当我以用户身份(不是 sheet 管理员)在单元格中输入值时,它会立即阻止单元格重新输入值。我们可以延迟这个过程吗?我的意思是,如果我们现在输入值,但在 10 分钟或 1 小时后而不是立即应用该单元的保护?

我相信你的目标如下。

  • 您的 LockCells 功能由 OnEdit 可安装触发器执行。
  • 您想运行 函数LockCells 中的脚本在OnEdit 触发器之后是运行。

在这种情况下,下面的修改脚本怎么样?

修改后的脚本 1:

比如当OnEdit触发器为运行时,当你想运行函数中的脚本LockCells后大概6分钟,修改后的脚本可以有点简单如下

function LockCells(event) {
  Utilities.sleep(5 * 60 * 1000); // For example, after 5 minutes, the script is run.
  var range = event.range;
  var description = 'Protected';   // + stringDate;
  var protection = range.protect().setDescription(description);
  var me = Session.getEffectiveUser();
  protection.addEditor(me);
  protection.removeEditors(protection.getEditors());
  if (protection.canDomainEdit()) {
    protection.setDomainEdit(false);
  }
}

修改后的脚本 2:

当你想运行函数中的脚本LockCells超过6分钟后,修改后的脚本如下。请将以下脚本复制并粘贴到电子表格的脚本编辑器中。并且,请将 OnEdit 可安装触发器重新安装到函数 LockCells。这样,当您编辑单元格时,在这个示例脚本中,编辑的单元格会在 10 分钟后受到保护。

var time = 10 * 60 * 1000; // 10 minutes

function LockCells(event) {
  var date = new Date().getTime();
  var range = event.range;
  var a1Notation = `'${range.getSheet().getSheetName()}'!${range.getA1Notation()}`;
  var p = PropertiesService.getScriptProperties();
  var ranges = p.getProperty("ranges");
  ranges = ranges ? JSON.parse(ranges).concat({ date, a1Notation }) : [{ date, a1Notation }];
  p.setProperty("ranges", JSON.stringify(ranges));
  ScriptApp.newTrigger("lockCellsByTrigger").timeBased().after(time).create();
}

function lockCellsByTrigger(e) {
  ScriptApp.getScriptTriggers().forEach(t => {
    if (t.getUniqueId() == e.triggerUid) ScriptApp.deleteTrigger(t);
  });
  var limit = time;
  var now = new Date().getTime();
  var p = PropertiesService.getScriptProperties();
  var ranges = p.getProperty("ranges");
  if (!ranges) return;
  ranges = JSON.parse(ranges);
  var {rranges, r} = ranges.reduce((o, e) => {
    o[e.date + limit < now ? "rranges" : "r"].push(e);
    return o;
  }, {rranges: [], r: []});
  if (rranges.length == 0) return;
  p.setProperty("ranges", JSON.stringify(r));
  var description = 'Protected';
  var me = Session.getEffectiveUser();
  rranges.forEach(({a1Notation}) => {
    var protection = SpreadsheetApp.getActiveSpreadsheet().getRange(a1Notation).protect().setDescription(description);
    protection.addEditor(me);
    protection.removeEditors(protection.getEditors());
    if (protection.canDomainEdit()) {
      protection.setDomainEdit(false);
    }
  });
}
  • 如果要更改时间,请修改time。当前阶段,10分钟后,编辑的单元格被保护。
  • 这个脚本的流程如下。
    1. 编辑单元格时,LockCells 由可安装的 OnEdit 触发器 运行。
    2. 将编辑单元格的a1Notation和日期放入Properties Service,10分钟后安装时间驱动触发器。
    3. 当时间驱动触发器 运行 函数 lockCellsByTrigger 时,10 分钟后编辑的单元格受到保护。

参考文献: