Script si modification dans une cellule

Bonjours à tous,

comment faire pour que lorsque:

  • un changement dans une cellule des colonnes en rouge rien ne doit se passe,
  • MAIS que si on modifie une cellule dans la colonne verte (qui est la référence d'après la date du jour" la plus proche") un script de tris s'effectue.
  • Si la modification à lieu dans les lignes 5 à 254 il y aura un tri sur ses lignes seulement et
  • si la modification à lieu dans les lignes 260 à 309 il y aura un tri également que sur ces lignes là.

https://docs.google.com/spreadsheets/d/14E6SomyKVqkr_bw969JazIxwLUaFWh1Cxncyc-eGIE0/edit?usp=sharing

image

Merci pour votre aide éventuel.

mbell

Bonjour,

ton code est déjà tellement complexe, je ne répondrai pas directement, mais je te donnerai des clés pour y arriver toi-même

exemple basique de fonction onEdit

function onEdit(event) {
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  if (################) {
    // mon tri
  }
}

dans les conditions, tu peux tester

  • le nom de la feuille avec feuille.getName()
  • la colonne avec cellule.getColumn() , que tu peux donc comparer avec le résultat de ta fonction rechercheDate()
  • la ligne avec cellule.getRow()

exemple

function onEdit(event) {
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  if (feuille.getName()=='2022' && cellule.getColumn()==rechercheDate() && cellule.getRow()>=5 && cellule.getRow()<=254) {
    // mon tri
  }
}

Bonjour Steelson,

voici le code modifier mais il y a deux question:

function onEdit(event) {
  const sh = SpreadsheetApp.getActiveSheet();
  var spreadsheet = SpreadsheetApp.getActive();
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  var fonction = 'D' + (+rechercheDate() - 5);

  if (spreadsheet && cellule.getColumn()==rechercheDate() && cellule.getRow()>=5 && cellule.getRow()<=254) 
     SpreadsheetApp.getUi().alert('👍 je suis dans les conditions. 👏');//ok   { // mon tri

   spreadsheet.getRange('5:254').activate();
   spreadsheet.getRange('a5:q254').activate()

   .sort([{column: 'D', ascending: false}, // colonne trouvée par le test ?? comment la nommé

         {column: 5, ascending: false}, // tri présence
         {column: 3, ascending: true}, // tri handicap
         {column: 1, ascending: true}, // tri nom
         {column: 2, ascending: true}]);  // tri prénom
   SpreadsheetApp.getUi().alert('👍 tri finis. 👏');
// replacement en haut de la colonne ligne 5

  spreadsheet.getColumn() && getRange('5').activate(); // mettre en haut de la colonne active?
  // mise à jour du nom de la feuille
     var d = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "dd-MM HH:mm");
     SpreadsheetApp.getActiveSpreadsheet().setName('Test Paragolf AFGOLF mise à jour le ' + d) // mettre le nom ici 
        SpreadsheetApp.getUi().alert('👍 renomer la feuille terminé. 👏');
    spreadsheet.getRange('5').activate();
        SpreadsheetApp.getUi().alert('👍 remise en haut de la feuille. 👏');
// fin 
  }
}

