Transférer un onglet dans un nouveau fichier avec les protections

Bonjour,

A partir d'une liste de noms dans une feuille, j'arrive à créer autant d'onglets que la liste contient de noms (les noms des onglets correspondent aux noms de la liste) : j'ai réussi à faire cette copie en conservant les protections de cellule de ma feuille modèle.

Maintenant, j'ai besoin, à partir de tous ces onglets, les transférer en tant que fichier indépendant en conservant les protections des cellules : j'arrive à le faire mais la protection des cellules n'est pas copiée.

Pour être plus parlant sur mes fichiers :
initialement : mon dossier contient un seul fichier avec 2 onglets (un "modèle" et une "liste" qui contient les noms qui m'intéressent, Nom1 Nom2 Nom3 ...)
1ère étape : je crée des copies de l'onglet modèle que je renomme Nom1 puis Nom2 ... Je dispose donc d'un seul fichier avec les onglets "modele", "liste", "Nom1", "Nom2", "Nom3", ...
2ème étape : je duplique l'onglet Nom1 pour créer un nouveau fichier - > je dois conserver les données et les protections.
A l'issue de cette étape, j'ai donc le fichier initial identique à celui de la fin de la 1ère étape puis autant de fichiers que de noms (fichier Nom1, fichier Nom2, ...)

https://docs.google.com/spreadsheets/d/1vwV9Tf3BKcETRUyFWhqrRtcM056SrfqEEHLUb1k4vKw/edit?usp=sharing

Mon script fonctionne, j'obtiens bien des fichiers indépendants mais la protection des cellules ne fonctionne pas.

Merci d'avance pour l'aide

const wbk = SpreadsheetApp.getActiveSpreadsheet();
const shModele = wbk.getSheetByName('Modele');
const shListe = wbk.getSheetByName('Liste');
const FOLDER_ID = ""; //noter ici l'ID du dossier qui va contenir les fichiers (apparait après /d/ ds l'URL)

//---MENU SPÉCIAL DANS LA BARRE D'OUTILS - Les petites photos sont des emoji-----
function spcMenu() {

  let subMenu1 = SpreadsheetApp.getUi().createMenu("❌Suppression des anciennes données")
    .addItem("🙅 Effacer les anciens onglets club","effaceOnglet")
    .addSeparator();

  let subMenu2 = SpreadsheetApp.getUi().createMenu("🗝️ Création")
    .addItem("🟩 Création des onglets","creationOnglet")
    .addSeparator()
    .addSeparator()
    .addItem("🟦 creation des fichiers - 1","creation1")
    .addSeparator();

  SpreadsheetApp.getUi().createMenu("📌 Nouveau menu")//---orange image is emoji character
    .addSubMenu(subMenu1)
    .addSeparator()
    .addSubMenu(subMenu2)
    .addSeparator()
    .addToUi();  
}

//---à l'ouverture du menu spécial --- exécute la ou les fonctions de cette portée de fonction au démarrage
function onOpen(){
  spcMenu();
}

//---FONCTION POUR CREER UN ONGLET PAR NOM (supprimé par la suite)
function creationOnglet() {
  let shLastRow = shListe.getLastRow();
  let liste = shListe.getRange(3, 1, shLastRow -1, 1).getValues(); //la liste débute en A3
  //console.log(liste);  
  let valeur = liste.filter(String).length+1; 
  //console.log(valeur);  

  let nouveaunom;
  for (let i=1;i<valeur;i++){
    if (shModele !== null) {
      shModele.activate();// make this sheet active
      wbk.duplicateActiveSheet();
  }
    let nom = shListe.getRange(i+2,1);
    nouveaunom = nom.getValue();
    //console.log(nom.getValue());

    let feuilleRenommer = wbk.getSheetByName('Copie de Modele');
    let feuilleINitiale = wbk.getSheetByName('Modele')

    feuilleRenommer.setName(nouveaunom);
    //Logger.log(shModele.getName());
    feuilleRenommer.getRange('L1').setValue(nouveaunom);
    transfererProtections(feuilleINitiale,feuilleRenommer)

  }
}

//---FONCTION POUR DUPLIQUER LA PROTECTION DE LA FEUILLE LORS DE LA COPIE - 

function transfererProtections(sh1,sh2){
    // cas d'une protection de plages
    sh1.getProtections(SpreadsheetApp.ProtectionType.RANGE).forEach(p1 => {
      var p2 = sh2.getRange(p1.getRange().getA1Notation()).protect();
      p2.setDescription(p1.getDescription());
      p2.setWarningOnly(p1.isWarningOnly());
      if (!p1.isWarningOnly()) {
        p2.removeEditors(p2.getEditors());
        p2.addEditors(p1.getEditors());
      }
    })
}

//---FONCTION POUR CREER UN FICHIER  INDEPENDANT AU LIEU DES ONGLETS - 
function creation1(){
let shLastRow = shListe.getLastRow();
let liste = shListe.getRange(3, 1, shLastRow -1, 1).getValues(); //la liste des clubs débute en A3
//console.log(liste);  
let valeur = liste.filter(String).length+1; 
//console.log(valeur); 

 let sheets = wbk.getSheets();

 let folder = DriveApp.getFolderById(FOLDER_ID);
 for (var i = 2; i<valeur+1 ; i++ ) {
  let sheet = sheets[i];
  let name =  sheet.getName()
  fichierInitial = wbk.getSheetByName(name)

  if (!folder.getFilesByName(name).hasNext()) {
   let newSpreadSheet = SpreadsheetApp.create(name);
   sheet.copyTo(newSpreadSheet).setName(name);
   sheet.copyTo(newSpreadSheet).setName("Feuille 2");
   defaultSheet = newSpreadSheet.getSheetByName("Feuille 1");
   transfererProtections(fichierInitial,defaultSheet)

   newSpreadSheet.deleteSheet(defaultSheet);
   defaultSheet = newSpreadSheet.getSheetByName(name);
   newSpreadSheet.deleteSheet(defaultSheet);
   let newFile = DriveApp.getFileById(newSpreadSheet.getId());
   newFile.moveTo(DriveApp.getFolderById(folder.getId()))
  }
 }
}

Bonjour,

Dans Google Sheet il y a 2 types de protections, les plages et les feuilles :

SpreadsheetApp.ProtectionType.RANGE // pour les ranges
SpreadsheetApp.ProtectionType.SHEET // pour les feuilles

Voici un script à tester, j'ai essayé de conserver ton nommage :

function transfererProtections(sh1, sh2) {
  var rangeProtec = sh1.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  var sheetProtec = sh1.getProtections(SpreadsheetApp.ProtectionType.SHEET);

  rangeProtec.forEach(p1 => {
    var range = p1.getRange().getA1Notation();
    var p2 = sh2.getRange(range).protect();
    p2.setDescription(p1.getDescription());
    p2.setWarningOnly(p1.isWarningOnly());
    if (!p1.isWarningOnly()) {
      p2.removeEditors(p2.getEditors());
      p2.addEditors(p1.getEditors());
    }
  });

  sheetProtec.forEach(p1 => {
    var p2 = sh2.protect();
    p2.setDescription(p1.getDescription());
    p2.setWarningOnly(p1.isWarningOnly());
    if (!p1.isWarningOnly()) {
      p2.removeEditors(p2.getEditors());
      p2.addEditors(p1.getEditors());
    }
  });
}

Bonjour,

Merci pour ton retour.

J'ai testé mais les protections ne sont pas conservées.

Re, j'ai été sur ton fichier, l’onglet "Modele" il y a une plage protégée : A5:F20 en lecture seule.

J'ai crée une copie de cet onglet : "Copie de Modele" il n'a aucune plage protégée

J'ai passé les 2 feuilles à la fonction de transfert :

function testProtect () {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s1 = ss.getSheetByName('Modele');
  var s2 = ss.getSheetByName('Copie de Modele');
  transfererProtections(s1,s2)
}

La protection s'est bien appliquée sur Copie de Modele (partiellement toutefois, car je ne suis pas propriétaire et ne peut me retirer des droits)

Quand je crée une copie de l'onglet, effectivement j'arrive bien à copier les protections.

Mon problème vient de la 2ème étape que je décris : je dois créer un fichier indépendant à partir des onglets Nom1, Nom2... C'est à cette étape que la protection ne se fait pas ! le nouveau fichier (par exemple Nom1) ne contient pas de plages protégées.

J'ai testé de mon coté sur un autre fichier sheets :

function test (){
  var ss1 = SpreadsheetApp.getActiveSpreadsheet();
  var ss2 = SpreadsheetApp.openById('1qi2B4EoZctA2RE7BPeFNoiIVqY1h2X2q5545qGmoMvDg')
  var s1 = ss1.getSheetByName('Feuille 1');
  var s2 = ss2.getSheetByName('Feuille 1');
  transfererProtections(s1, s2)
}

function transfererProtections(sh1, sh2) {
  var rangeProtec = sh1.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  var sheetProtec = sh1.getProtections(SpreadsheetApp.ProtectionType.SHEET);

  rangeProtec.forEach(p1 => {
    var range = p1.getRange().getA1Notation();
    var p2 = sh2.getRange(range).protect();
    p2.setDescription(p1.getDescription());
    p2.setWarningOnly(p1.isWarningOnly());
    if (!p1.isWarningOnly()) {
      p2.removeEditors(p2.getEditors());
      p2.addEditors(p1.getEditors());
    }
  });

  sheetProtec.forEach(p1 => {
    var p2 = sh2.protect();
    p2.setDescription(p1.getDescription());
    p2.setWarningOnly(p1.isWarningOnly());
    if (!p1.isWarningOnly()) {
      p2.removeEditors(p2.getEditors());
      p2.addEditors(p1.getEditors());
    }
  });
}

Les protections sont bien copiées dans le 2nd fichier.

J'ai trouvé mon erreur : c'est dans l'appel de la fonction transfererProtection que j'avais fait une erreur

je l'appliquais du fichier initial (ça c'était bon) vers une mauvaise feuille (la 'feuille 1' au lieu de la feuille 'name').

Rechercher des sujets similaires à "transferer onglet nouveau fichier protections"