Apps Script : Script nouvelle feuille automatique

Bonjour,

J’ai un classeur Google sheets dans lequel j’ai sur une feuille principale (liée à un Google Forms) intitulée « Base adhérents » (c’est un exemple).
Je souhaiterais, à chaque nouvelle ligne importée dans cette feuille, créer une nouvelle feuille.

Cette nouvelle feuille devra :

  • Dupliquer tout le contenu d’une autre feuille du classeur, déjà existante (nommée « Modèle ») ;

  • Dupliquer la nouvelle ligne créée de la feuille « Base adhérents », dans la ligne 2 de cette nouvelle feuille ;

  • Porter un nom (dans son onglet) en fonction de deux cellules de cette nouvelle ligne. Si par exemple ces cellules se trouvent en colonnes F et T de la nouvelle ligne, ma nouvelle feuille devra s’appeler « Association [contenu cellule F…] version [contenu cellule T…] » ;

Il m’est impossible de le faire à la main compte-tenu du nombre de données à traiter.

J’espère avoir été clair dans ma recherche et vous remercie par avance !

Hello,

S’agit il d’un besoin perso ou professionnel ?
Sais-tu scripter ou manipuler les scripts ?
Quel est le degré d’urgence ?
Besoin que tu partages ici un exemple fictif, voire que tu fasses une vidéo loom explicative.
A réception, je branche l’équipe de champions de Numericoach !

Hello Petziboy,

Je pense avoir la réponse à ta question, à savoir un script qui :

  • s’exécute à la réception d’un formulaire associé à ton classeur Google Sheets ;
  • qui crée une nouvelle feuille en partant d’un modèle ;
  • qui récupère les valeurs insérées par l’utilisateur dans le formulaire pour les insérer dans la ligne 2 de cette nouvelle feuille ;
  • qui nomme cette feuille nouvellement créée en : Association __${nomAsso} version ${versionAsso}.

Voici le script qui te permet de réaliser cela :

const creerNouvelleFeuille = (e) => {
  const COL_ASSO = "B";
  const COL_VERSION = "C";
  const valeurs = e.values;
  const sheet = SpreadsheetApp.getActive();
  const modele = sheet.getSheetByName("Modèle");
 
  const titre = {
    nomAsso: valeurs[COL_ASSO.toLowerCase().charCodeAt(0) - 97],
    versionAsso: valeurs[COL_VERSION.toLowerCase().charCodeAt(0) - 97],
  };
  const nouvelleFeuille = sheet.insertSheet(
    `Association ${titre.nomAsso} version ${titre.versionAsso}`,
    { template: modele }
  );
  nouvelleFeuille.getRange(2, 1, 1, valeurs.length).setValues([valeurs]);
};

Attention, tu dois modifier plusieurs éléments. Dans la ligne 2 et la ligne 3 tu as les variables suivantes :

const COL_ASSO = "B";
const COL_VERSION = "C";

Tu devras remplacer « B » par la lettre représentant la colonne où se trouve le nom de l’asso que tu souhaites insérer dans ton nom de feuille **Association **${nomAsso}.
Puis, tu devras remplacer **« C » **par la lettre représentant la colonne où se trouve la version que tu souhaites insérer dans ton nom de feuille **version **${versionAsso}.
(Dans ton message, tu as donné comme exemple les colonnes T et F, si tu vois ce que je veux dire ! :wink:)

Aussi, il faut que tu mettes en place un déclencheur automatique pour que cette fonction s’exécute lorsque quelqu’un répond à ton formulaire.

Pour se faire, tu vas dans l’interface Google Apps Script, tu cliques sur **Déclencheur **:

Ensuite, tu pourras créer un nouveau déclencheur qui s’exécute lors de l’envoi d’un formulaire. À toi de voir à quelle fréquence tu veux configurer tes notifications en cas d’échec. Voici la manip en image :

En principe à partir de là, tout sera fonctionnel. N’hésite pas à tester et reviens vers nous si tu as des questions ou si ça ne convient pas tout à fait.

En espérant que ma réponse soit à hauteur de tes attentes !

A+++

Merci !
Je n’y connais rien en script mais j’apprends…
J’essaye ça dans la semaine et j’essaye de vous répondre avant ce week-end.
Encore merci à vous deux d’avoir pris le temps de me répondre !

SUPER GÉNIAL NC-Ahmet !!! Merci mille fois !
Ça marche nickel !!!

Seul problème : au bout d’une douzaine de feuilles, le déclencheur ne peut plus générer d’autres feuilles et se met en erreur (alors que je devrais avoir une cinquantaine de feuilles) :
« Exception: Si vous effectuez cette action, vous dépasserez le nombre maximum de 10000000 cellules autorisé dans le classeur. -at creerNouvelleFeuille(Code:12:33) »

Je ne sais pas comment contourner ce problème.
Une idée ?..

Hello,

Il semblerait que tu as beaucoup trop de cellules dans ton classeur…

Regarde voir dans ta feuille « Modèle » le nombre de lignes/colonnes que tu possèdes.

Supprime celles qui sont inutiles. Pareil dans tes autres feuilles.

Ça ne sert à rien d’avoir 10000 lignes ou colonnes si tu en utilises que 10.

Bon weekend !
A+

En effet, ça va mieux après un brin de ménage ! :yum:

Une dernière question : ma feuille modèle est protégée en écriture (sauf certaines cellules qui serviront à la saisie). Y a-t-il un moyen pour que les feuilles dupliquées automatiquement soient pareillement protégées ?
Merci encore !
Bonne soirée.

Coucou Petziboy :sunglasses:

J’éspère que tu vas bien.

Pour répondre à ta question, il est possible de gérer, ajouter ou supprimer des protections en Google Apps Script via la classe Protection.

Je t’invite à consulter la documentation officielle présente juste ici

Dans ton cas, il sera donc nécessaire à chaque création de feuille de récupérer cette feuille dans une variable puis d’y attribuer la protection de ton choix.

Voici un exemple :

var ss = SpreadsheetApp.getActive();
ss.insertSheet().setName(« hello »);
var newSheet = ss.getSheetByName(« hello »);
var range = ss.getRange(« A:A »);
newSheet.protect().setUnprotectedRanges([range]);

Ici, je créé une feuille « hello » que je protège ensuite entièrement à l’exception de la colonne A.

Les méthodes à regarder sont protect() et setUnprotectedRanges().

En espérant que ça règle ton soucis ! N’hésite pas à revenir vers nous si besoin.

Si tu manques trop de temps ou de connaissances, n’hésite pas à prendre un rdv juste ici : nous proposons des formations et développements sur mesure :grin:

Bonne soirée,

Christopher

Merci Christopher,

En effet, je suis une bille donc je n’y comprends pas grand chose.
Le script proposé plus haut par NC-Hamet fonctionne parfaitement mais j’aimerais que lors de chaque création automatique d’une nouvelle feuille dans Google Sheets (à chaque formulaire rempli dans le Google Forms lié), cette nouvelle feuille, basée sur ma feuille « Modèle », puisse être automatiquement protégée de la même façon que ma feuille « Modèle ». Que dois-je ajouter à son script ?

Je fais ce boulot pour mon association, je n’ai pas trop le temps de me former, hélas !

Merci beaucoup !

Fred


\

Coucou Petziboy,

Navré pour le délai de réponse et merci Christopher pour ta contribution !

Je reprends ton script, voici :

const creerNouvelleFeuille = (e) => {
  const COL_ASSO = "B";
  const COL_VERSION = "C";
  const valeurs = e.values;
  const sheet = SpreadsheetApp.getActive();
  const modele = sheet.getSheetByName("Modèle");
  const protection = modele.getProtections(
    SpreadsheetApp.ProtectionType.SHEET
  )[0];
  const titre = {
    nomAsso: valeurs[COL_ASSO.toLowerCase().charCodeAt(0) - 97],
    versionAsso: valeurs[COL_VERSION.toLowerCase().charCodeAt(0) - 97],
  };
  const nouvelleFeuille = sheet.insertSheet(
    `Association ${titre.nomAsso} version ${titre.versionAsso}`,
    { template: modele }
  );
  const nouvelleProtection = nouvelleFeuille.protect();
  nouvelleFeuille.getRange(2, 1, 1, valeurs.length).setValues([valeurs]);
  dupliquerProtection(protection, nouvelleProtection, nouvelleFeuille);
};

const dupliquerProtection = (p, p2, s) => {
  const nouvellesPlages = [];
  p2.setDescription(p.getDescription()).setWarningOnly(p.isWarningOnly());
  if (!p.isWarningOnly()) { p2.removeEditors(p2.getEditors()).addEditors(p.getEditors()) };
  for (plage of p.getUnprotectedRanges()) { nouvellesPlages.push(s.getRange(plage.getA1Notation())) };
  p2.setUnprotectedRanges(nouvellesPlages);
};

Attention encore une fois pense bien à mettre à jour les deux lignes const COL_ASSO = « B » ainsi que**_ const COL_VERSION = « C » _**avec les colonnes qui vont bien.

Le script a pas mal changé donc fait bien un copier/coller intégral.

A+

Hello !
Avec un peu de retard, merci 1000 fois, NC-Ahmet, c’est génial, ça marche nickel !
Tu ne peux pas savoir comme ça me facilite la vie, sachant que je dois gérer une centaine d’associations qui comptent chacune entre 2 et 50 membres et qui renseignent pour chacun de ces membres un dizaine d’infos dans un Google Form, lié à mon Google Sheet !

Autant dire que l’immense tableau de restitution créé dans Google Sheets (sur environ 450 colonnes) ne me convenait pas et que tes scripts (magiques pour moi) m’ont permis de créer autant de tableaux de restitution que d’associations (à partir de ma matrice remplie de formules).

Dernier point sur lequel je bute, justement en voulant créer un grand tableau synthétique à partir de celui généré automatiquement, mais cette fois ce n’est pas un problème de script mais simplement de formules que je ne trouve pas, pour transformer le 1er tableau en 2ème comme dans l’exemple très simplifié ci-dessous :

Sachant que chaque asso n’a pas le même nombre d’adhérents (par exemple ici, l’asso B n’en a que 2, donc il faudra directement créer la ligne suivante pour l’asso C plutôt que de laisser un champ vide dans mon 2ème tableau).

(L’idéal serait aussi qu’un tri automatique se fasse au fur et à mesure de la remontée des résultats du questionnaire mais bon, ça c’est la cerise sur le gâteau, pas obligatoire…)

Je ne veux pas abuser mais… si tu as une idée… Merci d’avance !

J’ai l’impression que mon image n’est pas passée dans mon précédent message. Là voici :

https://lens.google.com/search?ep=gisbubb&hl=fr&re=df&p=ATHekxcQ9jEqj0gk4cTF0dmST-yVQHvr32tnI3v9ShjN4atX_6py7WMBMdxUmPIKixo09mpmq_YB7m6QYbOJR5tz6cF_Fyp_JnObgwLgP0181fa5y7_dfBiblh1r48g_RHJ9PiqS07c3_96lmyEf4J_wymjrx91aI-Zdvxl6dOWJaITI9Ba1BivordZR5E4HcefKZAXTUmieyf1RKeLadSY1bkVrdcxDJvFdaUBfRSb720y7NWu33LszJJyEf6z2tRjeZoZZt83X27xmKQC7a-ZdOO0TOUryMcIY-WS5wQgKnCVSFhwSLoVYGxadB404#lns=W251bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGwsIkVrY0tKR1U0WVdVd05qRTVMVGd6WldFdE5EUmlPUzFpWVdJeUxURXdOamM1T1RZeU1EaGlZaElmWnpZM05ESk5UV1pOVTJkU1VVUjFWV2RKVkUxaWJEUjNVbXMzWm1oQ1p3PT0iXQ==

Bon, décidément, je suis une bille, je ne parviens pas à insérer une image pour illustrer mes questions (elle se transforme systématiquement en une suite de nombres dès que je l’envoie) :frowning: