Script de saisie de bdd

Bonjour

J'ai récupéré un script pour renseigner une bdd à partir d'une feuille de saisie

Voici une image de la feuille de saisie

image

Voici le code utilisé

function saisir(){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var f1 = SpreadsheetApp.getActive();
  var n = f1.getRange('H3').getValue();
  var origine = ["C4","C7","E7","G7","C10","E10","G10"];
  if (n == 4) {
    var destination = ["A","B","F","G","C","E","D"];
    var f2 = doc.getSheetByName('saisie log');
    var derL = getLastDataRow(f2) + 1;
        for (var i = 0; i < origine.length; i++){
      f2.getRange(destination[i] + derL).setValue(f1.getRange(origine[i]).getValue());
    }
    var d = Utilities.formatDate(new Date(), "GMT+1", "yyyy-MM-dd")
    f1.getRange(origine[0]).setValue(d);
    //f1.setActiveSelection(origine[0]);
  } else {
    Browser.msgBox('Merci de renseigner tous les champs !');
    f1.setActiveSelection(origine[0]);
  }
}

function getLastDataRow(f) {
  var lastRow = f.getLastRow();
  var range = f.getRange("A" + lastRow);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }              
}

Voici ce que ca donne dans la feuille "BDD saisie" lorsque je clique sur le bouton que j'ai lié au script "saisir"

image

Ca marche donc parfaitement si je saisie une seule tache logistique

Vous voyez qu'il y a une protection : obligation de renseigner les cellules avec un *

 var n = f1.getRange('H3').getValue();
  if (n == 4) {
....
  } else {
    Browser.msgBox('Merci de renseigner tous les champs !');

En H3, j'ai simplement mis la formule =NBVAL(C4;C7;C10;G10)

A ce niveau tout fonctionne parfaitement

Au niveau du script je butte sur 2 points:

- J'aimerais que dans la saisie pour un même nom, je puisse saisir plusieurs taches associées à plusieurs temps de travail

Et dans ce cas dans la feuille "BDD saisie", cela m'affiche une ligne par tache avec un rappel du nom

ex cette saisie

image

doit donner comme résultat cela

image

Cela bien sur pour éviter de relancer le script pour chaque nouvelle tache pour une même personne

En gros si les lignes 13, 16 ,19 et 22 ne sont pas vide alors je dois réécrire une nouvelle ligne dans le bdd en répétant le nom, type de contrat et agence mais en ajoutant la nouvelle tache de travail et le temps passé

- Une fois que j'ai validé lancé le script, j'aimerais que les cellules bleues qui ont été renseignées se vident afin de renseigner une nouvelle personne. La date en revanche doit rester. De même les cellules blanches contiennent des formules donc ne doivent pas être effacées

Voici le fichier si vous avez besoin de visualiser. Il vous suffit de me demander les droits

https://docs.google.com/spreadsheets/d/1eoR_eanPW_YZIgwHZMUPR88JlAUmhvy1dBfjSGZo2tI/edit#gid=2071785...

ok je reconnais ma contribution, je te fais cela d'ici demain matin

donne moi une autorisation ou donne l'accès a minima en lecture que j'en fasse une copie https://www.sheets-pratique.com/fr/cours/partage

image

Tu peux travailler directement dessus. C'est déjà une copie simplifiée de mon fichier.

En effet c'est ton script que je réutilise car il marche super bien sur mon premier fichier. :)

J'attends une formation sur scprit semaine prochaine pour gagner un peu plus en autonomie sur le sujet ^^

j'ai écrit de façon plus extensive et claire

function saisir(){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var f1 = SpreadsheetApp.getActive();
  var test = f1.getRange('H3').getValue();
  if (test == 'ok') {
    var f2 = doc.getSheetByName('saisie log');
    for (var ligne = 10; ligne <= 22; ligne=ligne+3){
      if (f1.getRange('C'+ligne).getValue()){
        var derL = getLastDataRow(f2) + 1;
        f2.getRange('A'+derL).setValue(f1.getRange('C4').getValue())
        f2.getRange('B'+derL).setValue(f1.getRange('C7').getValue())
        f2.getRange('F'+derL).setValue(f1.getRange('E7').getValue())
        f2.getRange('G'+derL).setValue(f1.getRange('G7').getValue())
        f2.getRange('C'+derL).setValue(f1.getRange('C'+ligne).getValue())
        f2.getRange('E'+derL).setValue(f1.getRange('E'+ligne).getValue())
        f2.getRange('D'+derL).setValue(f1.getRange('G'+ligne).getValue())
      }
    }
  } else {
    Browser.msgBox('Merci de renseigner tous les champs !');
    f1.setActiveSelection(origine[0]);
  }
}

function getLastDataRow(f) {
  var lastRow = f.getLastRow();
  var range = f.getRange("A" + lastRow);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }              
}

