Script de vérification de l'onglet actif Le sujet est résolu

Avatar de l’utilisateur
dubs_one
Messages : 10
Inscription : 20 janv. 2023 14:23
A remercié : 1 fois
Remercié : 2 fois

Script de vérification de l'onglet actif

Message par dubs_one »

Bonjour,

J'ai créé une "fiche" sur un onglet qui me permet d'exporter par mail un PDF A4 avec des infos que je récupère dans un tableau sur l'onglet d'à côté.
Le hic, c'est que je n'avais pas anticipé de devoir en créer une seconde sur un nouvel onglet... ce qui m'oblige à adapter maintenant mes scripts que je lance depuis le menu Google Sheet :
function onOpen() {var ui = SpreadsheetApp.getUi();var menu = ui.createMenu("Fiche de FAB");
menu.addItem("[Guide] Comment utiliser le planning.","reglesUtilisateur");
menu.addItem("Copier sur le serveur","exportMailServeur");
menu.addItem("Envoyer par mail","exportMailUtilisateur");
menu.addItem("Vider la Fiche de FAB","cleanFab");
menu.addToUi();}
J'ai fait mes tests sur la dernière option du menu "Vider la Fiche de FAB" car c'est la plus pratique/rapide (et surtout je n'envoie pas de mail à chaque fois).

La seule variable qui me parait importante, c'est celle qui me permet de cibler toutes mes constantes dans les 3 scripts du menu, à savoir le nom de l'onglet, que j'ai appelé "fabID".
Donc avant je ciblais forcément "FAB", maintenant je dois lancer mes scripts sur "FAB" ou "FAB2".

Plutôt que créer des duplicatas de mes fonctions (testées et approuvées) dans code.gs (et donc de doubler les entrées de mon menu), je me suis dit qu'il serait plus "propre" de créer une boucle pour vérifier l'onglet affiché, et renvoyer la variable "fabID" qui m'intéresse.

Jusqu'ici, je suis parvenu à lancer le bon script en fonction de l'onglet affiché :
Si onglet "FAB" affiché -> lance cleanFab1() 👍
Si onglet "FAB2" affiché -> lance cleanFab2() 👍
Si tout autre onglet du classeur -> message d'erreur 👍

Là où ça se complique, c'est que j'ai essayé de voir comment adapter cette "boucle" pour qu'elle ne soit pas DANS ma fonction "cleanFab()" (laquelle appelait ensuite soit cleanFab1() soit cleanFab2()), pour que ce soit une fonction autonome que je pourrai utiliser dans mes autres scripts quelque soit l'item cliqué dans mon menu.

J'ai donc créé une nouvelle fonction "controlOnglet()", et j'ai placé son activation au début de ma fonction "cleanFab()" en espérant pouvoir ensuite copier juste cette ligne au début de mes 2 autres scripts de menu.
Sauf que la variable "fabID" ne veut pas suivre... et j'ai un message d'erreur qui m'indique qu'elle n'est pas définie.

Voilà où je me suis arrêté à ce stade...
function controlOnglet() {
var ongletID = SpreadsheetApp.getActiveSpreadsheet().getSheetName();
if(ongletID == 'FAB'){
const fabID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB');
}else if(ongletID == 'FAB2'){
const fabID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB2');
} else{
var ui = SpreadsheetApp.getUi();
ui.alert('Vous devez être sur l\'onglet de votre fiche de FAB');
}}

function cleanFab() {
controlOnglet()
//const fabID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(ongletID);
const cellPlanning = fabID.getRange('G2').clearContent();
const cellDevis = fabID.getRange('M2').clearContent();
const cellProdPoses = fabID.getRange('H15').clearContent();
const cellProdDouble = fabID.getRange('F17').clearContent();
const cellProdFormat = fabID.getRange('F19').clearContent();
const cellProdPasse = fabID.getRange('N15').clearContent();
const cellProdFeuilles = fabID.getRange('O17').clearContent();
const cellProdTotal = fabID.getRange('P19').clearContent();
if(ongletID == 'FAB2'){
const cellDescriptif = fabID.getRange('A8').clearContent();
}}
J'ai bien tenté un truc en utilisant la variable "ongletID" mais ça n'a pas marché... pour les mêmes raisons d'ailleurs...

Si une bonne âme peut m'aider... snif.
Avatar de l’utilisateur
NC-Ahmet

Coach Numericoach
Invétéré
Messages : 87
Inscription : 19 sept. 2022 14:09
A remercié : 16 fois
Remercié : 19 fois

Re: Script de vérification de l'onglet actif

Message par NC-Ahmet »

Hello, j'espère que tu vas bien !

Il y a tellement de méthodes possibles pour résoudre ta problématique...

Mais en l'état, la chose la plus simple à mettre en place à mon avis, ça serait de faire en sorte que ta fonction controlOnglet() retourne une valeur que tu pourras ré-utiliser dans ta fonction cleanFab().

Par exemple : 

function controlOnglet() {
const ongletID = SpreadsheetApp.getActiveSpreadsheet().getSheetName();
const fabTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB');
const fab2Tab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB2');

if(ongletID == 'FAB'){
return fabTab;
}else if(ongletID == 'FAB2'){
return fab2Tab;
}else{
const ui = SpreadsheetApp.getUi();
ui.alert('Vous devez être sur l\'onglet de votre fiche de FAB');
}

Ici, si l'onglet actif est "FAB", la fonction controlOnglet() va return SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB'). S'il s'agit de "FAB2", cette même fonction controlOnglet() va return SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB2').

Ensuite, dans ta fonction cleanFab(), tu pourras rajouter la ligne suivante tout au début :

function cleanFab() {
const fabID = controlOnglet()

//ton code ici...
}

Ça devrait t'aider sans devoir trop modifier ton code existant. 😉

Bon weekend ! 
Avatar de l’utilisateur
dubs_one
Messages : 10
Inscription : 20 janv. 2023 14:23
A remercié : 1 fois
Remercié : 2 fois

Re: Script de vérification de l'onglet actif

Message par dubs_one »

Bonjour NC-Ahmet,

Merci pour ta réponse, c'est toujours aussi limpide !

Ce "return" qui encapsule la variable (si je comprends bien), c'est ce qu'il me manquait...
Comme tu l'as deviné, je "code" en bidouillant et en interprétant des bouts que je trouve à droite et à gauche, mais les subtilités du langage m'échappe.

J'ai réussi à faire plus ou moins la même chose, mais sans vraiment comprendre pourquoi ça avait marché...
C'est d'ailleurs pour ça que je n'ai pas réussi à le refaire dans le cas exposé plus haut.

L'une des autres fonctions, ExportMail(), est lancée grâce à une fenêtre de dialogue que j'active dans mon menu :
function exportMailUtilisateur() {
const fabID = SpreadsheetApp.getActiveSpreadsheet();
const fabID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB');
const responsableID = fabID.getRange('D4').getValue();
var ui = SpreadsheetApp.getUi();
var result = ui.prompt('Renseignez votre mail :', ui.ButtonSet.OK_CANCEL);
var button = result.getSelectedButton();
var mailID = result.getResponseText();
if (button == ui.Button.OK) {
exportMail(mailID)
}}


Puis :
function exportMail(mailID) {
const docID = SpreadsheetApp.getActiveSpreadsheet().getId();
const fabID = SpreadsheetApp.getActiveSpreadsheet();
const matriceID = Sp... etc.


J'avais remarqué que dans certains codes, je retrouvais les variables dans les parenthèses des fonctions, donc j'ai essayé et ça a marché.
Ça me paraissait logique de mettre les valeurs dans les parenthèses de la fonction que j'appelle parce qu'elles suivaient en quelque sorte le cheminement du code, pour passer d'une fonction à l'autre...
Mais c'est vraiment au doigt mouillé :-)

Cette ligne là par exemple "const fabID = controlOnglet()", sa logique m'échappe complètement... je comprends que c'est la fonction qui transmets la valeur de la variable du coup, mais c'est une fonction, pas une variable justement... et que se passe-t-il si j'ai besoin de récupérer plusieurs variables (ou constantes) ?
Par exemple dans mon cas, si j'avais besoin de d'une seconde constante autre que fabID, ça ne marcherait plus n'est-ce pas ?

PS : Je n'ai pas encore pu tester ta solution (désolé), j'espère que mes clients me laisseront un peu en paix d'ici la fin de la semaine pour me remettre dessus !
Avatar de l’utilisateur
NC-Ahmet

Coach Numericoach
Invétéré
Messages : 87
Inscription : 19 sept. 2022 14:09
A remercié : 16 fois
Remercié : 19 fois

Re: Script de vérification de l'onglet actif

Message par NC-Ahmet »

Hello,

Pour t'expliquer la logique derrière "const fabID = controlOnglet()" ta fonction controlOnglet() retourne une valeur car on a rajouté des "return" dans la fonction.

if(ongletID == 'FAB'){
return fabTab;
}else if(ongletID == 'FAB2'){
return fab2Tab;

Ici, on utilise return, ça veut dire que si je fais un console.log(controlOnglet()), la console va imprimer la valeur que la fonction est en train de "return".

On peut donc utiliser une fonction comme variable, oui !

Exemple, si je crée une fonction qui fait une addition simple :

function addition(a, b) {
  const resultat = a + b
  return resultat
}


Ici, ma fonction addition prend deux valeurs, les additionne et les attribue à la variable resultat puis le retourne.

Ça signifie que addition(1, 2) retourne la valeur 3 (car c'est a+b, soit 1+2 dans ce cas), donc je peux l'attribuer à une variable, par exemple :

const maValeur = addition(1, 2)   
> ici, on attribue la valeur retournée par addition(1, 2) à la variable maValeur

Naturellement, console.log(maValeur) affichera la valeur 3 dans ma console.

Si tu as besoin de retourner plusieurs valeurs c'est simple : retourne un tableau (Array en anglais, caractérisé par les crochets, par exemple ["a", "b", "c"]) ou un objet (Object en anglais, caractérisé par les accolades {1: "a", 2: "b", 3: "c"})

Je te redirige sur la documentation officielle au sujet de l'instruction return, au sujet des tableaux (Array) et des objets (Object).

A+ !
Avatar de l’utilisateur
dubs_one
Messages : 10
Inscription : 20 janv. 2023 14:23
A remercié : 1 fois
Remercié : 2 fois

Re: Script de vérification de l'onglet actif

Message par dubs_one »

Merci pour le débrief et les liens !
J'irai étudier tout ça plus tard en prenant le temps de faire quelques exercices pour mieux saisir le concept 😅

J'ai testé ta solution sur ma boucle de vérification ce soir et ça donne ça :

function controlOnglet() {
const ongletID = SpreadsheetApp.getActiveSpreadsheet().getSheetName();
const fabTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB');
const fab2Tab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('FAB2');
if(ongletID == 'FAB'){
return fabTab;
}else if(ongletID == 'FAB2'){
return fab2Tab;
}else{
const ui = SpreadsheetApp.getUi();
ui.alert('Vous devez être sur l\'onglet de votre fiche de FAB');
}}


function cleanFab() {
const fabID = controlOnglet()
//const fabID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(ongletID);
const cellPlanning = fabID.getRange('G2').clearContent();
const cellDevis = fabID.getRange('M2').clearContent();
const cellProdPoses = fabID.getRange('H15').clearContent();
const cellProdDouble = fabID.getRange('F17').clearContent();
const cellProdFormat = fabID.getRange('F19').clearContent();
const cellProdPasse = fabID.getRange('N15').clearContent();
const cellProdFeuilles = fabID.getRange('O17').clearContent();
const cellProdTotal = fabID.getRange('P19').clearContent();
const cellTest = fabID.getRange('T6').getValue();
if(cellTest == 2){
const cellDescriptif = fabID.getRange('A8').clearContent();

}}


Alors ça marche nickel sauf qu'il se passe un truc que je n'avais pas anticipé... la fonction "cleanFab()" s'exécute AUSSI quand aucun des 2 onglets est sélectionné.
Donc juste après le message qui prévient l'utilisateur, j'ai un renvoi d'erreur sur le script car forcément, la constante "fabID" n'est pas définie...
J'ai fait quelques recherches/tests mais je n'ai pas trouvé le terme qui permettrait de stopper la lecture du script.

L'autre aspect qui m'a fait perdre un peu de temps ce soir, c'est ce petit "If" dans "cleanFab()" qui me permet de vider la cellule A8 uniquement sur "FAB2" (parce que sur "FAB", cette cellule contient une formule que je ne veux pas vider). N'ayant pas réussi à le faire proprement, j'ai contourné le problème en mettant un "2" en blanc sur fond blanc (invisible) pour tester la valeur incognito. C'est moche mais ça semble marcher...

Encore merci pour ton temps passé et ta bienveillance !
Répondre

Rejoignez la discussion 💬

Vous devez être enregistré pour participer à la discussion et échanger avec les différents membres

Inscrivez-vous dès aujourd'hui

Vous n'êtes pas encore membre ? Rejoignez-nous gratuitement dès aujourd'hui et contribuer en postant votre réponse ou question sur tous les forums disponibles

Inscription

Connectez-vous