Modifier Client (Pour chaque changement détecté :différence entre ancienne et nouvelle valeur)

 Modifier Client (Pour chaque changement détecté :différence entre ancienne et nouvelle valeur)

function ModifierClient_dans_BDD() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sourceSheet = ss.getActiveSheet();
  const targetSheet = ss.getSheetByName("BDD");
  const interventionSheet = ss.getSheetByName("Liste intervention");
  const ui = SpreadsheetApp.getUi();

  const ligneCible = Number(sourceSheet.getRange("F1").getValue());
  const nomClient = sourceSheet.getRange("G2").getValue();
  const idEcoleSource = sourceSheet.getRange("H1").getValue();
  const personne = sourceSheet.getRange("C1").getValue();

  if (!ligneCible || !nomClient || isNaN(ligneCible)) {
    ui.alert("❌ Ligne cible invalide ou nom client vide.");
    return;
  }
  if (ligneCible < 11 || ligneCible > 100000) {
    ui.alert("❌ Ligne de modification hors plage autorisée.");
    return;
  }

  const headers = targetSheet.getRange(10, 1, 1, targetSheet.getLastColumn()).getValues()[0];
  const colIndexByName = Object.fromEntries(headers.map((h, i) => [h, i]));
  const idColIndex = colIndexByName["ID  Ecole"];
  if (idColIndex === undefined) {
    ui.alert("❌ Colonne 'ID  Ecole' introuvable.");
    return;
  }

  const idEcoleBDD = targetSheet.getRange(ligneCible, idColIndex + 1).getValue();
  if (idEcoleBDD !== idEcoleSource) {
    ui.alert(`⚠️ L'ID Ecole de la ligne ${ligneCible} ne correspond pas (${idEcoleBDD} ≠ ${idEcoleSource}).`);
    return;
  }

  const confirmation = ui.alert("Confirmation", "Voulez-vous vraiment modifier ce client dans la BDD ?", ui.ButtonSet.YES_NO);
  if (confirmation !== ui.Button.YES) return;

  const valeurs = {
    "Nom": nomClient
  };

  const ancienneValeurMad = targetSheet.getRange(ligneCible, colIndexByName["Mad Dt MNT"] + 1).getValue(); // Mad
  const ancienneValeureMad = targetSheet.getRange(ligneCible, colIndexByName["eMad Dt MNT"] + 1).getValue(); // eMad
  const ancienneValeurVM = targetSheet.getRange(ligneCible, colIndexByName["Version Mad"] + 1).getValue();  ///// Version Mad
 
  const dynRanges = [
    "G1|H1",
    "F2|G2", "F3|G3", "F4|G4", "F5|G5", "F6|G6", "F7|G7", "F8|G8",
    "I2|J2", "I3|J3", "I4|J4", "I5|J5", "I6|J6", "I7|J7", "I8|J8",
    "K2|L2", "K3|L3", "K4|L4", "K5|L5", "K6|L6", "K7|L7", "K8|L8",
    "M2|N2", "M3|N3", "M4|N4", "M5|N5", "M6|N6", "M7|N7", "M8|N8",
    "O2|P2", "O3|P3", "O4|P4", "O5|P5", "O6|P6", "O7|P7", "O8|P8",
    "Q2|R2", "Q3|R3", "Q4|R4", "Q5|R5", "Q6|R6", "Q7|R7", "Q8|R8",
    "U8|V8", "S2|S3"
  ];

  const cellsToRead = dynRanges.flatMap(p => p.split("|"));
  const cellObjects = sourceSheet.getRangeList(cellsToRead).getRanges();
  const cellValues = cellObjects.map(r => r.getValue());

  for (let i = 0; i < dynRanges.length; i++) {
    const [label, val] = [cellValues[i * 2], cellValues[i * 2 + 1]];
    if (label) valeurs[label] = val;
  }

  const updates = []; //////// Mad
  let nouvelleValeurMad = null;
  for (const [colName, val] of Object.entries(valeurs)) {
    const colIndex = colIndexByName[colName];
    if (colIndex !== undefined) {
      updates.push({ col: colIndex + 1, value: val });
      if (colName === "Mad Dt MNT") nouvelleValeurMad = val;
    }
  }

    const updates2 = []; //////// eMad
   let nouvelleValeureMad = null;
   for (const [colName, val] of Object.entries(valeurs)) {
    const colIndex = colIndexByName[colName];
    if (colIndex !== undefined) {
      updates2.push({ col: colIndex + 1, value: val });
      if (colName === "eMad Dt MNT") nouvelleValeureMad = val;
    }
  }
      const updatesVM = []; //////  update Version Mad
   let nouvelleValeurVM = null;////// new Version Mad
   for (const [colName, val] of Object.entries(valeurs)) {
    const colIndex = colIndexByName[colName];
    if (colIndex !== undefined) {
      updatesVM.push({ col: colIndex + 1, value: val }); //////  update Version Mad
      if (colName === "Version Mad") nouvelleValeurVM = val;//////  new Version Mad
    }
  }

  updates.forEach(u => targetSheet.getRange(ligneCible, u.col).setValue(u.value));  //////// Mad
  updates2.forEach(u => targetSheet.getRange(ligneCible, u.col).setValue(u.value));  //////// eMad
  updatesVM.forEach(u => targetSheet.getRange(ligneCible, u.col).setValue(u.value));  ///// Version Mad

  // 🔁 Intervention seulement si modification de Mad Dt MNT

    const intHeaders = interventionSheet.getRange(1, 1, 1, interventionSheet.getLastColumn()).getValues()[0];
    const colID = intHeaders.indexOf("ID  Ecole");
    const colDate = intHeaders.indexOf("DATE Suivie");
    const colSuivie = intHeaders.indexOf("SUIVIE");
    const colPers = intHeaders.indexOf("Personne");
    const colObs = intHeaders.indexOf("Observation");
    const colNum = intHeaders.findIndex(h => h === "N°" || h === "Num" || h === "Numéro");

   if (ancienneValeurMad !== nouvelleValeurMad && nouvelleValeurMad !== "") {                //////// Mad 2

      // ✅ Insertion ligne à la 2e ligne (juste après en-tête), sans mise en forme
      interventionSheet.insertRows(2, 1);

      if (colID !== -1) interventionSheet.getRange(2, colID + 1).setValue(idEcoleSource);
      if (colDate !== -1) {
      const dateSuivie = Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
      interventionSheet.getRange(2, colDate + 1).setValue(dateSuivie);
      }
      if (colSuivie !== -1) interventionSheet.getRange(2, colSuivie + 1).setValue("Mad Dt MNT");     //////// Mad
      if (colPers !== -1) interventionSheet.getRange(2, colPers + 1).setValue(personne);
      if (colObs !== -1) {
      //const obs = `Avant: ${ancienneValeurMad} | Après: ${nouvelleValeurMad}`;
        const formatDate = d => {
        if (!(d instanceof Date)) return d;
        return Utilities.formatDate(d, ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
        };

          const obs = `Avant : ${formatDate(ancienneValeurMad)} | Après : ${formatDate(nouvelleValeurMad)}`;  //////// Mad 2
      //
      interventionSheet.getRange(2, colObs + 1).setValue(obs);
      }
      if (colNum !== -1 && colIndexByName["Num"] !== undefined) {
      const valNum = targetSheet.getRange(ligneCible, colIndexByName["Num"] + 1).getValue();
      interventionSheet.getRange(2, colNum + 1).setValue(valNum);
      }
     }

   // 🔁 Intervention seulement si modification de eMad Dt MNT
   if (ancienneValeureMad !== nouvelleValeureMad && nouvelleValeureMad !== "") {  //////// eMad 2
    // ✅ Insertion ligne à la 2e ligne (juste après en-tête), sans mise en forme
    interventionSheet.insertRows(2, 1);

    if (colID !== -1) interventionSheet.getRange(2, colID + 1).setValue(idEcoleSource);
    if (colDate !== -1) {
      const dateSuivie = Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
      interventionSheet.getRange(2, colDate + 1).setValue(dateSuivie);
    }
    if (colSuivie !== -1) interventionSheet.getRange(2, colSuivie + 1).setValue("eMad Dt MNT");//////// eMad
    if (colPers !== -1) interventionSheet.getRange(2, colPers + 1).setValue(personne);
    if (colObs !== -1) {
      //const obs = `Avant: ${ancienneValeurMad} | Après: ${nouvelleValeurMad}`;
        const formatDate = d => {
        if (!(d instanceof Date)) return d;
        return Utilities.formatDate(d, ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
        };

          const obs = `Avant : ${formatDate(ancienneValeureMad)} | Après : ${formatDate(nouvelleValeureMad)}`;  //////// eMad 2
      //
      interventionSheet.getRange(2, colObs + 1).setValue(obs);
    }
    if (colNum !== -1 && colIndexByName["Num"] !== undefined) {
      const valNum = targetSheet.getRange(ligneCible, colIndexByName["Num"] + 1).getValue();
      interventionSheet.getRange(2, colNum + 1).setValue(valNum);
    }
  }

   // 🔁 Intervention seulement si modification de VM Dt MNT
   if (ancienneValeurVM !== nouvelleValeurVM && nouvelleValeurVM !== "") {  //////// VM 2
    // ✅ Insertion ligne à la 2e ligne (juste après en-tête), sans mise en forme
    interventionSheet.insertRows(2, 1);

    if (colID !== -1) interventionSheet.getRange(2, colID + 1).setValue(idEcoleSource);
    if (colDate !== -1) {
      const dateSuivie = Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
      interventionSheet.getRange(2, colDate + 1).setValue(dateSuivie);
    }
    if (colSuivie !== -1) interventionSheet.getRange(2, colSuivie + 1).setValue("Version Mad");//////// VM
    if (colPers !== -1) interventionSheet.getRange(2, colPers + 1).setValue(personne);
    if (colObs !== -1) {
      //const obs = `Avant: ${ancienneValeurMad} | Après: ${nouvelleValeurMad}`;
        const formatDate = d => {
        if (!(d instanceof Date)) return d;
        return Utilities.formatDate(d, ss.getSpreadsheetTimeZone(), "dd/MM/yyyy");
        };

          const obs = `Avant : ${formatDate(ancienneValeurVM)} | Après : ${formatDate(nouvelleValeurVM)}`;  //////// eMad 2
      //
      interventionSheet.getRange(2, colObs + 1).setValue(obs);
    }
    if (colNum !== -1 && colIndexByName["Num"] !== undefined) {
      const valNum = targetSheet.getRange(ligneCible, colIndexByName["Num"] + 1).getValue();
      interventionSheet.getRange(2, colNum + 1).setValue(valNum);
    }
  }


  sourceSheet.getRange("A1").setValue("");
  ui.alert("✅ Client modifié avec succès dans la BDD !");
}

✅ Résumé des fonctions principales :

1. Vérifications initiales

  • Vérifie la ligne cible (F1) et le nom du client (G2).

  • Compare l'ID Ecole de la source (H1) avec celui de la feuille BDD.

2. Lecture dynamique des libellés et valeurs

  • Lit tous les libellés des cellules comme F2, I3, etc., via la liste dynRanges.

  • Remplit un objet valeurs sous forme :

    js

    { "Mad Dt MNT": "01/06/2025", "eMad Dt MNT": "15/06/2025", ... }

3. Mise à jour dans la feuille BDD

  • Met à jour uniquement les colonnes trouvées par leur nom dans valeurs.

  • Séparé en trois sous-blocs : Mad, eMad et Version Mad.

4. Ajout dans la feuille Liste intervention

  • Pour chaque changement détecté (différence entre ancienne et nouvelle valeur), insère une ligne à la position 2.

  • Ajoute ID Ecole, date du jour, le libellé du champ modifié (SUIVIE), la personne (C1), une observation, et le numéro du client.


Commentaires

Posts les plus consultés de ce blog

RECHERCHEX avec plusieurs conditions (ET / OU) – Guide complet et exemples

🛠 Utilisation de CustomUIEditor pour Personnaliser le Ruban Excel

Tableau croisé dynamique Afficher Matricule “à côté” du Nom & Prénom (en colonne), et non en dessous