Есть ли событие, которое срабатывает при изменении разрешения для листа в Google Sheets? - PullRequest
2 голосов
/ 12 февраля 2020

onEdit и onChanged, похоже, не срабатывают при удалении или предоставлении разрешения пользователю. Я не видел ни одного события, связанного с этим в документации. Если таких событий нет, есть ли способ программно отслеживать изменения разрешений?

Редактировать: Извините, если вопрос был неясным, но я имел в виду разрешения защиты листов для отдельных листов в книге вместо общего доступа к диску. разрешение на рабочую книгу.

1 Ответ

1 голос
/ 12 февраля 2020

Если я вас правильно понимаю, вы хотите отслеживать изменения в защите листа. Как вы сказали, не существует триггеров 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, чтобы регистрировать изменения, которые произошли с защитой с момента последнего выполнения.

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...