google-apps-script - Apps 脚本 - 删除保护
问题描述
我想通过只允许用户编辑空单元格或由他填充的单元格,而不是由其他编辑器填充的单元格来限制 Google 表格中的单元格编辑。简单地说 :
- 如果单元格为空白,任何文档编辑器都可以在其中写入内容
- 编辑者将内容放入单元格后,只有他和文档所有者才能进一步编辑它
- 如果单元格被其作者或文档所有者之一清除,则保护也应自动删除,因此任何编辑者现在都可以对其进行编辑(返回步骤 1)
我正在尝试使用Apps Script来执行此操作,但看起来您无法删除Protection,也无法获取适用于特定单元格的保护列表。
甚至有可能做到这一点吗?
解决方案
保护类型
Protection
不必全部设置Sheet
,您可以调用您选择的protect()
方法Range
,无论是一个单元格还是自定义Range
。
移除保护
有一种专门用于Protection
从Sheet
/中删除的方法Range
,称为remove()
. 它可以在Protection
之前通过getProtections()
方法调用获得的任何对象上调用(getProtections()
方法返回Array
所有Protection
实例中的一个)。
在您的情况下,生成的流程如下所示:
- 编辑器清除单元格 -> 调用
getProtections()
-> 检查目标单元格 ->remove()
; - 单元格收到一个值 -> 调用-> 通过/
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()
扳机)。看看可能会发生什么:
有用的链接
推荐阅读
- vue.js - 如何添加旧版本的 vuetify
- java - JavaFX:如何在用户输入上动态添加文本字段和按钮
- javascript - javascript 在新创建的元素上自动引发点击事件
- sql-server - 如何在 STUFF 中包含单引号
- aws-lex - 使用 Connect/Lex 在机器人中录制对话
- python - Django LogoutView 不发出 user_logged_out 信号
- r - 以条件条件方式扩展向量
- c# - 当您必须直接引用控件时,MVVM 如何适应 WPF
- sql - 我需要根据同一查询中其他字段的多个条件对一个字段的值求和。例如
- docker - 如何将配置设置传递给 docker 映像以进行本地开发?