Incrémentation + suivi + reset mois + suivi du nbre de plafonds atteint

Bonjour à tous,

J'ai un groupe de membres, pour lesquels j'organise des événements virtuels.

Pour chaque participation à un de ces évènements, un point est attribué au membre.

Cette partie la fonctionne avec un script.

Mais afin de suivre la fréquence, je souhaite modifier ce qui suis.

  • Conserver l'attribution d'un point par participation à chaque événement.
  • Ajouter un point pour un membre participant à deux évènements dans un même mois.

Pour le moment la mécanique que je vois serait la suivante :

Au moment où le script "set" le point de participation un événement, il faudrait qu'il le fasse à deux endroits

Le premier ne change pas de l'actuel et permet de conserver le suivis en cours.

Le second sur un onglet masqué, incluant le nom du membre (début de ligne) et la date à laquelle le dernier point est attribué

"nom membre" | "nombre de points" | "pts fréquence" | "mois/ an"

À chaque changement du "nombre de point" :

  • Incrémenter de "1" si le mois est le même
  • Reset à "1" si le mois est différent
  • Si la valeur passe à "2" incrémenter le "pts fréquence", mais ne pas incrémenter si la fréquence plus d'une fois par mois (ne pas incrémenter pour 3 pts, etc)

note: le chiffre peux passer à plus de deux, mais n'incrémentera pas la dernière valeur. Seule la seconde participation sur un même mois compte.

Fichier ci-dessous

https://docs.google.com/spreadsheets/d/1ZH9JN0kECXPMFcMETtAZV1XPOJr35DMVj5_cowlbtvQ/edit?usp=sharing

Edit: J'ai oublié que mes connaissance se limite à adapter" du code, je n'ai pas de connaissance pour le rédiger.

Bonjour,

  • où se trouve la date de l'événement ?
  • pour le calcul, est-ce dans le même mois ou dans "30 jours glissants" ? en d'autres termes, s'il y a participation le 31 mars et le 1er avril, cela vaut 1 ou un bonus ?

Bonjour et merci de prendre le temps,

La date de l'événement n'importe pas dans mon cas. Je ne souhaite pas savoir à quel date un membre à participer à un événement par le passer, mais uniquement combien de fois il a participé, et combien de fois, il a participé plus de 2 fois dans un même mois.

Pour obtenir le point bonus, il faut que les deux participations soit en mars, le 31 mars et le 1er avril ne donnerait donc pas de point bonus.

Voir Sheet3 (tu peux masquer les colonnes D et E)

function onEdit(e) {
  var f = e.source.getActiveSheet();
  var cel = e.source.getActiveRange();
  if (f.getName()=='Sheet3'){
    if (cel.getValue()){
      var i = cel.getRow()
      var m = Utilities.formatDate(new Date(), "GMT+1", "MM")
      var y = Utilities.formatDate(new Date(), "GMT+1", "yyyy")
      if ((f.getRange('D'+i).getValue()==y) && (f.getRange('E'+i).getValue()==m)) {
        var p=2
      }else{
        var p=1
      }
      f.getRange('C'+i).setValue(p)
      f.getRange('D'+i).setValue(y)
      f.getRange('E'+i).setValue(m)
      Browser.msgBox(p+' point(s)')
      cel.setValue(!cel.getValue())
    }
  }
};

Bonsoir Mikhail

Merci !

Si je comprends bien, cela

Ajoute 1 point si la cellule est à 1 ou à 0, et rien si la cellule est déjà à 2.

Réinitialise à 1 si le mois est différent depuis le dernier changement.

Si j'arrive à fusionner ce que tu m'as donné avec ce que j'avais, c'est excellent !

Je suis trop fatigué pour essayer là, mais demain je m'y colle :)

Je ferais un retour ici si j'y arrive

Merci encore

Bonsoir Mikhail

J'ai tenté différentes approches, mais je ne comprends pas comment faire pour que le script ne se déclenche que manuellement.

J'ai d'abord essayé de transformer le "onEdit(e)'" en fonction normale, mais sans y parvenir.

Puis j'ai tenté de cumuler les deux fonctions, mais celle "onEdit" ne se déclenche pas si l'autre est active, et la fonction "onEdit" réagis à toutes modifications sur la ligne, ce qui ne me permettrait plus de modifier par exemple, un nom de membre, ou tout autre valeurs.

Idéalement, "valider"

  1. Ajouterais systématiquement 1pt sur la colonne D, (sans plafond)
  2. Ajouterais 1pt dans la limite de 2 par mois sur la colonne E (comme ce que tu as fait sur la seconde feuille en colonne C)
  3. Ajouterais la date sur les colonnes F et G
  4. Ajouterais 1pt dans la limite de 1 par mois (mais sans autre plafond), si un "2" a été affiché en colonne E sur la même ligne.

Si jamais tu as une idée pour aller dans ce sens, je suis preneur.

Merci pour ton aide,

Je n'ai pas tout saisi ce que tu souhaitais, néanmoins voici la fonction déclenchée manuellement

function valider() {
  var classeur = SpreadsheetApp.getActiveSpreadsheet();
  var f = classeur.getSheetByName('Sheet1');
  for (var i=2;i<f.getLastRow();i++){
    if (f.getRange('C'+i).getValue()){
      var m = Utilities.formatDate(new Date(), "GMT+1", "MM")
      var y = Utilities.formatDate(new Date(), "GMT+1", "yyyy")
      if ((f.getRange('F'+i).getValue()==y) && (f.getRange('G'+i).getValue()==m)) {
        var p=2
      }else{
        var p=1
      }
      f.getRange('D'+i).setValue(p)
      f.getRange('F'+i).setValue(y)
      f.getRange('G'+i).setValue(m)
      Browser.msgBox(p+' point(s) ligne '+i)
     // cel.setValue(!cel.getValue())
    }
  }
};

est-ce que à partir de là tu saurais "broder" quelque chose ? sinon dis moi ce qu'il manquerait !

Bonjour Mikhail,

Merci pour la version "cliquable" du script, j'ai en effet pu broder quelque chose, c'est un mix, donc je vois bien que le code serait améliorable, mais au moins, 3/4 de ce que je veux fonctionne.

Le point gagner en colonne D n'a aucune "condition" autre que cocher la case et cliquer.

Le point en colonne H, quant à lui en a 2 :

  1. On ne peut gagner que 1 pt par mois en cours
  2. Au moins 2 points ont été gagnés par ce membre en colonne D sur "le mois en cours"

Le décompte de la colonne E ne m'est pas nécessaire en lui-même, je ne le vois que comme une étape pour le résultat sur colonne H.

La logique dans le script ci-dessous vérifie déjà il me semble, s’il y a déjà eu un point de donné dans le mois en cours puisque le mois et l'année sont noté et donné comme condition pour savoir s’il y aura un 1 ou un 2.

for (var i=2;i<f.getLastRow();i++) {
        if (f.getRange('C'+i).getValue()) {
          var m = Utilities.formatDate(new Date(), "GMT+1", "MM")
          var y = Utilities.formatDate(new Date(), "GMT+1", "yyyy")
          if ((f.getRange('F'+i).getValue()==y) && (f.getRange('G'+i).getValue()==m)) {
            var p=2
            }else {
            var p=1
            }

          f.getRange('E'+i).setValue(p)
          f.getRange('F'+i).setValue(y)
          f.getRange('G'+i).setValue(m)
          d.setValues(dv);
        }
    }

Du coup, plutôt que de donner un 1 ou un 2 en colonne E, ne serait-il pas possible de directement incrémenter le deuxième point mensuel seulement ?

Encore merci pour ton aide.

Re-bonjour Mikhail,

J'ai réussi à broder quelque chose qui marche !

Juste afin d'être certain de ne pas avoir cassé des fonctionnalités (surtout celle qui concerne le changement de mois), pourrais-tu me confirmer si ce qui suit reste valide ?

Par ailleurs, j'ai mélangé un script que j'avais pour la colonne D, peut être serait-il plus propre de l'intégré avec ton style.

