首页 > 解决方案 > Apps 脚本 - 删除保护

问题描述

我想通过只允许用户编辑空单元格或由他填充的单元格,而不是由其他编辑器填充的单元格来限制 Google 表格中的单元格编辑。简单地说 :

  1. 如果单元格为空白,任何文档编辑器都可以在其中写入内容
  2. 编辑者将内容放入单元格后,只有他和文档所有者才能进一步编辑它
  3. 如果单元格被其作者或文档所有者之一清除,则保护也应自动删除,因此任何编辑者现在都可以对其进行编辑(返回步骤 1)

我正在尝试使用Apps Script来执行此操作,但看起来您无法删除Protection,也无法获取适用于特定单元格的保护列表。

甚至有可能做到这一点吗?

标签: google-apps-scriptgoogle-sheets

解决方案


保护类型

Protection不必全部设置Sheet,您可以调用您选择的protect()方法Range,无论是一个单元格还是自定义Range

移除保护

有一种专门用于ProtectionSheet/中删除的方法Range,称为remove(). 它可以在Protection之前通过getProtections()方法调用获得的任何对象上调用(getProtections()方法返回Array所有Protection实例中的一个)。

在您的情况下,生成的流程如下所示:

  1. 编辑器清除单元格 -> 调用getProtections()-> 检查目标单元格 -> remove()
  2. 单元格收到一个值 -> 调用-> 通过/protect()添加编辑器;addEditor()addEditors()

这两个步骤都可以放入可安装的onEdit()触发器中,例如在正在编辑的单元格上触发。

示例脚本

再一次,您尝试实现的目标是可能的,请尝试下面的脚本(不要忘记将其作为可安装触发器的回调包含在内)。它使其他编辑器无法编辑此单元格,直到当前用户清空它,反之亦然[UPD:优化'getRow()'和'getColumn()'用法]。

/**
 * Protects and unprotects ranges;
 * @param {Object} e event object;
 */
function protect(e) {

  //access edited range, value and sheet;
  var rng = e.range;
  var val = e.value;
  var sh  = rng.getSheet();

  //access edited range row and column;
  var row = rng.getRow();
  var col = rng.getColumn();

  //access protections;
  var ps = sh.getProtections(SpreadsheetApp.ProtectionType.RANGE);

  //filter out other cells protections;
  ps = ps.filter(function(p){
   var ptd = p.getRange();
   if(row===ptd.getRow()&&col===ptd.getColumn()) {
     return p;
   }
  })[0];

  //if protection not set -> protect;
  if(!ps) {
    var protection = rng.protect(); //protect Range;
    var users = protection.getEditors(); //get current editors;

    protection.addEditor(Session.getEffectiveUser());
    protection.removeEditors(users); //remove other editors' access;
  }else {
    if(!val) { ps.remove(); } //if cell is empty -> remove protection;
  }

}

假设

此解释和示例脚本假定环境getEffectiveUser()有所不同(例如,脚本项目未部署为 WebApp +execute as me等)。

关于重要性addEditor()

addEditor()根据我们在评论中的讨论,如果之前不使用该方法,应该注意将自己锁定在编辑单元格之外的可能性removeEditors()(要复制的测试条件是:GSuite 电子表格所有者,Gmail 编辑器用户,权限设置为“关闭”,可安装onEdit()扳机)。看看可能会发生什么:

在此处输入图像描述

有用的链接

  1. addEditor() 参考
  2. remove() 参考
  3. getProtections() 参考

推荐阅读