Как я могу заблокировать права на редактирование в Google Таблицах с помощью Google Scripts на основе цвета ячейки?

#google-apps-script #google-sheets #google-sheets-api

#google-apps-script #google-sheets #google-sheets-api

Вопрос:

Я работаю с несколькими таблицами Google с цветовой кодировкой и пытаюсь заблокировать все ячейки определенного цвета (например, розовый). Идея состоит в том, чтобы эти ячейки заполнялись автоматически из-за содержащихся в них формул, но не редактировались никем.

Я новичок в Google Scripts и пытаюсь использовать ClassProtection. но если у кого-то уже есть опыт реализации подобного решения, я был бы очень признателен за ваши предложения. Я полагаю, мне придется заходить на каждый лист и интегрировать один и тот же скрипт Google, чтобы все розовые ячейки на всех листах были заблокированы аналогичным образом.

Заранее благодарю вас!

Ответ №1:

Следующий скрипт может защищать определенные диапазоны, и вы можете указать, как выбирать диапазоны на разных листах в соответствии с вашими требованиями.

 function script() {
  var spreadsheet = SpreadsheetApp.getActive();
  var lastrow = spreadsheet.getLastRow();
  var lastcolumn = spreadsheet.getLastRow();
  var ranges = spreadsheet.getRange(1, 1, lastrow, lastcolumn).getBackground()
  var protection = spreadsheet.getActiveSheet().protect();
  for (var i = 0; i < ranges.length; i  ) {
    for (var j = 0; j < lastcolumn; j  ) {
      if (ranges[i][j] == 'Pink') {  //any color code
        protection.setUnprotectedRanges([spreadsheet.getRange(i, j)])
          .removeEditors(['user1@domain.com', 'user2@domain.com']);
        protection.addEditor('user0@domain.com');
      }
    }
  }
  SpreadsheetApp.flush();
}; 

Комментарии:

1. Вы извлекаете только цвет фона первой ячейки на листе (вы должны использовать getBackgrounds вместо этого), это не может работать. Кроме того, вы не перебираете все листы в электронной таблице. Кроме того, вы защищаете весь лист и снимаете защиту с розовой ячейки. Это противоположно тому, что хотел OP. Наконец, нет смысла вызывать flush в конце скрипта, лист все равно обновится, когда скрипт завершится.

Ответ №2:

Проблема:

Вы хотите защитить все ячейки в электронной таблице, которые имеют определенный цвет.

Решение:

Вы можете сделать следующее:

  • Просмотрите все листы в вашей электронной таблице, используя Spreadsheet.getSheets() и forEach() .
  • Для каждого листа вы должны перебирать все ячейки на листе, а не только ячейки с содержимым, поскольку ячейка может быть пустой и иметь цвет, который вы хотите защитить. Из-за этого вам нужно знать, каковы последние строка и столбец на каждом листе, а не только последняя строка и столбец с содержимым. Чтобы получить эту информацию, вы можете использовать Sheet.getMaxRows() и Sheet.getMaxColumns() (если вам не нужно защищать ячейки после последней строки / столбца с содержимым, вы можете использовать getLastRow() и getLastColumn() вместо этого).
  • После того, как вы знаете размеры диапазона для выборки для каждого листа, вы можете использовать getRange(строка, столбец, numRows, numColumns) для получения соответствующего диапазона и getBackgrounds() для получения шестнадцатеричного цветового кода каждой ячейки в диапазоне в 2D-массиве.
  • После получения 2D-массива с фоновыми цветами (вызывается backgrounds в примере ниже), вы должны перебрать этот массив. В приведенном ниже примере для этого используются два цикла for .
  • Для каждой ячейки вы должны проверить, соответствует ли цвет фона цветовому коду, который вы хотите защитить. В приведенном ниже примере код #ff00ff соответствует названному magenta цвету. Отредактируйте это в коде, если это не тот цвет, который вы хотите защитить.
  • Если цвет совпадает, скрипт защитит ячейку. Это можно сделать, сначала извлекая ячейку, используя индексы for счетчика циклов ( i , j ) и getRange(строка, столбец), а затем вызывая Range.protect() и удаляя все редакторы, кроме пользователя, выполняющего скрипт (вы не можете защитить диапазон от этого пользователя), как показано на рисункессылка на метод, которую я только что связал.

Фрагмент кода:

 function protectColor() {
  const spreadsheet = SpreadsheetApp.getActive();
  const sheets = spreadsheet.getSheets();
  sheets.forEach(sheet => { // Loop through sheets in spreadsheet
    const maxRow = sheet.getMaxRows(); // Get last row in sheet
    const maxColumn = sheet.getMaxColumns(); // Get last column in sheet
    const backgrounds = sheet.getRange(1,1,maxRow,maxColumn).getBackgrounds(); // Get cell colors
    for (let i = 0; i < backgrounds.length; i  ) { // Loop through rows in sheet
      for (let j = 0; j < backgrounds[i].length; j  ) { // Loop through current row
        if (backgrounds[i][j] === "#ff00ff") { // Change if necessary
          const pinkCell = sheet.getRange(i 1, j 1); // Get pink cell
          const protection = pinkCell.protect(); // Protect cell
          const me = Session.getEffectiveUser();
          protection.addEditor(me);
          protection.removeEditors(protection.getEditors());
          if (protection.canDomainEdit()) {
            protection.setDomainEdit(false);
          }
        }
      }
    }
  });
}
 

Примечание:

  • Поскольку совершенно неизвестно, какие ячейки розовые, скрипт должен индивидуально защитить каждую ячейку этим цветом. Это не очень эффективно, и если бы вы знали, что существует шаблон для раскраски ячеек (например, если все ячейки в строке всегда имеют один и тот же цвет), вы могли бы сразу раскрасить больший диапазон, сократив время выполнения protect процесса и повысив эффективность (см. Раздел Использование пакетные операции).