Déjà?

Top je l'ai converti sur mon fichier et ca marche impec.

Ca a nécessité 1-2 petits ajustements car mon fichier est un peu différent mais en effet le script est beaucou plus compréhensible

Quel script dois-je écrire pour effacer les cellules en bleues une fois le scprit terminé? En langage macro excel je sais utiliser le clearcontents mais pas encore en javascript

De même j'ai un petit point bloquant mais je ne sais pas s'il y a moyen de l'optimiser ou c'est juste un problème interne à sheet: Si je dois saisir 5 taches, le script dure environ 25 secondes!

En considérant que je peux monter à 400 feuilles de saisie par jour, ca monte à près de 2.5h d'attente par jour

Je présume que l'on a aucun moyen de faire plus vite, c'est la gestion du cloud qui nécessite un tel délai?

quelque chose comme ceci (c'est ~pareil qu'avec excel)

function saisir(){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var f1 = SpreadsheetApp.getActive();
  var test = f1.getRange('H3').getValue();
  if (test == 'ok') {
    var f2 = doc.getSheetByName('saisie log');
    for (var ligne = 10; ligne <= 22; ligne=ligne+3){
      if (f1.getRange('C'+ligne).getValue()){
        var derL = getLastDataRow(f2) + 1;
        f2.getRange('A'+derL).setValue(f1.getRange('C4').getValue())
        f2.getRange('B'+derL).setValue(f1.getRange('C7').getValue())
        f2.getRange('F'+derL).setValue(f1.getRange('E7').getValue())
        f2.getRange('G'+derL).setValue(f1.getRange('G7').getValue())
        f2.getRange('C'+derL).setValue(f1.getRange('C'+ligne).getValue())
        f2.getRange('E'+derL).setValue(f1.getRange('E'+ligne).getValue())
        f2.getRange('D'+derL).setValue(f1.getRange('G'+ligne).getValue())
        f1.getRange('C'+ligne).clearContent()
        f1.getRange('G'+ligne).clearContent()
      }
    }
    f1.getRange('C4').clearContent()
    f1.getRange('C7').clearContent()
  } else {
    Browser.msgBox('Merci de renseigner tous les champs !');
    f1.setActiveSelection(origine[0]);
  }
}

function getLastDataRow(f) {
  var lastRow = f.getLastRow();
  var range = f.getRange("A" + lastRow);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }              
}

Bonjour

Votre script correspond parfaitement à une attente que j'avais

Par contre je ne vois pas où j'indique que je copie les champs de la feuille Saisie vers la Feuille Tableau ?

Merci d'avance

La feuille de saisie est celle-ci

var f1 = SpreadsheetApp.getActive();

la feuille base de données est la f2

var f2 = doc.getSheetByName('saisie log');

ensuite, on affecte à des cellules de f2 la valeur de cellules de f1, exemple

f2.getRange('A'+derL).setValue(f1.getRange('C4').getValue())

as-tu un sujet "bloqué" ? ou un sujet spécifique > poste le.

Prends une copie https://docs.google.com/spreadsheets/d/1CzfnBt4HC0SEAUs9UJa5TQHuWBYnRwpUksg-UNesvTk/copy

function saisir(){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var f1 = SpreadsheetApp.getActive();
  if (f1.getRange('C3').getValue()!='' && f1.getRange('C6').getValue()!='' && f1.getRange('C7').getValue()!='') {
    var f2 = doc.getSheetByName('Bdd');
    var resultat=[]
    for (var i=3;i<=8;i++){resultat.push(f1.getRange('C'+i).getValue())}
    der=f2.getLastRow()+1
    f2.getRange('A'+der+':F'+der).setValues([resultat])
  } else {
    Browser.msgBox('Merci de renseigner les champs obligatoires !');
  }
}

