我想通过只允许用户编辑空单元格或由他填充的单元格,而不允许其他编辑器填充的单元格来限制Google表格中的单元格编辑。简单地说:
我正在尝试使用Apps Script来执行此操作,但是看来您无法删除 Protection,也无法获得适用的保护列表到特定的单元格。
是否有可能这样做?
答案 0 :(得分:1)
保护类型
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 Spreadsheet owner ,Gmail编辑器用户,权限设置为“关闭”,可安装onEdit()
触发器)。看看会发生什么:
有用的链接
答案 1 :(得分:0)
使用实际保护号码。
你能做什么。
创建一个OnEdit函数,该函数在元数据或注释中记录单元格的值和用户。 (注释不太安全,但更容易调试)。
在单元格的每次编辑中,它都会检查此元数据,并且如果用户不是同一用户/管理员,它将文本内容恢复为之前为该单元格保存的值(可能弹出窗口显示“不是您要编辑的单元格”)。
在函数底部添加一些内容,表明如果修改没有价值,请清除元数据。