Как отформатировать UnprotectedRanges? - PullRequest
1 голос
/ 29 марта 2019

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

function wtf() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var protection = sheet.protect();
var unprotected = protection.getUnprotectedRanges();  
  for (var i = 0; i < unprotected.length; i++) {
  ui.alert('this cell is unprotected');
  } 
}

Ответы [ 2 ]

3 голосов
/ 01 апреля 2019

Проблема:

Существует два типа защит 1 :

  • RANGE - Защита только определенных диапазонов.
  • ЛИСТ - Защита целых листов с исключениями.

Если вы используете защиту листа, вы также можете исключить (кроме) определенные диапазоны из защиты листа (так называемые незащищенные диапазоны) с помощью пользовательского интерфейса. Эти незащищенные диапазоны могут быть затем получены с помощью protection.getUnprotectedRanges() 2 . Защита листа лучше для того, что вы хотите сделать, и этот ответ достаточно объясняет это. Однако диапазоны, которые не защищены на листе, где некоторые диапазоны защищены с помощью «защиты диапазона», не могут быть легко получены.

Возможное решение:

  • Раскрасьте весь лист и очистите формат / восстановление только в защищенных диапазонах.

Отрывок:

function colorUnprotectedRangesRed() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheets()[0]; //first sheet
  const prots = sh.getProtections(SpreadsheetApp.ProtectionType.RANGE); //get onlyRangeProtections
  const rngList = prots.map(function(pro) {
    return pro.getRange().getA1Notation();
  });
  sh.getRange('1:' + sh.getMaxRows()).setBorder(
    true,
    true,
    true,
    true,
    true,
    true,
    'red',
    SpreadsheetApp.BorderStyle.SOLID
  );
  //SpreadsheetApp.flush(); //flush the changes first before clearing format, if you have issues
  sh.getRangeList(rngList).clearFormat();
}
2 голосов
/ 29 марта 2019

Поскольку вы заявляете, что хотите обработать все незащищенные Range с одинаковым образом, я рекомендую вам создать RangeList из возможных непересекающихся Range с, а затем сделать один вызов до Range#setBorder:

function mark_non_protected() {
  const wb = SpreadsheetApp.getActive();
  wb.getSheets().forEach(function (sheet) {
    var pr = sheet.protect();
    var upr = pr.getUnprotectedRanges().map(function (rg) { return rg.getA1Notation(); });
    // Since some sheets may not have any unprotected ranges, don't try to create an empty RangeList:
    if (!upr.length)
      return;

    var rgl = sheet.getRangeList(upr);
    rgl.setBorder(
      true, // top
      true, // left
      true, // bottom
      true, // right
      true, // internal vertical
      true, // internal horizontal
      "red", // color name or CSS hex
      /* optional borderstyle like SpreadsheetApp.BorderStyle.DOTTED */
    );
    /** do other stuff with the unprotected ranges as a whole unit */
  });
}

Альтернативой является вызов setBorder и других методов непосредственно для каждого диапазона:

...
pr.getUnprotectedRanges().forEach(function (rg) {
  rg.setBorder(...);
  rg.someOtherMethod(...);
  ...
});
...

Этот подход может быть полезен, если вам нужно отформатировать каждый диапазон по-разному.

1018 * работы *

...