il faudra donner les autorisations

autorisation

Merci beaucoup je vais pouvoir adapter.

Merci pour les clearcontents ;)

Par contre ca alourdit encore plus le script. Je suis passé de 25sec à 55sec l'éxécution

je vais travailler non plus cellule par cellule mais globalement, tu me diras combien tu gagnes

je me suis créé une copie pour ne pas tout perturber

Reprends une copie. Attention, j'ai supprimé certaines en-têtes.

https://docs.google.com/spreadsheets/d/133fNs_S92FKHCQHnksGa_QVFVJg2wCluE7WMvyK9-t0/edit?usp=sharing

function saisir(){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var f1 = SpreadsheetApp.getActive();
  var test = f1.getRange('H3').getValue();
  if (test == 'ok') {
    var data = f1.getRange('C4:G18').getValues()
    var result = []
    var f2 = doc.getSheetByName('saisie log');
    for (var ligne = 6; ligne <= 14; ligne=ligne+2){
      if(data[ligne][0]!=''){
        result.push([data[0][0],data[3][0],data[ligne][0],data[ligne][4],data[ligne][2],data[3][2],data[3][4]])
      }
    }
    var f2 = doc.getSheetByName('saisie log')
    var der = f2.getLastRow()
    f2.getRange(der+1,1,result.length,7).setValues(result)
    f1.getRange('C10:C18').clearContent()
    f1.getRange('G10:G18').clearContent()
  } else {
    Browser.msgBox('Merci de renseigner tous les champs !');
    f1.setActiveSelection(origine[0]);
  }
}

C'est exactement ça!

Maintenant ca met 2-3 sec pas plus

Par contre bien sur avec ta sélection de clearcontent, tu supprimes aussi les intitulés

 f1.getRange('C10:C18').clearContent()

J'ai tenté ca mais ca ne marche pas.

f1.getRange('C10;C13;C16;C19;C22').clearContent()

si je mets des , au lieu des ; c'est pareil.

Il faut que je fasse une ligne par cellule?

edit. Bon même avec une ligne par clearcontents ca n'alourdit pas le temps du script.

Merci beaucoup pour le temps que tu as consacré à ce projet. Tu vas nous faire gagner en productivité!

C'est pour cela que je n'ai laissé qu'un seul intitulé pour les 5 occurrences, et supprimé une ligne sur 3

Oui je pense que je vais laisser comme ca et upprimer les initulés en doublon. Ils ne servent à rien au final

J'avais controlé la longueur du scprit, mais pas le résultat.

En fait cela crée des lignes en trop

ex

image

donne

image

Si je mets plusiuers taches c'est toujours la dernière qui va se dupliquer dans la bdd

De même sur ton ancien script je savais ajuster la colonne où il faut saisir la donnée.

En effet dans mon fichier final, je ne veux pas coller des colonnes A à E mais coller sur certaines colonnes que je dois identifier dans le script

Ou puis-je sélectionner une colonne d'écriture dans ton code?

    var f2 = doc.getSheetByName('saisie log');
    for (var ligne = 6; ligne <= 14; ligne=ligne+2){
      if(data[ligne][0]!=''){
        result.push([data[0][0],data[3][0],data[ligne][0],data[ligne][4],data[ligne][2],data[3][2],data[3][4]])
      }

je ne comprends pas bien !

Si je mets plusiuers taches c'est toujours la dernière qui va se dupliquer dans la bdd

je viens d'essayer ... j'ai bien 5 taches différentes

capture d ecran 625

dans mon fichier final, je ne veux pas coller des colonnes A à E mais coller sur certaines colonnes que je dois identifier dans le script

pour accélérer, je procède en bloc, donc je colle ici (dernière ligne +1 et 1ère colonne)

f2.getRange(der+1,1,result.length,7).setValues(result)

l'ensemble des données mises dans un tableau-résultat

result.push([data[0][0],data[3][0],data[ligne][0],data[ligne][4],data[ligne][2],data[3][2],data[3][4]])

Rechercher des sujets similaires à "script saisie bdd"