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

🛠 Utilisation de CustomUIEditor pour Personnaliser le Ruban Excel

🗓️ Simulateur de Congés et Calendrier Collaboratif sous Google Sheets

Explication VBA : Facturation automatique Gestion client