Я хотел бы поместить красную рамку вокруг каждой ячейки в электронной таблице, которая не имеет никакой защиты, назначенной ячейке или диапазону ячеек. Я знаю, как установить границу, но как получить доступ к форматированию для незащищенных диапазонов?
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');
}
}
Возможный дубликат Установите цвет и стиль границы в электронной таблице программно





Поскольку вы заявляете, что хотите обрабатывать все незащищенные 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(...);
...
});
...
Этот подход может быть полезен, если вам нужно форматировать каждый диапазон по-разному.
ссылки
Может быть, что-то не так с тем, как я настроил лист. Я попытался создать новый лист и добавил различные диапазоны, но всегда получаю сообщение об ошибке ниже. Диапазоны должны иметь хотя бы один диапазон. (строка 6, файл "Код") 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(); }); var rgl = sheet.getRangeList(upr); rgl.setBorder(true, null, null, null, null, null, "red", SpreadsheetApp.BorderStyle.SOLID_MEDIUM); }); }
@user Да, в моем ответе есть неявное предположение, что на каждом листе будет хотя бы один незащищенный диапазон, когда лист защищен. Как разработчик вы обязаны понять, а затем адаптировать этот код к вашему конкретному сценарию, включая добавление проверки ошибок. если вы не можете устранить ошибку, вам следует задать новый, хорошо изученный вопрос. В качестве второй подсказки подумайте, как вы можете сначала проверить наличие незащищенных диапазонов перед созданием RangeList
В раскрывающихся меню в разделе «Данные» есть пункт меню «Защищенные диапазоны и листы», который дает список «защищенных» диапазонов. Нет пункта меню для отображения "незащищенных" диапазонов. На моем листе есть несколько диапазонов, которые защищены, и некоторые диапазоны, которые не имеют никакой защиты. Я как разработчик это понимаю. Я все еще получаю сообщение об ошибке.
Если вы используете защиту листа, вы также можете исключить (за исключением) определенные диапазоны из защиты листа (так называемые незащищенные диапазоны) с помощью пользовательского интерфейса. Затем эти незащищенные диапазоны можно получить с помощью 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();
}
Согласно документации, это массив
Rangeобъектов. Поэтому используйте методы нормального диапазона.