function valider() {
    var classeur = SpreadsheetApp.getActiveSpreadsheet();
    var f = classeur.getSheetByName('Sheet1');

    var z = f.getRange('C2:C499');
    var zv = z.getValues();
    var d = f.getRange('D2:D499');
    var dv = d.getValues();

    for(var j=0;j<zv.length;j++) {
        console.log(zv[j][0]);
        if(zv[j][0]===true) {
                 dv[j][0]++;
        }
    }

    for (var i=2;i<f.getLastRow();i++) {
        if (f.getRange('C'+i).getValue()) {
          var m = Utilities.formatDate(new Date(), "GMT+1", "MM")
          var y = Utilities.formatDate(new Date(), "GMT+1", "yyyy")
        var p = f.getRange('H'+i).getValue()
          if ((f.getRange('F'+i).getValue()==y) && (f.getRange('G'+i).getValue()==m)) 
            {
            var p = p+1        // l'incrementation doit se faire de 1 par mois, si participation à 2 events
                    }
            else 
            {
            var p = p        // pas de pas d'incrémentation (ni reset)
                        }

          f.getRange('E'+i).setValue(p)
          f.getRange('F'+i).setValue(y)
          f.getRange('G'+i).setValue(m)
          d.setValues(dv);
        }
    }

    f.getRange('C2:C30').setValue('FALSE');
    Browser.msgBox(' Token given! ')
};

Dans tout les cas, je te remercie infiniment, je n'y serais sans doute pas parvenu sans ton aide.

Je viens de tester à grandeur réelle, le script fonctionne, mais toutefois avec un problème avec la commande pour décocher les lignes

 f.getRange('C2:C30').setValue('FALSE');

Le problème est le temps requis pour mes 500 lignes

N'y a-t-il pas une possibilité de lui faire décocher que les cases qui étaient coché lors de l'exécution ?

J'aurais rarement plus de 20 ou 30 participants simultanés.

je viens de tester ceci sur 1200 lignes

function raz(){
  var f = SpreadsheetApp.getActiveSheet();
  f.getRange('A1:A1200').setValue('FALSE');
}

cela ne met pas plus d'une seconde

as-tu un autre script du genre onEdit qui lui ralentirait l'effacement des coches ?

Bonjour Mikhail,

Non, voici (ci-dessous) tous les scripts que j'ai sur mon fichier "live", celui-ci étant sur 499 lignes et allant jusqu'à la colonne BM.
Le script ne ciblant que les colonnes nécessaires, je ne pense pas que ça soit lié.

J'ai deux autres script, mais à ma connaissance, aucun ne se déclenche "onEdit", ils ont des actions manuels.

Lorsque j'exécute le dernier script, il lui arrive parfois de dépasser les 6 min et que j'ai un timeout.

J'ai modifié le fichier de test sur lequel on a fait le script, pour lui ajouter le même nombre de lignes. Ce matin, j'ai lancé un script avec 8 cases cochées et le script a mis 48 secondes avant de se terminer. Ce fichier n'ayant que ce dernier script.
function Commendation() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName('Roster');

  var z = s.getRange('N2:N499');
  var zv = z.getValues();

  var o = s.getRange('O2:O499');
  var ov = o.getValues();

  for(var i=0;i<zv.length;i++) {
    console.log(zv[i][0]);
    if(zv[i][0]===true) {
      ov[i][0]++;
    }
  }

  o.setValues(ov);
  s.getRange('N2:N499').setValue('FALSE');
  SpreadsheetApp.flush();
};

function Mission() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName('Roster');

  var z = s.getRange('P2:P499');
  var zv = z.getValues();

  var q = s.getRange('Q2:Q499');
  var qv = q.getValues();

  for(var i=0;i<zv.length;i++) {
    console.log(zv[i][0]);
    if(zv[i][0]===true) {
      qv[i][0]++;
    }
  }

  q.setValues(qv);
  s.getRange('P2:P499').setValue('FALSE');
  SpreadsheetApp.flush();
};
function returnDims(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var lRow = sheet.getLastRow();
  var imgUrl = '';

  for (var i = 2; i <= lRow; i++) {
    r1 = sheet.getRange(i, 1);
    imgUrl = r1.getValue();
    if (imgUrl != ''){
      imageSize(imgUrl, i, 2);
      Utilities.sleep(6000);
    }
  }
}

