W Arkuszach Google, w jaki sposób mogę powielić arkusz wraz z jego zezwoleniem

10

W arkuszu kalkulacyjnym Google o nazwie Frekwencja znajduje się arkusz o nazwie Szablon . Użytkownik powiela ten arkusz, zmienia nazwę arkusza na bieżącą datę i używa tego arkusza do oznaczania obecności studentów. Arkusz szablonu zawiera chronione komórki, a frekwencja jest oznaczana poprzez wpisanie numeru ID studenta w podanym polu (komórki niechronione). Używam następującego skryptu, aby powielać wiele arkuszy i codziennie zmieniać ich nazwy:

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;
}

Ten skrypt pomaga mi tworzyć wiele kopii arkuszy z szablonu, ale duplikaty nie zachowują uprawnień do komórki / zakresu. Czy istnieje sposób na dodanie funkcji pętli, która wyodrębnia uprawnienie z szablonu i stosuje je za każdym razem, gdy pętla template.copyTotworzy arkusz?

Arvind
źródło
Proszę zobaczyć mój powiązany post tutaj ... stackoverflow.com/questions/40512801/…
phinland

Odpowiedzi:

9

Scenariusz 1: szablon jest chronionym arkuszem z niechronionymi zakresami

W skrypcie poniżej duplikuję arkusz, uzyskuję jego ochronę typu Arkusz, a następnie chronię nowy arkusz w ten sam sposób: ten sam opis, ten sam typ. Jeśli ochrona nie jest tylko ostrzeżeniem, usuń wszystkie edytory i dodaj te dozwolone dla oryginalnego arkusza. Na koniec zapętlaj niezabezpieczone zakresy, ponownie przypisując każdy z nich (przez getA1Notation) do nowego arkusza i nie chroń tych.

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);
}  

Scenariusz 2: szablon jest arkuszem z chronionymi zakresami

Za pomocą sheet.getProtectionsmetody można uzyskać szereg zabezpieczeń na danym arkuszu i zapętlić je, tworząc ich analogi na arkuszu docelowym. Jest to nieco denerwujące, ponieważ wydaje się, że nie ma metody, aby po prostu sklonować ochronę do innego zakresu. (Można zmienić zakres ochrony, ale spowoduje to przeniesienie go do nowego zakresu zamiast kopiowania).

Tak więc w funkcji poniżej wykonuję następujące czynności:

  1. Uzyskaj notację A1 dla każdego chronionego zakresu za pomocą p.getRange().getA1Notation();
  2. Chroń odpowiedni zakres arkusza docelowego za pomocą p2 = sheet2.getRange(rangeNotation).protect();
  3. Ustaw właściwości nowej ochrony p2zgodnie z właściwościami oryginalnej ochrony 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 
   }
  }
} 

Możliwe jest również posiadanie chronionych zakresów w chronionym arkuszu, w takim przypadku należy połączyć dwie funkcje (wykonaj wszystko, co każda z nich robi, z wyjątkiem tego, że arkusz zostanie skopiowany tylko raz).


źródło
Wstawiłem twoją sugestię do mojej pętli i przetestowałem w Scenariuszu 1, otrzymałem komunikat o błędzie TypeError: Cannot call method "protect" of null. Otrzymuję ten błąd, ponieważ z tej linii var p2 = sheet.protect();.
Arvind,
1
To była linia sheet2.protect();? Oznacza to, że arkusz2 ma wartość zerową, więc powinieneś spojrzeć na linię, w której jest zdefiniowany.
W moim kodzie arkusz 2 jest nazywany arkuszem . Jest zdefiniowany jakovar sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind,
Tak czy siak. Debugowanie kodu to praca, a nie moja.