comment nommé la colonne ici :

  .sort([{column: 'D', ascending: false}

et de même que revenir à la 5ème ligne de cette colonne en fin de script?

Merci beaucoup pour ton aide

mbell

  var col = rechercheDate()
  spreadsheet.getRange('a5:q254').activate()
 .sort([{ column: col, ascending: false}, // colonne trouvée par le test
         {column: 5, ascending: false}, // tri présence
         {column: 3, ascending: true}, // tri handicap
         {column: 1, ascending: true}, // tri nom
         {column: 2, ascending: true}]);  // tri prénom

le précédent activate() est superflu

et

spreadsheet.getRange(5,col).activate()

Bonjour Steelson,

et merci pour me faire chercher la solution, mais je bloque encore;

voici le code actuel

function onEdit(event) {
  var spreadsheet = SpreadsheetApp.getActive();
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  var fonction = 'D' + (+rechercheDate() - 5);
  var col = rechercheDate();

  if (spreadsheet && cellule.getColumn()==rechercheDate() && cellule.getRow()>=5 && cellule.getRow()<=254){col=true;}else{return;};

 Browser.msgBox(rechercheDate());// test donne la colonne maitre ok 

 // Si je suis dans la bonne colonne "col" continuer si non sortir du script ne fonctionne pas 

 SpreadsheetApp.getUi().alert('👍 je suis dans les conditions. 👏');//ok donc je continue 

  // mon tri
  var col = rechercheDate()
   spreadsheet.getRange('a5:q254').activate()
   .sort([{ column: col, ascending: false}, // colonne trouvée par le test
         {column: 5, ascending: false}, // tri présence
         {column: 3, ascending: true}, // tri handicap
         {column: 1, ascending: true}, // tri nom
         {column: 2, ascending: true}]);  // tri prénom
 SpreadsheetApp.getUi().alert('👍 tri finis. 👏');//ok

// Spreadsheet.getRange('e4').activate(); // cellule du nombre de participant
// Spreadsheet.getRange(col()+13).copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

// mise à jour du nom de la feuille
     var d = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "dd-MM HH:mm");
     SpreadsheetApp.getActiveSpreadsheet().setName('Test Paragolf AFGOLF mise à jour le ' + d) // mettre le nom ici 
 SpreadsheetApp.getUi().alert('👍 renomer la feuille terminé. 👏'); // ok
     spreadsheet.getRange(5,col).activate();
 SpreadsheetApp.getUi().alert('👍 remise en haut de la feuille. 👏');// ne fonctionne pas
//      spreadsheet.getRange(5,col).activate();

// fin
}

Dans un premier temps ce qui est demander est bien fait (donne la bonne colonne) , sur la fin ne se positionne pas sur la ligne 5 et sur la bonne colonne

    spreadsheet.getRange(5,col).activate()
image

Ici j'ai complété la colonne "N" et à la fin ce place sur la cellule "A5".

Tu vois j'essaye mais ne contrôle pas.

Merci pour ton aide.

mbell

re:

Modification qui est presque bonne reste toujours la fin qui n'est pas bonne cela s'arrête à "Tri finis",

function onEdit(event) {
  var spreadsheet = SpreadsheetApp.getActive();
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  var fonction = 'D' + (+rechercheDate() - 5);
  var col = rechercheDate();

  if (spreadsheet && cellule.getColumn()==rechercheDate() && cellule.getRow()>=5 && cellule.getRow()<=254)
      {col=true;}
      else{
      SpreadsheetApp.getUi().alert('👍 je ne suis pas dans les conditions. 👏');//  
        return;}

 Browser.msgBox(rechercheDate());// test donne la colonne maitre ok 

 // Si je suis dans la bonne colonne "col" continuer si non sortir du script ne fonctionne pas 

 SpreadsheetApp.getUi().alert('👍 je suis dans les conditions. 👏');//ok donc je continue 

  // mon tri
  var col = rechercheDate()
   spreadsheet.getRange('a5:q254').activate()
   .sort([{ column: col, ascending: false}, // colonne trouvée par le test
         {column: 5, ascending: false}, // tri présence
         {column: 3, ascending: true}, // tri handicap
         {column: 1, ascending: true}, // tri nom
         {column: 2, ascending: true}]);  // tri prénom
 SpreadsheetApp.getUi().alert('👍 tri finis. 👏');//ok

// Spreadsheet.getRange('e4:e254').activate(); // cellule du nombre de participant
// Spreadsheet.getRange(col()+13).copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); // comment écrire que ces les lignes 4 à 254 ?

 SpreadsheetApp.getUi().alert('👍 Présence à jour. 👏');//ok

// mise à jour du nom de la feuille
     var d = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "dd-MM HH:mm");
     SpreadsheetApp.getActiveSpreadsheet().setName('Test Paragolf AFGOLF mise à jour le ' + d) // mettre le nom de la feuille ici 

     SpreadsheetApp.getUi().alert('👍 renomer la feuille terminé. 👏'); // ok

     spreadsheet.getRange(5,col).activate();

     SpreadsheetApp.getUi().alert('👍 remise en haut de la feuille. 👏');// ne fonctionne pas

//   spreadsheet.getRange(5,col).activate();

// fin
}

Je ne vois pas où la première cellule est en "A5" et pourquoi

   spreadsheet.getRange(5,col).activate();

ne fonctionne pas, help.

Petit supplément ceci ne fonctionne pas non plus que manque t'il ou comment faut il l'écrire.

// Spreadsheet.getRange('e4:e254').activate(); // cellule du nombre de participant
// Spreadsheet.getRange(col()+13).copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); // comment écrire que ces les lignes 4 à 254 ?

Merci pour ton aide Steelson

mbell

1-

Je ne vois pas où la première cellule est en "A5" et pourquoi

   spreadsheet.getRange(5,col).activate();

ne fonctionne pas, help.

qu'est-ce qui ne fonctionne pas ? et pourquoi A5 sachant que tu avais demandé

et de même que revenir à la 5ème ligne de cette colonne en fin de script?

2-

pourquoi mettre true à col ??? ce qui détruit la valeur de col recherchée précédemment

function onEdit(event) {

//...
  var col = rechercheDate();

  if (spreadsheet && cellule.getColumn()==rechercheDate() && cellule.getRow()>=5 && cellule.getRow()<=254)
      {col=true;}
 

pourquoi 3-

Petit supplément ceci ne fonctionne pas non plus que manque t'il ou comment faut il l'écrire.

// Spreadsheet.getRange('e4:e254').activate(); // cellule du nombre de participant
// Spreadsheet.getRange(col()+13).copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); // comment écrire que ces les lignes 4 à 254 ?

il faut arrêter avec les activate() et getActivaRange()

pour copier, il faut identifier la zone à copier, par exemple

var rng = laFeuille.getRange('A2:Z20')

et ensuite copier, par exemple

rng.copyTo(laFeuille.getRange("A1"), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false)

donc indique ce qui soit être copié et où cela doit être copié

Bonjour Steelson,

mbell a écrit :

Je ne vois pas où la première cellule est en "A5" et pourquoi

spreadsheet.getRange(5,col).activate();

ne fonctionne pas, help.

qu'est-ce qui ne fonctionne pas ? et pourquoi A5 sachant que tu avais demandé

Ce qui ne fonctionne pas c'est que l'affichage reste grisé, donc pour un utilisateur maladroit cliquant sur "dell" efface toutes les données.

Mais après réflexion ne serait il pas mieux si possible de rester sur la ligne du changement même si déplacé par un tri.

Je pense à la personne qui serait en ligne 146 et qui après le tri doit chercher sa ligne et qu'il se trouve en 237 heu pas marrant alors de se trouvé en x5 et de devoir chercher son nom dans les 250 lignes plus bas, de toute façon sur le fichier le joueur ne coche que pour lui donc restera sur cette ligne quoi qu'il arrive.

pourquoi mettre true à col ??? ce qui détruit la valeur de col recherchée précédemment

Parce qu'après plusieurs essais j'ai trouvé que la formule fonctionnait: lorsque j'était sur une mauvaise colonne l'alerte "je ne suis pas dans les conditions" s'affichait et qu'en suite le script s'arrêtait là, si j'étais dans la bonne colonne il me donnait le chiffre de la colonne l'alerte "je suis dans les conditions " s'affichait et passait à la suite, le tri la mise à jour du fichier mais je n'avais pas la fin du script donc l'idéal le retour sur la dernière cellule activée et peut importe si elle montée ou descendue de ligne.

image

car pour le moment à la fin c'est ainsi grisé ou bleuté

image

alors que cela devrait être ainsi et

image

et mieux encore le top serait de se retrouver sur la ligne de départ (cellule où l'encodage a eu lieur) et que si à cause du tri la cellule se retrouve en ligne 122 elle suit cet emplacement afin qu'Émilie ne cherche pas sa ligne dans le fichier.

image image

soit après un clic se retrouver sur la cellule de droite mais toujours même ligne.

il faut arrêter avec les activate() et getActivaRange()

Tu as raison, je recopiait d'après la fonction "enregistrer une macro"

Maintenant tu me montre un autre moyen je vais donc essayer cette méthode surement plus efficace.

Dans cet ordre d'idée est ce correct?

var rng6 = spreadsheet.getRange('s4:s254');
var rng12= spreadsheet.getRange('y4:y254'); // et pour toute les 12 colonnes

// la suite du code  

  rng12.copyTo(spreadsheet.getRange("E4"), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false)

 SpreadsheetApp.getUi().alert('👍 Présence à jour. 👏');//ok

Puis je faire des var rng1,2,3,4,5,6,7,8,9,10,11,12 = la feuille(donc spreadsheet).getRange('là les cellule') c'est bien ainsi qu'il faut déterminé une variable

et si on l'appelle ce sera pour la 8 par exemple: rng8.la commande .

Si c'est bien ca il doit manqué quelque chose ou le code modifié n'est pas correct.

Restera encore à formulé comment définir le bon rng en fonction de la rechercheDate puisque je mettrait pour chaque colonne une var rngx

Est ce une bonne méthode Steelson ca fait beaucoup mais cela me permet de chercher aussi.

Merci pour ton aide et ton approche à me faire découvrir ces nouvelles méthodes.

mbell

Désolé, mais je n'ai pas le temps de lire toute une prose.

Pose une question précise en 2 lignes et je répondrai.

Et je n'ai toujours pas compris le col=true !

Re:

Vu sur le forum Opérateur ternaire avec Google Apps Script (sheets-pratique.com) donc j'ai essayer d'adapter, car lorsque qu'on fait un SI il y a aussi une autre solution normalement.

Alors question: comment en fin de script, même s'il y a un tri, rester sur la ligne de donnée cliquée, rester sur Émilie même sil la ligne monte ou descend à cause du tri, est ce possible?

image

Voilà simple et conscrit Steelson.

mbell

Ah oui, j'adhère

En plus tu soulèves en effet un cas très intéressant.

Après essais (il faudra adapter)

function trier(col) {
  var f = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('test tri');
  var valeur = f.getActiveRange().getValue()
  var colonne = f.getActiveRange().getColumn()
  var debut = 4
  var r = f.getRange(debut, 1, f.getLastRow() - (+debut - 1), f.getLastColumn());
  r.sort([{ column: col, ascending: false }]);
  var ligne = f.getRange(debut, colonne, f.getLastRow() - (+debut - 1), 1).getValues().flat().indexOf(valeur) + debut
  f.getRange(ligne, colonne).activate()
}

debut représente ici le première ligne à trier et col la colonne de tri

image

re:

Pour le moment j'ai adapté var début, var f ('2022') mais si c'est la feuille ouverte il faut la nommée aussi

  var f = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('2022');

Parce que ces formules seront sur des feuilles identique une par année il n' y a pas un autre moyen que de donné un nom.

  var debut = 5

mais où puis je mettre la dernière ligne à trier?

re:

1er problème résolut:

  const sh = SpreadsheetApp.getActiveSheet();
  var f = sh //SpreadsheetApp.getActiveSpreadsheet();//.getSheetByName('2022');

Bon je ne sais pas si c'est correct met la function tourne sur la bonne feuille

Reste le problème de la dernière ligne où mettre l'information que c'est la ligne 254, parce que là il fait toute la feuille

mbell

replace

var r = f.getRange(debut, 1, f.getLastRow() - (+debut - 1), f.getLastColumn());

par

var r = spreadsheet.getRange('a5:q254')

re:

doit y avoir un soucis dans "function trier(col)" le col est en gris , dans la var aussi tout comme la nouvelle variable "var r = spreadsheet.getRange('a5:q254')" le r est en gris.

function trier(col) {
  var col = rechercheDate();
  const sh = SpreadsheetApp.getActiveSheet();
  var f = sh //SpreadsheetApp.getActiveSpreadsheet();//.getSheetByName('2022');
  var valeur = f.getActiveRange().getValue()
  var colonne = f.getActiveRange().getColumn()
  var debut = 5
  var r = spreadsheet.getRange('a5:q254')
  var ligne = f.getRange(debut, colonne, f.getLastRow() - (+debut - 1), 1).getValues().flat().indexOf(valeur) + debut
  f.getRange(ligne, colonne).activate()
}

je pense quand même que tu as supprimé une ligne qui était plus qu'utile !

re:

function trier(col) {

  const sh = SpreadsheetApp.getActiveSheet();
  var col = rechercheDate();
  var f = sh //
  var valeur = f.getActiveRange().getValue()
  var colonne = f.getActiveRange().getColumn()
  var debut = 5
  var r = sh.getRange('a5:q254')
  r.sort([{ column: col, ascending: false }]);
  var ligne = f.getRange(debut, colonne, f.getLastRow() - (+debut - 1), 1).getValues().flat().indexOf(valeur) + debut
  f.getRange(ligne, colonne).activate()
}

Enfin trouver j'en reste là pour aujourd'hui, un très grand merci à toi steelson tu es médaille , je reviendrais vers toi plus tard pour cette feuille pour une autre fonction.

mbell

re:

pour info sur ce script si on veut être pointu et bien sûr si c'est réalisable il y a un petit hic:

image

Si l'action se déroule par exemple sur une cellule "Présent" le curseur ira se mettre sur la première cellule "Présent" même chose pour "Absent" et si on supprime ce qui se trouve sur la cellule le curseur ira également sur la première cellule vide.

Et malheureusement pas sur la ligne de départ !

Ne saurait on pas juste avant le tri que la position du curseur (activeRange) ce décale d' une cellule sur la droite ce qui fera, peut être, laisser le curseur sur la bonne ligne même pendant le tri.

Qu'en pense tu?

Merci déjà pour ce que tu as fait pour ce fichier Steelson tu es le plus .

mbell

Il faut une colonne qui soit sans doublons. Si par exemple la colonne A contient des identifiants, alors on pourrait s'y appuyer et revenir ensuite à la colonne affichée. Je vais te faire un exemple mais dis moi dans quelle colonne se trouve un identifiant unique.

Bonjour Steelson,

La colonne "A" A5 à A254

Ce serais une bonne chose cette solution.

Merci à toi.

mbell

Rechercher des sujets similaires à "script modification"