web-dev-qa-db-fra.com

Dans Google Sheets, comment dupliquer une feuille avec son autorisation?

Dans une feuille de calcul Google appelée présence, il existe une feuille appelée modèle. L'utilisateur duplique cette feuille, la renomme avec la date du jour et l'utilise pour indiquer la présence des étudiants. La feuille de modèle contient des cellules protégées et l'assistance est marquée en entrant le numéro d'identification de l'étudiant dans l'espace prévu à cet effet (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 de Modèle, mais les copies en double ne conservent pas les autorisations Cell/Range. Existe-t-il un moyen d’ajouter une fonction de boucle qui extrait l’autorisation de Template et l’applique à chaque fois que la boucle template.copyTo crée une feuille?

9
Arvind

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, obtient sa protection de type feuille, puis protège la nouvelle feuille de la même manière: même description, même type. Si la protection n'est pas simplement un avertissement, supprimez tous les éditeurs et ajoutez ceux autorisés pour la feuille d'origine. Enfin, passez en boucle sur les plages non protégées, remappez chacune d’elles (via getA1Notation) sur 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 plages protégées

En utilisant la méthode sheet.getProtections, vous pouvez obtenir le tableau de protections sur une feuille donnée et les parcourir en boucle, créant ainsi leurs analogues sur la feuille cible. C'est un peu gênant car il ne semble pas y avoir de méthode pour cloner simplement une protection dans une autre plage. (On peut modifier l'étendue de la protection, mais cela la déplacerait dans la nouvelle étendue 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 p2 en fonction 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. Dans ce 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.)

7
user79865