Format personnalisé sous condition

Bonjour,

C'est pourtant très simple comme demande mais je n'ai pas trouvé (ou alors mal cherché).

Colonne A j'ai des cellules avec un menu déroulant (3 options)
Colonne B je rentre une valeur numérique
Je souhaite que cette valeur s'affiche avec une unité différente selon l'option choisie en A

Exemple
Choix de l'option 1 en A, je tape 15 en B et ça s'affiche 15 m²
Choix de l'option 2 en A, je tape 35 en B et ça s'affiche 35 ml
Choix de l'option 3 en A, je tape 20 en B et ça s'affiche 20 kg

C'est dommage que "mise en forme conditionnelle" ne fasse pas ce boulot.

Avez-vous une solution à me proposer ?

Par avance merci

Salut,

Il y a sans doute plus optimale mais assez simplement, si tu n'as que 3 catégories, une imbrication de SI ?

Ex : =SI(A2="Surface";B2&" m²";SI(A2="Liquide";B2&" ml";SI(A2="Masse";B2&" kg";"")))

image

EDIT : pour plus de robustesse, je ferais un tableau de correspondance dans une feuille "paramétrage" avec les unités et leurs terminaisons

=B2&" "&RECHERCHEX(A2;'Parametrage'!A:A;'Parametrage'!B:B;"")

Bonjour,

Alternativement, la manière "correcte" de procéder dans votre cas n'est pas trop une MFC mais une table de référence. Vous entrez dans la 1e colonne vos valeurs recherchées, et dans la 2e les correspondance. Puis vous utilisez Fonction RECHERCHEX - Aide Éditeurs Google Docs pour trouver le résultat.

Par exemple

LiquidemL
MasseKg
Surfacem2

Ensuite vous utilisez le même procédé que Pierre.

Alternativement, vous pouvez aussi l'utiliser en MFC en définissant 1 MFC par type et en vérifiant la valeur de la cellule A de la ligne correspondante. Par exemple : =$A1="Liquide"

Sans MFC vous perdez le type des données, qui passe de nombre à texte, avec MFC vous le gardez mais c'est beaucoup plus de travail surtout si vous avez beaucoup d'unités. De plus les MFC peuvent vite alourdir un classeur.

EDIT : je viens de voir l'edit de Pierre, qui va dans le meme sens que moi.

D'abord merci à vous deux pour ces propositions.

Vous me confirmez que dans ce que vous proposez, on doit nécessairement ajouter une colonne de "résultat" (colonne C).

Ne peut-on pas envisager une solution en passant par l'app script pour modifier l'affichage "à la volée" de ma cellule B2 (par exemple) qui afficherait le résultat de votre cellule C2 ?

S'il existe une solution mais complexe, ne vous prenez pas la tête avec ça, je rajouterai une colonne.

Il y a toujours une solution : (modifies juste le nom de la feuille)

const NOMENCLATURE = {
  "Masse": "kg",
  "Liquide": "ml",
  "Surface": "m2"
};

function onEdit(e) {
  const sheet = e.range.getSheet();
  const range = e.range;
  if (sheet.getName() === "Feuille 1" && range.getColumn() === 2) { 
    const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];
    sheet.getRange(range.getRow(), range.getColumn()).setValue(range.getValue() + " " + unit);
  }
}

Le même script avec la doc (si besoin) :

/**
 * Dictionnaire associant une catégorie à son unité de mesure.
 * @type {Object.<string, string>}
 */
const NOMENCLATURE = {
  "Masse": "kg",
  "Liquide": "ml",
  "Surface": "m2"
};

/**
 * Déclenché automatiquement lors de la modification d'une cellule dans la feuille.
 * Ajoute l'unité de mesure à la valeur de la cellule si elle se trouve dans la colonne 2 de la feuille "Feuille 1".
 * 
 * @param {GoogleAppsScript.Events.SheetsOnEdit} e - Événement de modification de la feuille.
 */
function onEdit(e) {
  const sheet = e.range.getSheet();  // Récupère la feuille où a eu lieu la modif
  const range = e.range; //  Récupère la range de modif
  if (sheet.getName() === "Feuille 1" && range.getColumn() === 2) {  // Vérifie si la modification a eu lieu dans la colonne 2 de la feuille "Feuille 1" A CHANGER.
    const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];  // Récupère la catégorie depuis la première colonne de la même ligne, la passe dans la nommenclature pour retourner l'unitée.
    sheet.getRange(range.getRow(), range.getColumn()).setValue(range.getValue() + " " + unit); // Ajoute l'unité de mesure à la valeur de la cellule.
  }
}

