Типы защиты
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()
триггер). Посмотрите, что может произойти:
Полезные ссылки
addEditor()
ссылка ;
remove()
ссылка ;
getProtections()
ссылка ;