function imageSize(imgUrl, r, c) {
  if  (typeof imgUrl == 'undefined') {
    imgUrl = '';  //ici un lien normalement mais le forum me le bloque car je n'ai pas trente messages a mon actif
  }

  var t = '';     
  t += '<script>\n';
  t += 'function hd(){\n';
  t += 'var img = new Image();\n';
  t += 'img.onload = function() {\n';
  t += "google.script.run.returnVal(this.width / this.height, " + r + ", " + c + ");\n";
  t += '}\n';
  t += "img.src = '" + imgUrl + "';\n";
  t += '}\n';
  t += 'google.script.run.withSuccessHandler(google.script.host.close)\n';
  t += '.returnVal(hd(), ' + r + ', ' + c + ');\n';
  t += '</script>\n';  

  var output = HtmlService.createHtmlOutput(t);
  output.setSandboxMode(HtmlService.SandboxMode.IFRAME); 
  SpreadsheetApp.getUi().showModalDialog(output,'please, wait...');
  output.clear();

}

function returnVal(h, r, c) {
  Logger.log(h);
  var sheet = SpreadsheetApp.getActiveSheet();
  var R = sheet.getRange(r, c);

  if (h != '') {
  R.setValue(h);}

}

Ce dernier script est celui rédigé par toi et que j'ai modifié, si dessous il s'agit de la version live, donc avec un autre titre, les colonnes adaptées, et une msgBox avec un texte diffèrent.

function PVPChallenge() {
    var classeur = SpreadsheetApp.getActiveSpreadsheet();
    var f = classeur.getSheetByName('Roster');

    var z = f.getRange('R2:R');
    var zv = z.getValues();
    var d = f.getRange('S2:S');
    var dv = d.getValues();

    var o = f.getRange('O2:O');
    var ov = o.getValues();

    for(var j=0;j<zv.length;j++) {
        console.log(zv[j][0]);
        if(zv[j][0]===true) {
        dv[j][0]++;
    ov[j][0]++;
        }
    }

    for (var i=2;i<f.getLastRow();i++) {
        if (f.getRange('R'+i).getValue()) {
            var m = Utilities.formatDate(new Date(), "GMT", "MM")
            var y = Utilities.formatDate(new Date(), "GMT", "yyyy")
            var p = f.getRange('T'+i).getValue()
        if ((f.getRange('U'+i).getValue()==y) && (f.getRange('V'+i).getValue()==m)) 
            {
            var p = p+1 
            }
            else 
            {
            var p = p
            }

        d.setValues(dv);
        o.setValues(ov);
        f.getRange('T'+i).setValue(p)
        f.getRange('U'+i).setValue(y)
        f.getRange('V'+i).setValue(m)
        }
    }

    f.getRange('R2:R').setValue('FALSE');
    Browser.msgBox(' All tokens have been given! ')
    SpreadsheetApp.flush();
};

Encore une fois, merci pour ton aide,

Tu n'as pas non plus de déclencheur ? (triggers)

Je suis un peu sec pour expertiser ... tu peux toujours me donner le lien (en mp si tu le souhaites) vers ton projet simplifié, juste pour tester.

Bonjour Mikhail,

Merci pour ton retour,

Je n'ai aucun déclencheur, (je savais même pas qu'il y avait ça en fait)

image

et en cherchant je suis tombé là-dessus :

image

Comme j'ai fait divers test hier, je ne suis pas certain que des erreurs dans mes modifs de script ne soit pas la cause du délai, mais celui de ce matin à 80.589 secondes a été fait avec le script collé dans mon post plus haut.

Même sur le fichier de test auquel tu as accès, le dernier test est à 51 secondes, et il n'y a que ce script.

Encore merci pour tout le temps que tu y passes.

Il me semble que ceci ne devrait pas être dans la boucle !

    o.setValues(ov);
    d.setValues(dv);

j'ai aussi réduit le nombre de lignes dans le script au strict nécessaire (mais pas dans la feuille) et enlevé console.log

Ce sont les résultats du mix de ce que j'avais déjà et du script que tu m'as fourni.

Il s'agit d'un incrément simple (pas d'autre condition que la checkbox) sur 2 autres colonnes.

J'ai essayé de le faire de la même manière que toi, mais sans y arriver.

Excellent !

Rien à demander de plus > sujet résolu

Merci Mikhail !

Rechercher des sujets similaires à "incrementation suivi reset mois nbre plafonds atteint"