Як я скопіював аркуш разом із його дозволом у Google Таблицях


10

У електронній таблиці Google під назвою Attendance є аркуш під назвою Template . Користувач дублює цей аркуш, перейменовує аркуш з поточною датою і використовує цей аркуш для позначення відвідуваності студентів. На аркуші шаблону містяться захищені комірки, а відвідуваність позначається введенням ідентифікаційного номера студента у вказаний простір (незахищені комірки). Я використовую наступний сценарій для копіювання декількох аркушів та перейменування їх щодня:

function createDailyAttendance() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var refss = ss.getSheetByName("DataPointers");

    // Get the range Row and Column information.
  var dataRangeRow = refss.getRange("K2").getValue();
  //var dataRangeCol = ss.getRangeByName(ColName).getValue();


   // Get the range of cells that store Duplicate sheet name.
  var AttendanceDataRange = refss.getRange(dataRangeRow);

  var AttendanceObjects = AttendanceDataRange.getValues();

  var template = ss.getSheetByName('Template');

  for (var i=0; i < AttendanceObjects.length; i++) {

     // Put the sheet you want to create in a variable
     var sheet = ss.getSheetByName(AttendanceObjects[i]);

      // Check if the sheet you want to create already exists. If so,
      // log this and loop back. If not, create the new sheet.
        if (sheet) {
           Logger.log("Sheet " + AttendanceObjects[i] + "already exists");
        } else {
           template.copyTo(ss).setName(AttendanceObjects[i]);
           }
        }
  return;
}

Цей скрипт допомагає мені створювати декілька копій аркушів із шаблону, але копії копій не зберігають дозволів на комірки / діапазон. Чи є спосіб додати функцію циклу, яка витягує дозвіл із шаблону та застосовує його щоразу, коли цикл template.copyToстворює аркуш?


Будь ласка , дивіться мою відповідну посаду тут ... stackoverflow.com/questions/40512801 / ...
phinland

Відповіді:


9

Сценарій 1: шаблон - це захищений аркуш із незахищеними діапазонами

У нижченаведеному сценарії я копіюю аркуш, отримую захист типу Sheet, потім захищаю новий аркуш таким же чином: той самий опис, той самий тип. Якщо захист не є лише попередженням, видаліть усі редактори та додайте ті, які дозволені для оригінального аркуша. Нарешті, переведіть петлю на незахищені діапазони, переставляючи кожен з них (через getA1Notation) на новий аркуш, і зніміть захист.

function duplicateProtectedSheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 
  sheet = ss.getSheetByName("Sheet1");
  sheet2 = sheet.copyTo(ss).setName("My Copy"); 
  var p = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0];
  var p2 = sheet2.protect();
  p2.setDescription(p.getDescription());
  p2.setWarningOnly(p.isWarningOnly());  
  if (!p.isWarningOnly()) {
    p2.removeEditors(p2.getEditors());
    p2.addEditors(p.getEditors());
    // p2.setDomainEdit(p.canDomainEdit()); //  only if using an Apps domain 
  }
  var ranges = p.getUnprotectedRanges();
  var newRanges = [];
  for (var i = 0; i < ranges.length; i++) {
    newRanges.push(sheet2.getRange(ranges[i].getA1Notation()));
  } 
  p2.setUnprotectedRanges(newRanges);
}  

Сценарій 2: шаблон - це аркуш із захищеними діапазонами

Використовуючи sheet.getProtectionsметод, ви можете отримати масив захистів на заданому аркуші та перекинути їх, створюючи їх аналоги на цільовому аркуші. Це дещо дратує, оскільки, здається, немає способу просто клонувати захист до іншого діапазону. (Можна змінити діапазон захисту, але це перемістить його в новий діапазон, а не копіювати.)

Отже, у функції нижче я виконую наступне:

  1. Отримайте позначення A1 кожного захищеного діапазону за допомогою p.getRange().getA1Notation();
  2. Захистіть відповідний діапазон цільового аркуша за допомогою p2 = sheet2.getRange(rangeNotation).protect();
  3. Встановіть властивості нового захисту p2відповідно до властивостей оригінального захисту p.
function duplicateSheetWithProtections() {
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 
  sheet = ss.getSheetByName('Template');
  sheet2 = sheet.copyTo(ss).setName('My Copy'); 
  var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  for (var i = 0; i < protections.length; i++) {
    var p = protections[i];
    var rangeNotation = p.getRange().getA1Notation();
    var p2 = sheet2.getRange(rangeNotation).protect();
    p2.setDescription(p.getDescription());
    p2.setWarningOnly(p.isWarningOnly());
    if (!p.isWarningOnly()) {
      p2.removeEditors(p2.getEditors());
      p2.addEditors(p.getEditors());
      // p2.setDomainEdit(p.canDomainEdit()); //  only if using an Apps domain 
   }
  }
} 

Також можна мати захищені діапазони в захищеному аркуші, і в цьому випадку вам потрібно буде поєднати дві функції (виконайте все, що робить кожен з них, за винятком, звичайно, ви будете дублювати аркуш лише один раз.)


Я вставив вашу пропозицію у свій цикл і перевірив сценарій 1, отримав повідомлення про помилку TypeError: Cannot call method "protect" of null. Я отримую цю помилку, оскільки з цього рядка var p2 = sheet.protect();.
Арвінд

1
Отже, це була лінія sheet2.protect();? Тоді це означає, що sheet2 є недійсним, тому слід подивитися на рядок, де він визначений.

У моєму коді sheet2 позначається як аркуш . Визначено якvar sheet = ss.getSheetByName(AttendanceObjects[i]);
Арвінд

У всякому разі. Налагодження коду - це ваша робота, а не моя.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.