Если я вас правильно понимаю, вы хотите отслеживать изменения в защите листа. Как вы сказали, не существует триггеров Apps Script, которые могли бы отслеживать это.
Обходной путь (триггер на основе времени и служба свойств):
В качестве обходного пути я бы предложил сделать следующее:
- Создайте основанный на времени триггер, который будет периодически запускать функцию (например, каждую 1 минуту ). Вы можете сделать это либо вручную , либо программно , запустив эту функцию один раз:
function createTrigger() {
ScriptApp.newTrigger("trackProtections")
.timeBased()
.everyMinutes(1)
.create();
}
Это вызовет функцию trackProtections
каждую минуту , Эта функция предназначена для отслеживания изменений в защитных листах с момента последнего запуска (в этом примере - 1 минута go).
- В сработавшей функции извлекает текущие защитные листы, сохраните их в свойствах скрипта и сравните ранее сохраненные средства защиты с текущими (проверьте editors , et c.). Вы можете использовать JSON .stringify () и JSON .parse () , чтобы иметь возможность сохранять эти защиты в свойствах сценария (которые принимают только строки) и преобразовывать их обратно. , Это может быть что-то вроде следующего (проверьте встроенные комментарии):
function trackProtections() {
var scriptProperties = PropertiesService.getScriptProperties(); // Get script properties (old protections)
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets(); // Get all sheets in spreadsheet
sheets.forEach(function(sheet) { // Iterate through each sheet in the spreadsheet
var sheetName = sheet.getName();
// Get sheet current protection (null if it's unprotected):
var protection = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0];
// Get previous editors of current sheet (stored in script properties):
var oldEditors;
if (scriptProperties.getProperty(sheetName) !== null) {
oldEditors = scriptProperties.getProperty(sheetName).split(',');
}
// Get current editors of current sheet:
var newEditors;
if (protection) {
newEditors = protection.getEditors().map(function(editor) {
return editor.getEmail();
});
}
if (oldEditors && !newEditors) { // Protection for the sheet was removed
scriptProperties.deleteProperty(sheetName); // Remove old property (protection doesn't exist anymore)
Logger.log('protection for ' + sheetName + ' was removed!');
} else if (!oldEditors && !newEditors) { // There were and there aren't any protections for the sheet
Logger.log('there are no protections');
} else if (!oldEditors && newEditors) { // Protection for the sheet was added
Logger.log('protection for ' + sheetName + ' was added!');
scriptProperties.setProperty(sheetName, newEditors.toString()); // Add script property with current editors
} else {
if (newEditors.sort().join(',') !== oldEditors.sort().join(',')) { // Check if old and current editors are the same
var addedEditors = newEditors.filter(function(editor) {
return oldEditors.indexOf(editor) === -1; // Return editors that are in current protection but not in old one (added)
});
var removedEditors = oldEditors.filter(function(editor) {
return newEditors.indexOf(editor) === -1; // Return editors that were in old protection but not in current one (removed)
});
Logger.log('protection for ' + sheetName + ' was modified!');
Logger.log('these editors were added: ' + JSON.stringify(addedEditors));
Logger.log('these editors were removed: ' + JSON.stringify(removedEditors));
scriptProperties.setProperty(sheetName, newEditors.toString()); // Add script property with current editors
}
}
});
}
Эта функция перебирает все листы в электронной таблице и ищет изменения в защите с момента последнего выполнения (будь то лист стал защищенным, или незащищенным, или изменились ли редакторы).
В этом примере средства защиты сохраняются в свойствах сценария следующим образом: каждое свойство имеет имя листа в качестве ключа и электронные письма различных редакторов листа в качестве значения (через запятую) , Сценарий использует toString и split для хранения массива электронных писем редактора в свойстве, поскольку свойства сценария принимают в качестве значения только строки.
Вы также можете отслеживать другие параметры защиты, которые меняются (описание и т. Д. c.), Что делает скрипт немного более сложным (и вам, вероятно, придется использовать JSON.stringify
и * 1041). *, но я надеюсь, что этого упрощенного примера будет достаточно, чтобы вы поняли рабочий процесс.
- Функция также должна проверять, есть ли изменения между текущими средствами защиты и теми, которые были ранее сохранены, и делать то, что вы планировали делать, когда менялись средства защиты листа. Так как я не знаю, что вы хотели сделать в этой ситуации, я просто использую
Logger.log
, чтобы регистрировать изменения, которые произошли с защитой с момента последнего выполнения.
Ссылка: