Sortie de macro Apps script
Bonjour à tous,
Merci pour l'existence de ce forum.
Je n'ai pas trouvé de solution avec google ou le cours Apps script ici. Je voudrais l'équivalent d'un exit sub en Vba ou de goto fin.
return permet de mettre fin à une fonction mais continue la macro.
break; me retourne une erreur de syntaxe. break in aussi et semble être l'équivalent de exit for.
var nom = feuilQuest.getRange(3,2).getValue();
//controles de saisie
// nom
if (nom=="")
{
Browser.msgBox("Veuillez saisir votre pseudo.");
return;
break;
}Merci pour votre aide.
Bonjour,
L'instruction return met fin à une fonction (break c'est pour les boucles).
Par exemple :
function test() {
const nom = '';
if (nom == '') {
Browser.msgBox('Veuillez saisir votre pseudo.');
return;
}
Browser.msgBox('Non affiché car la fonction a été quittée.');
}Si dans ton cas tu as une fonction appelée par une fonction et que tu veux quitter le tout, il faut que ton return soit dans la fonction principale, par exemple :
function test() {
const nom = '';
const estVide = verifierSiNomVide(nom);
if (estVide) {
return;
}
Browser.msgBox('Non affiché car la fonction a été quittée.');
}
function verifierSiNomVide(nom) {
const estVide = nom == '';
if (estVide) {
Browser.msgBox('Veuillez saisir votre pseudo.');
}
return estVide;
}Bonjour,
Merci pour votre réponse.
Je n'ai pas de changement avec vos indications qu'il me semble suivi dans le code :
function verifierSiNomVide(nom)
{
const estVide = nom == '';
if (estVide)
{
Browser.msgBox('Veuillez saisir votre pseudo.');
}
return estVide;
}
// 3 questions formulaire d'onglet questions à onglet admin
function NouvQuestion(){
// definition var
var fichSondage = SpreadsheetApp.getActive();
var feuilQuest = fichSondage.getSheetByName("questions");
// feuille validation question par l'administrateur
var feuilAdmin = fichSondage.getSheetByName("admin");
// parametrage questions
const nom = feuilQuest.getRange(3,2).getValue();
const estVide = verifierSiNomVide(nom);
if (estVide)
{
return;
}
var quest1 = feuilQuest.getRange(6,2).getValue();
var quest2 = feuilQuest.getRange(9,2).getValue();
var quest3 = feuilQuest.getRange(12,2).getValue();
var repons1 = feuilQuest.getRange(6,4).getValue();
var repons2 = feuilQuest.getRange(9,4).getValue();
var repons3 = feuilQuest.getRange(12,4).getValue();
// controle saisie pour les questions
if (quest1 =="")
{
Browser.msgBox("Veuillez saisir au moins la 1ere question.");
return;
}
// controle saisie pour les réponses
if (repons1 =="" && quest1 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la première question.");
return;
}
if (repons2 =="" && quest2 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la 2ème question.");
return;
}
if (repons3 =="" && quest3 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la 3ème question.");
return;
}
//annonce
//SpreadsheetApp.getUi().alert('Vos réponses ont été enregistré. Une fois validées, elles apparaîtront dans les questions à répondre.');
Browser.msgBox('Vos réponses ont été enregistrées. Une fois validées, elles apparaîtront dans les questions à répondre.');Apparition des messages dans l'ordre :
Désolé
Apparition des messages dans l'ordre :
En regardant rapidement ton code et l'ordre des messages, celui-ci n'est pas logique ... sauf si ta fonction est exécutée plusieurs fois, et dans ce cas, une fois c'est allé jusqu'au bout et la seconde fois ça s'est arrêté au return.
Ajoute par exemple :
console.log(nom);Après cette ligne :
const nom = feuilQuest.getRange(3,2).getValue();Pour voir quel est le nom en cours et combien de fois est exécutée ta fonction.
(note qu'il n'y a pas d'intérêt à utiliser verifierSiNomVide dans ton cas, le premier exemple est bien plus simple)
function NouvQuestion(){
// definition var
var fichSondage = SpreadsheetApp.getActive();
var feuilQuest = fichSondage.getSheetByName("questions");
// feuille validation question par l'administrateur
var feuilAdmin = fichSondage.getSheetByName("admin");
// parametrage questions
const nom = feuilQuest.getRange(3,2).getValue();
console.log(nom);
En faisant éxécuter, çà tourne dans le vide.
Bonjour,
De ce que je comprends, tu as des champs à remplir, nom + 3 question et 3 réponses.
Tu veux tester si les champs sont complétés, et s'ils le sont, enregistrer les données, s'ils ne le sont pas, afficher un message d'erreur à l’utilisateur, voici un script permettant cela :
function nouvQuestion() {
// déclaration des constantes
const fichSondage = SpreadsheetApp.getActive();
const feuilQuest = fichSondage.getSheetByName("questions");
const feuilAdmin = fichSondage.getSheetByName("admin"); // feuille validation question par l'administrateur
var data = { // map des données
'nom': 'B3',
'question 1': 'B6',
'question 2': 'B9',
'question 3': 'B12',
'réponse 1': 'D6',
'réponse 2': 'D9',
'réponse 3': 'D12'
};
for (let key in data) { // Boucle pour remplacer les adresses des cellules par leurs valeurs
let cellAddress = data[key]; // obtient l'adresse de la cellule (ex: 'B3')
let cellValue = feuilQuest.getRange(cellAddress).getValue(); // obtient la valeur dans la cellule
data[key] = cellValue; // remplace l'adresse par la valeur
if (cellValue === "") { // Vérifie si une cellule est vide
SpreadsheetApp.getUi().alert("Il manque une information, veuillez remplir le champ : " + key); // message d'erreur
return;
}
}
// function enregistreQuest(data); > fonction pour enregistrer les données ?
SpreadsheetApp.getUi().alert('Vos réponses ont été enregistrées. Une fois validées, elles apparaîtront dans les questions à répondre.'); // Si toutes les données sont présentes, affiche un message de confirmation
}@Sebastien
Ok, si je ferme les boites de dialogue des 2 messages, le journal affiche le pseudo saisit.
Cà valide ton hypothèse que la fonction est éxécutée 2 fois, alors qu'on devrait sortir au doublon du pseudo. (ou s'il n'est pas saisit)
dans ce cas, une fois c'est allé jusqu'au bout et la seconde fois ça s'est arrêté au return.
@PierreLepinay
Tu as bien compris qu'il y avait 3 questions à remplir, mais une suffirait.
Tu veux tester si les champs sont complétés, et s'ils le sont, enregistrer les données, s'ils ne le sont pas, afficher un message d'erreur à l’utilisateur..
Non je veux ajouter de une à 3 questions si le pseudo n'existe pas dans la feuille de destination(Admin). Et le code d'enregistrement fonctionne.
Page questions (C'est plutôt mesures) :
Page admin, pour valider la question :
Voilà le code en entier.
// questions formulaire d'onglet questions à onglet admin et onglet historiq
function NouvQuestion(){
// definition var
var fichSondage = SpreadsheetApp.getActive();
var feuilQuest = fichSondage.getSheetByName("questions");
// feuille validation question par l'administrateur
var feuilAdmin = fichSondage.getSheetByName("admin");
// parametrage questions
const nom = feuilQuest.getRange(3,2).getValue();
console.log(nom);
// nom
if (nom =="")
{
Browser.msgBox("Veuillez saisir votre pseudo.");
return;
}
var quest1 = feuilQuest.getRange(6,2).getValue();
var quest2 = feuilQuest.getRange(9,2).getValue();
var quest3 = feuilQuest.getRange(12,2).getValue();
var repons1 = feuilQuest.getRange(6,4).getValue();
var repons2 = feuilQuest.getRange(9,4).getValue();
var repons3 = feuilQuest.getRange(12,4).getValue();
// controle saisie pour les questions
if (quest1 =="")
{
Browser.msgBox("Veuillez saisir au moins la 1ere question.");
return;
}
// controle saisie pour les réponses
if (repons1 =="" && quest1 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la première question.");
return;
}
if (repons2 =="" && quest2 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la 2ème question.");
return;
}
if (repons3 =="" && quest3 !== "")
{
Browser.msgBox("Veuillez sélectionner votre réponse à la 3ème question.");
return;
}
// dernieres lignes
var dernQuest = feuilAdmin.getLastRow();
var nouvQuest = feuilAdmin.getLastRow() + 1;
//verif nom existant dans admin
for (i=2;i <= dernQuest;i++)
{
if (feuilAdmin.getRange(i,2).getValue() == nom)
{
Browser.msgBox("Vous ne pouvez pas faire l'opération plusieurs fois.");
return;
}
}
// Destinations feuille admin et historique
// numero
var numero = dernQuest - 1;
// nom google a voir
// 1ere question obligatoire en feuille admin
feuilAdmin.getRange(nouvQuest,1).setValue(numero); // numero
feuilAdmin.getRange(nouvQuest,2).setValue(nom); // nom
feuilAdmin.getRange(nouvQuest,3).setValue(quest1); // question 1
feuilAdmin.getRange(nouvQuest,3).setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // retour ligne longue
feuilAdmin.getRange(nouvQuest,4).setValue(repons1); // reponse 1
feuilAdmin.getRange(nouvQuest,5).setValue("=TODAY()"); // formule
feuilAdmin.getRange(nouvQuest,6).setValue("=HOUR(NOW())"); // formule
feuilAdmin.getRange(nouvQuest,5).setValue(feuilAdmin.getRange(nouvQuest,5).getValue()); // date en dur
feuilAdmin.getRange(nouvQuest,6).setValue(feuilAdmin.getRange(nouvQuest,6).getValue()); // heure en dur
feuilAdmin.getRange(nouvQuest,7).setDataValidation(SpreadsheetApp.newDataValidation() // LD
.setAllowInvalid(false)
.requireValueInList(['Validé', 'Refusé'], true)
.build());
if (quest2 !== "")
{
var nouvQuest = feuilAdmin.getLastRow() + 1;
feuilAdmin.getRange(nouvQuest,1).setValue(numero + 1); // numero
feuilAdmin.getRange(nouvQuest,2).setValue(nom); // nom
feuilAdmin.getRange(nouvQuest,3).setValue(quest2); // question 2
feuilAdmin.getRange(nouvQuest,3).setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // retour ligne longue
feuilAdmin.getRange(nouvQuest,4).setValue(repons2); // reponse 2
feuilAdmin.getRange(nouvQuest,5).setValue("=TODAY()"); // formule
feuilAdmin.getRange(nouvQuest,6).setValue("=HOUR(NOW())"); // formule
feuilAdmin.getRange(nouvQuest,5).setValue(feuilAdmin.getRange(nouvQuest,5).getValue()); // date en dur
feuilAdmin.getRange(nouvQuest,6).setValue(feuilAdmin.getRange(nouvQuest,6).getValue()); // heure en dur
feuilAdmin.getRange(nouvQuest,7).setDataValidation(SpreadsheetApp.newDataValidation() // LD
.setAllowInvalid(false)
.requireValueInList(['Validé', 'Refusé'], true)
.build());
}
// Si 3eme question
if (quest3 !== "")
{
var nouvQuest = feuilAdmin.getLastRow() + 1;
feuilAdmin.getRange(nouvQuest,1).setValue(numero + 2); // numero
feuilAdmin.getRange(nouvQuest,2).setValue(nom); // nom
feuilAdmin.getRange(nouvQuest,3).setValue(quest3); // question 3
feuilAdmin.getRange(nouvQuest,3).setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // retour ligne longue
feuilAdmin.getRange(nouvQuest,4).setValue(repons3); // reponse 3
feuilAdmin.getRange(nouvQuest,5).setValue("=TODAY()"); // formule
feuilAdmin.getRange(nouvQuest,6).setValue("=HOUR(NOW())"); // formule
feuilAdmin.getRange(nouvQuest,5).setValue(feuilAdmin.getRange(nouvQuest,5).getValue()); // date en dur
feuilAdmin.getRange(nouvQuest,6).setValue(feuilAdmin.getRange(nouvQuest,6).getValue()); // heure en dur
feuilAdmin.getRange(nouvQuest,7).setDataValidation(SpreadsheetApp.newDataValidation() // LD
.setAllowInvalid(false)
.requireValueInList(['Validé', 'Refusé'], true)
.build());
}
}
//annonce
//SpreadsheetApp.getUi().alert('Vos réponses ont été enregistré. Une fois validées, elles apparaîtront dans les questions à répondre.');
Browser.msgBox('Vos réponses ont été enregistrées. Une fois validées, elles apparaîtront dans les questions à répondre.');
Vous avez tout là je crois.
Merci
Ok ok, donc, si je comprends bien, tu as un formulaire avec 7 inputs :
1 nom
3 question + réponses
Quand un user complète, il faut qu'au minimum il y ai son nom + une paire question réponse de rempli.
Ensuite, on test si le nom est déjà dans la base, si oui, message d'erreur et en stop, sinon :
pour chaque paire question + réponse on insère une ligne dans laquelle on insère :
1 : numéro réponse
2 : nom (je le mets en majuscule pour éviter la casse, ex : Machin != machin != MACHIN)
3 : la question (mis à la ligne)
4 : la réponse
5 : la date format dd/MM/yyyy
6 : l'heure format HH
7 : règle de validation
Si j'ai bon, voici le script :
/**
* Déclaration des constantes pour accéder aux feuilles de calcul.
*/
const FICH_SONDAGE = SpreadsheetApp.getActive();
const FEUIL_QUEST = FICH_SONDAGE.getSheetByName("questions");
const FEUIL_ADMIN = FICH_SONDAGE.getSheetByName("admin");
/**
* Fonction principale pour gérer l'ajout de nouvelles questions.
*
* Lit les données de la feuille "questions", vérifie que les données requises sont présentes,
* et appelle la fonction pour enregistrer les questions si toutes les conditions sont remplies.
*/
function nouvQuestion() {
var data = { // Dictionnaire des adresses de cellules pour les données
'nom': 'B3',
'question 1': 'B6',
'question 2': 'B9',
'question 3': 'B12',
'réponse 1': 'D6',
'réponse 2': 'D9',
'réponse 3': 'D12'
};
// Remplace les adresses des cellules par leurs valeurs
for (let key in data) {
let cellAddress = data[key]; // Adresse de la cellule (ex: 'B3')
let cellValue = FICH_SONDAGE.getRange(cellAddress).getValue(); // Valeur dans la cellule
data[key] = cellValue; // Remplace l'adresse par la valeur
}
// Vérifie que le nom est obligatoire
if (data['nom'] === "") {
SpreadsheetApp.getUi().alert("Le champ 'nom' est obligatoire. Veuillez le remplir.");
return;
}
// Vérifie si le nom existe déjà dans la feuille "admin"
const adminData = FEUIL_ADMIN.getRange(1, 2, FEUIL_ADMIN.getLastRow(), 1).getValues();
for (let i = 0; i < adminData.length; i++) {
if (adminData[i][0].toUpperCase() === data['nom'].toUpperCase()) {
SpreadsheetApp.getUi().alert("Vous ne pouvez pas faire l'opération plusieurs fois.");
return;
}
}
// Vérifie qu'au moins un couple question + réponse est renseigné
let pairQuestReponse = false; // Initialement, aucun couple valide trouvé
for (let i = 1; i <= 3; i++) {
let questionKey = 'question ' + i;
let reponseKey = 'réponse ' + i;
// Vérifie si la question et la réponse correspondante ne sont pas vides
if (data[questionKey] !== "" && data[reponseKey] !== "") {
pairQuestReponse = true; // Au moins un couple question + réponse est valide
break; // Sort de la boucle si un couple valide est trouvé
}
}
// Si aucun couple valide n'a été trouvé, affiche un message d'erreur
if (!pairQuestReponse) {
SpreadsheetApp.getUi().alert("Au moins un couple question + réponse doit être complété.");
return;
}
// Si toutes les vérifications sont passées, enregistre les questions
SpreadsheetApp.getUi().alert('Vos réponses ont été enregistrées. Une fois validées, elles apparaîtront dans les questions à répondre.');
enregistreQuest(data);
}
/**
* Fonction pour enregistrer les questions dans la feuille "admin".
*
* - Ajoute une nouvelle ligne pour chaque question valide avec les données fournies.
* - Les informations incluent le numéro de la question, le nom, la question, la réponse, la date, et l'heure.
* - Ajoute également une validation de données pour la colonne de statut.
*
* @param {Object} data - Les données des questions et réponses.
*/
function enregistreQuest(data) {
const dernQuest = FEUIL_ADMIN.getLastRow(); // Obtient la dernière ligne remplie
const numero = dernQuest-1; // Numéro pour la nouvelle question
var now = new Date();
var date = Utilities.formatDate(now, Session.getScriptTimeZone(), "dd/MM/yyyy"); // Date actuelle
var heure = Utilities.formatDate(now, Session.getScriptTimeZone(), "HH"); // Heure actuelle
// Boucle sur les questions 1 à 3
for (let i = 1; i <= 3; i++) {
let questionKey = 'question ' + i;
let reponseKey = 'réponse ' + i;
// Vérifie si la question et la réponse sont renseignées
if (data[questionKey] !== "" && data[reponseKey] !== "") {
let nouvQuest = FEUIL_ADMIN.getLastRow() + 1; // Nouvelle ligne à insérer
// Insère les données dans les colonnes correspondantes
FEUIL_ADMIN.getRange(nouvQuest, 1).setValue(numero); // Colonne 1 : Numéro de la question
FEUIL_ADMIN.getRange(nouvQuest, 2).setValue(data['nom'].toUpperCase()); // Colonne 2 : Nom en majuscules
FEUIL_ADMIN.getRange(nouvQuest, 3).setValue(data[questionKey]) // Colonne 3 : Question
.setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // Applique le retour à la ligne
FEUIL_ADMIN.getRange(nouvQuest, 4).setValue(data[reponseKey]); // Colonne 4 : Réponse
FEUIL_ADMIN.getRange(nouvQuest, 5).setValue(date); // Colonne 5 : Date
FEUIL_ADMIN.getRange(nouvQuest, 6).setValue(heure); // Colonne 6 : Heure
// Colonne 7 : Validation (Validé ou Refusé)
var validationRule = SpreadsheetApp.newDataValidation()
.setAllowInvalid(false)
.requireValueInList(['Validé', 'Refusé'], true)
.build();
FEUIL_ADMIN.getRange(nouvQuest, 7).setDataValidation(validationRule);
}
}
}Bravo Pierre çà fonctionne bien
Il me reste à comprendre ton code
Merci à tous
1 on déclare les constantes, des données fixes dont on va se servir à plusieurs endroits, dans notre cas les feuilles.
2 la première fonction a pour but de récupérer les infos, tester si on a ce qui est attendu et si oui, envoyer les données dans la fonction d'enregistrement.
Afin de simplement récupérer les données et pouvoir rendre cela simple à maintenir, au lieu de prendre les données une à une comme ceci :
var quest1 = feuilQuest.getRange(6,2).getValue();
var quest2 = feuilQuest.getRange(9,2).getValue();
var quest3 = feuilQuest.getRange(12,2).getValue();
var repons1 = feuilQuest.getRange(6,4).getValue();
var repons2 = feuilQuest.getRange(9,4).getValue();
var repons3 = feuilQuest.getRange(12,4).getValue();J'ai fais un objet, avec un clé et une valeur :
var data = { // Dictionnaire des adresses de cellules pour les données
'nom': 'B3',
'question 1': 'B6',
'question 2': 'B9',
'question 3': 'B12',
'réponse 1': 'D6',
'réponse 2': 'D9',
'réponse 3': 'D12'
};Donc, les clés sont par exemple nom, question 1, etc, et les valeurs, initialement sont les adresses des cellules, ainsi, si ta page change, tu as juste à mettre à jour ici, tout va suivre.
Sauf qu'il faut ensuite récupérer les données, c'est ce que fais ce bout de code :
// Remplace les adresses des cellules par leurs valeurs
for (let key in data) {
let cellAddress = data[key]; // Adresse de la cellule (ex: 'B3')
let cellValue = FICH_SONDAGE.getRange(cellAddress).getValue(); // Valeur dans la cellule
data[key] = cellValue; // Remplace l'adresse par la valeur
}Ici, on va réattribuer les adresses et les remplacer par les valeurs, ainsi, à la place de B3 il y aura le nom, en question 1 ce qu'il y a en B6 etc...et s'il n'y a rien, eh bien l'emplacement sera vide.
Donc, on a un objet "data" avec des clés, et des données associés à chaque clé, maintenant on veut vérifier si on a nos données requises, donc, le nom et au moins une paire question + réponse, pour ce faire, on va déjà voir s'il y a quelque chose dans data['nom'] :
// Vérifie que le nom est obligatoire
if (data['nom'] === "") {
SpreadsheetApp.getUi().alert("Le champ 'nom' est obligatoire. Veuillez le remplir.");
return;
}Ensuite, on va directement vérifier si le nom entré est déjà connu, pour se faire on va tester dans la feuille admin toutes les lignes complétées colonne 2 (en mettant l'input user en MAJUSCULE) :
// Vérifie si le nom existe déjà dans la feuille "admin"
const adminData = FEUIL_ADMIN.getRange(1, 2, FEUIL_ADMIN.getLastRow(), 1).getValues();
for (let i = 0; i < adminData.length; i++) {
if (adminData[i][0].toUpperCase() === data['nom'].toUpperCase()) {
SpreadsheetApp.getUi().alert("Vous ne pouvez pas faire l'opération plusieurs fois.");
return;
}
}Après, oui, là c'est un peu plus complexe, car on doit tester une donnée, puis SA pair (donc est ce que question 2 est complété ET réponse 2)
Donc, on initie un booléen faux disant qu'il n'y a PAS de pair, puis on teste les clés question et réponses 1, 2 et 3 si on a des données aux 2 pairs on passe le booléen en VRAI.
à la fin de ces lignes, si le booléen est VRAI on continue, s'il est FAUX alors on affiche un message d'erreur et on stop.
// Vérifie qu'au moins un couple question + réponse est renseigné
let pairQuestReponse = false; // Initialement, aucun couple valide trouvé
for (let i = 1; i <= 3; i++) {
let questionKey = 'question ' + i;
let reponseKey = 'réponse ' + i;
// Vérifie si la question et la réponse correspondante ne sont pas vides
if (data[questionKey] !== "" && data[reponseKey] !== "") {
pairQuestReponse = true; // Au moins un couple question + réponse est valide
break; // Sort de la boucle si un couple valide est trouvé
}
}
// Si aucun couple valide n'a été trouvé, affiche un message d'erreur
if (!pairQuestReponse) {
SpreadsheetApp.getUi().alert("Au moins un couple question + réponse doit être complété.");
return;
}Donc, à arrivé à cet instant, on sait que l'objet "data" contient, un nom et au moins une paire question + reponse.
Maintenant on va envoyer "data" dans une autre fonction, pour l'enregistrement :
enregistreQuest(data);3. la fonction d'enregistrement, donc, elle reçoit les données et doit les enregistrer.
Dans un premier temps on va stocker quelques données, le numéro de la dernière ligne, le numéro, on va créer un objet date et de cet objet, générer une date et une heure aux formats voulus :
const dernQuest = FEUIL_ADMIN.getLastRow(); // Obtient la dernière ligne remplie
const numero = dernQuest-1; // Numéro pour la nouvelle question
var now = new Date();
var date = Utilities.formatDate(now, Session.getScriptTimeZone(), "dd/MM/yyyy"); // Date actuelle
var heure = Utilities.formatDate(now, Session.getScriptTimeZone(), "HH"); // Heure actuelleEnsuite, tu avais fait un test, sur chaque question, si il y a une donnée tu répétais un script similaire ; afin d'optimiser l’exécution, le but est d'éviter les répétions, pour ce faire, vu qu'on a 3 pairs possibles, je fais une boucle sur 3 et on va interroger l'objet data voir si 1, 2 ou 3 pairs sont complétés :
// Boucle sur les questions 1 à 3
for (let i = 1; i <= 3; i++) {
let questionKey = 'question ' + i;
let reponseKey = 'réponse ' + i;Ensuite, pour chaque pair on teste s'il y a des données à insérer ;
// Vérifie si la question et la réponse sont renseignées
if (data[questionKey] !== "" && data[reponseKey] !== "") {Et si oui, on crée une nouvelle ligne (sinon, la boucle passe à la paire question - réponse suivante), on insère le numéro précédemment généré, le nom (en MAJ), la question, la réponse, la date, l'heure et la validation.
let nouvQuest = FEUIL_ADMIN.getLastRow() + 1; // Nouvelle ligne à insérer
// Insère les données dans les colonnes correspondantes
FEUIL_ADMIN.getRange(nouvQuest, 1).setValue(numero); // Colonne 1 : Numéro de la question
FEUIL_ADMIN.getRange(nouvQuest, 2).setValue(data['nom'].toUpperCase()); // Colonne 2 : Nom en majuscules
FEUIL_ADMIN.getRange(nouvQuest, 3).setValue(data[questionKey]) // Colonne 3 : Question
.setWrapStrategy(SpreadsheetApp.WrapStrategy.WRAP); // Applique le retour à la ligne
FEUIL_ADMIN.getRange(nouvQuest, 4).setValue(data[reponseKey]); // Colonne 4 : Réponse
FEUIL_ADMIN.getRange(nouvQuest, 5).setValue(date); // Colonne 5 : Date
FEUIL_ADMIN.getRange(nouvQuest, 6).setValue(heure); // Colonne 6 : Heure
// Colonne 7 : Validation (Validé ou Refusé)
var validationRule = SpreadsheetApp.newDataValidation()
.setAllowInvalid(false)
.requireValueInList(['Validé', 'Refusé'], true)
.build();
FEUIL_ADMIN.getRange(nouvQuest, 7).setDataValidation(validationRule);
}Pour verrouiller une page, clic droit sur l'onglet > protéger la page (attention, ça peut entrer en contradiction avec les scripts).
Pour gérer les droits, quand une feuille est protégée, tu peux définir les autorisations.
Google Forms ne répondait pas à ton besoin ? C'est un moyen simple, no-code de faire des formulaires personnalisés et les retours sont envoyés dans Google Sheets.
Les protections des feuilles ont été faites sans que j'intervienne, j'aurais dû le préciser.
J'ai pas pensé à google forms, mais les questions ne vont plus se rajouter en admin.
idem pour les réponses à une 20éne de question, que j'ai fait sur une autre page.
Je vais regarder pour la gestion des droits. Merci
