Dans Google Sheets, comment dupliquer une feuille avec son autorisation


10

Dans une feuille de calcul Google appelée Présence, il y a une feuille appelée Modèle . L'utilisateur duplique cette feuille, renomme la feuille avec la date actuelle et utilise cette feuille pour marquer la présence des étudiants. La feuille de modèle contient des cellules protégées et la présence est marquée en entrant le numéro d'identification de l'élève dans l'espace donné (cellules non protégées). J'utilise le script suivant pour dupliquer plusieurs feuilles et les renommer tous les jours:

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

Ce script m'aide à créer plusieurs copies de feuilles à partir du modèle, mais les copies en double ne conservent pas les autorisations Cellule / Plage. Existe-t-il un moyen d'ajouter une fonction de boucle qui extrait l'autorisation du modèle et l'applique chaque fois que la boucle template.copyTocrée une feuille?


Veuillez consulter mon article connexe ici ... stackoverflow.com/questions/40512801/…
phinland

Réponses:


9

Scénario 1: le modèle est une feuille protégée avec des plages non protégées

Dans le script ci-dessous, je duplique la feuille, j'obtiens sa protection de type Feuille, puis je protège la nouvelle feuille de la même manière: même description, même type. Si la protection n'est pas seulement un avertissement, supprimez tous les éditeurs et ajoutez ceux autorisés pour la feuille d'origine. Enfin, parcourez les plages non protégées, remappez chacune d'entre elles (via getA1Notation) à la nouvelle feuille et déprotégez-les.

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

Scénario 2: le modèle est une feuille avec des plages protégées

En utilisant la sheet.getProtectionsméthode, vous pouvez obtenir le tableau de protections sur une feuille donnée, et les boucler, créant leurs analogues sur la feuille cible. C'est quelque peu ennuyeux car il ne semble pas y avoir de méthode pour cloner simplement une protection vers une autre plage. (On peut changer la plage de protection, mais cela la déplacerait vers la nouvelle plage, au lieu de la copier.)

Donc, dans la fonction ci-dessous, je fais ce qui suit:

  1. Obtenez la notation A1 de chaque plage protégée avec p.getRange().getA1Notation();
  2. Protégez la plage correspondante de la feuille cible avec p2 = sheet2.getRange(rangeNotation).protect();
  3. Définissez les propriétés de la nouvelle protection en p2fonction des propriétés de la protection d'origine 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 
   }
  }
} 

Il est également possible d'avoir des plages protégées dans une feuille protégée, auquel cas vous devrez combiner les deux fonctions (faites tout ce que chacune d'entre elles fait, sauf bien sûr que vous ne dupliquerez la feuille qu'une seule fois.)


J'ai inséré votre suggestion dans ma boucle et testé dans le scénario 1, j'ai reçu un message d'erreur TypeError: Cannot call method "protect" of null. Je reçois cette erreur car à partir de cette ligne var p2 = sheet.protect();.
Arvind

1
Alors, c'était la ligne sheet2.protect();? Ensuite, cela signifie que sheet2 est nul, vous devez donc regarder la ligne où il est défini.

Dans mon code, sheet2 est appelé feuille . Il est défini commevar sheet = ss.getSheetByName(AttendanceObjects[i]);
Arvind

En tous cas. Déboguer votre code est votre travail, pas le mien.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.