Apps脚本-删除保护

时间:2019-06-20 18:48:13

标签: google-apps-script google-sheets

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

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

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

是否有可能这样做?

2 个答案:

答案 0 :(得分:1)

保护类型

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

取消保护

有一种专门用于从Protection / Sheet中删除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 Spreadsheet owner ,Gmail编辑器用户,权限设置为“关闭”,可安装onEdit()触发器)。看看会发生什么:

enter image description here

有用的链接

  1. addEditor() reference;
  2. remove() reference;
  3. getProtections() reference;

答案 1 :(得分:0)

使用实际保护号码。

你能做什么。

创建一个OnEdit函数,该函数在元数据或注释中记录单元格的值和用户。 (注释不太安全,但更容易调试)。

在单元格的每次编辑中,它都会检查此元数据,并且如果用户不是同一用户/管理员,它将文本内容恢复为之前为该单元格保存的值(可能弹出窗口显示“不是您要编辑的单元格”)。

在函数底部添加一些内容,表明如果修改没有价值,请清除元数据。