Si possibilité avec une formule, je l'ignore.

Joli script Pierre, peut-etre rajouter un cas par défaut (affectation d'une string nulle en amont?) pour gérer le cas ou la recherche échoue (valeur non tabulée, problèmes de majuscules et d'accents…).

Vraiment extra si on y arrive

Alors pour le moment petite erreur de range apparemment :

/**
 * Dictionnaire associant une catégorie à son unité de mesure.
 * @type {Object.<string, string>}
 */
const NOMENCLATURE = {
  "1.place de ponton": "ml",
  "2.terre-plein": "m²",
  "3.hangar": "m²"
};

/**
 * Déclenché automatiquement lors de la modification d'une cellule dans la feuille.
 * Ajoute l'unité de mesure à la valeur de la cellule si elle se trouve dans la colonne 2 de la feuille "Feuille 1".
 * 
 * @param {GoogleAppsScript.Events.SheetsOnEdit} e - Événement de modification de la feuille.
 */
function onEdit(e) {
  const sheet = e.range.getSheet();  // Récupère la feuille où a eu lieu la modif
  const range = e.range; //  Récupère la range de modif
  if (sheet.getName() === "LOCATIONS" && range.getColumn() === 11) {  // Vérifie si la modification a eu lieu dans la colonne 2 de la feuille "Feuille 1" A CHANGER.
    const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];  // Récupère la catégorie depuis la première colonne de la même ligne, la passe dans la nommenclature pour retourner l'unitée.
    sheet.getRange(range.getRow(), range.getColumn()).setValue(range.getValue() + " " + unit); // Ajoute l'unité de mesure à la valeur de la cellule.
  }
}

J'ai mis le 11 car la colonne K dans laquelle je dois saisir le nombre se trouve ici.

Et en exécutant le script j'ai cette erreur :

image

EDIT : réponse à Saboh

Quand je propose un script, c'est en réponse à un énoncé donné, je n'inclus pas de gestion des erreurs, logs, try...catch ou autre, car j'ignore les tenants / aboutissants.

Mais si dans cet exemple, on voulait rendre + fiable, il nécessiterait plusieurs points de vérifications :

e = une donnée

e = un nombre

unit = définit

Voici comment nous pourrions faire avec à la fois des logs et info user avec message :

/**
 * Dictionnaire associant une catégorie à son unité de mesure.
 * @type {Object.<string, string>}
 */
const NOMENCLATURE = {
  "Masse": "kg",
  "Liquide": "ml",
  "Surface": "m2"
};

/**
 * Déclenché automatiquement lors de la modification d'une cellule dans la feuille.
 * Ajoute l'unité de mesure à la valeur de la cellule si elle se trouve dans la colonne 2 de la feuille "Feuille 1".
 * 
 * @param {GoogleAppsScript.Events.SheetsOnEdit} e - Événement de modification de la feuille.
 */
function onEdit(e) {
  const sheet = e.range.getSheet();  // Récupère la feuille où a eu lieu la modif
  const range = e.range; //  Récupère la range de modif
  const value = range.getValue(); // Récupère la valeur de la cellule modifiée

  if (sheet.getName() === "Feuille 1" && range.getColumn() === 2 && value !=="") { 
    if (typeof value !== "number") {
      console.error("L'entrée " + value + " située en " + range.getA1Notation() + " n'est pas un nombre");
      Browser.msgBox("Valeur incorrecte en " + range.getA1Notation());
      return; // Arrête l'exécution de la fonction si la valeur n'est pas un nombre
    }

    const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];  

    if (unit) {
      sheet.getRange(range.getRow(), range.getColumn()).setValue(value + " " + unit); 
    } else {
      console.error("Unité introuvable pour la mesure : " + sheet.getRange(range.getRow(), 1).getValue() + " veuillez vérifier la nomenclature.");
      Browser.msgBox("Erreur nomenclature pour la mesure : " + sheet.getRange(range.getRow(), 1).getValue() + " veuillez consulter les logs.");
    }
  }
}

Après, il est toujours possible d'aller plus loin, mettre en rouge la donnée erronée par exemple, en gras, la supprimer, etc.

@numerus ici :

const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];

on va chercher l'élément de la liste déroulante dans la 1ere colonne, est-ce que les listes sont bien en 1ere colonne ?

Non non c'est très simple, pas besoin de compliquer, je n'en ai pas besoin. C'est juste visuellement pratique, je tape 10, je valide la cellule et ça affiche 10 m² ou 10 ml en fonction de l'option choisie dans la colonne précédente.

@pierre : la liste déroulante est en colonne J

edit 2 : si je mets 10 à la place de 1, j'ai la même erreur

Dans ce cas remplace :

const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 1).getValue()];

par :

const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 10).getValue()];

Concernant la réponse à Saboh en effet, de base je ne prévois pas de vérification, car partant du postulat que les données sont fiables (liste déroulante obligatoire par ex), surtout que + de vérification = script plus lent et plus long, pour des personnes ne connaissant pas forcément bien app script, "less is better" .

Mais il est tout à fait possible d'enrichir en vérifications, protections et parades diverses afin de pallier de mauvais usages, bug, etc... tout dépend de l'usage voulu, un formulaire pour une banque n'aura pas les mêmes contraintes qu'une inscription pour une asso.

Vraiment top

Voilà ce que ça donne :

image

@pierre : juste peut être remplacer "undefined" par un autre mot ou rien, un blanc, qu'en penses-tu ?

Tu dois avoir des formules ? Car j'ai testé avec le script initial, pas d'erreurs :

image

Ajoute une vérification savoir si unit existe, remplace

sheet.getRange(range.getRow(), range.getColumn()).setValue(range.getValue() + " " + unit); // Ajoute l'unité de mesure à la valeur de la cellule.

par :

if(unit){sheet.getRange(range.getRow(), range.getColumn()).setValue(range.getValue() + " " + unit);}// Ajoute l'unité de mesure à la valeur de la cellule.

Rebonjour, désolé j'étais avec des clients.

Alors, malgré l'erreur dans le journal d’exécution qui persiste, le comportement attendu demandé est opérationnel comme ça, je vais donc tester le comportement de ton script sur plusieurs jours et voir si je garde ça en prod.

Un grand merci, je vais clore le sujet.

Si tu as des erreurs, utilise la version "complexe" :

/**
 * Dictionnaire associant une catégorie à son unité de mesure.
 * @type {Object.<string, string>}
 */
const NOMENCLATURE = {
  "1.place de ponton": "ml",
  "2.terre-plein": "m²",
  "3.hangar": "m²"
};

/**
 * Déclenché automatiquement lors de la modification d'une cellule dans la feuille.
 * Ajoute l'unité de mesure à la valeur de la cellule si elle se trouve dans la colonne 2 de la feuille "Feuille 1".
 * 
 * @param {GoogleAppsScript.Events.SheetsOnEdit} e - Événement de modification de la feuille.
 */
function onEdit(e) {
  const sheet = e.range.getSheet();  // Récupère la feuille où a eu lieu la modif
  const range = e.range; //  Récupère la range de modif
  const value = range.getValue(); // Récupère la valeur de la cellule modifiée

  if (sheet.getName() === "LOCATIONS" && range.getColumn() === 11 && value !=="") { 
    if (typeof value !== "number") {
      console.error("L'entrée " + value + " située en " + range.getA1Notation() + " n'est pas un nombre");
      Browser.msgBox("Valeur incorrecte en " + range.getA1Notation());
      return; // Arrête l'exécution de la fonction si la valeur n'est pas un nombre
    }

    const unit = NOMENCLATURE[sheet.getRange(range.getRow(), 10).getValue()];  

    if (unit) {
      sheet.getRange(range.getRow(), range.getColumn()).setValue(value + " " + unit); 
    } else {
      console.error("Unité introuvable pour la mesure : " + sheet.getRange(range.getRow(), 1).getValue() + " veuillez vérifier la nomenclature.");
      Browser.msgBox("Erreur nomenclature pour la mesure : " + sheet.getRange(range.getRow(), 1).getValue() + " veuillez consulter les logs.");
    }
  }
}
Rechercher des sujets similaires à "format personnalise condition"