Problème pour ajouter des lignes à la suite en fonction d'une variable

Bonjour à tous,

Je suis apprentis en langage sheet et je suis plus habitué sur du VBA mais ma profession m'a obligé à me convertir.

J'ai créée un fichier et un script grâce à ce forum me permettant de créer des feuilles de routes automatiquement pour des compagnies d'artistes à partir d'un onglet source et les reportant sur un onglet modèle copié à chaque fois. Tout aller bien jusqu'à la rencontre de 2 problèmes que je n'arrive pas à résoudre sur ce script.

Chaque compagnie peut avoir 1 ou 19 artistes par exemple et j'ai des données qui n'ont pas besoin d'être répété sur la feuille de route puisqu'elles sont génériques, tel que les noms de compagnie, nom de spectacle, etc. Etant donné que chaque feuilles reprend l'ensemble des données concernant la compagnie, je ne sais pas si il existe une solution du type pour "tout les artistes de la compagnie x mettre les données à la suite" en bref. Et je sais pas comment scripter ça.

Le second problème est que j'aimerai que les données concernant les repas et les nuitées soient copiés également, c'est une copie d'une plage de donnée par artiste et non pas de cellule propre, j'ai voulu simplifier pour que la plage du fichier source corresponde à celle du modèle. En soit que ça copie la ligne ("S:AX") en ("F26:AF26") sur chaque nouvelle feuille et ainsi de suite

C'est compliqué à expliquer j'espère avoir été clair, j'ai mis ci-joint le document en copie, cleané et anonymisé.

https://docs.google.com/spreadsheets/d/1BM2dbA1I6R-iQYQz7Ey6pg6DOdUdMRxLajjYc2tQiEA/edit?usp=sharing

Avez vous une solution ou un conseil ?

Merci d'avance

Bojour,

Je n'ai pas compris le premier problème ! La phrase ne me paraît pas très française

"tout les artistes de la compagnie x mettre les données à la suite" en bref

Pour le second

f2.getRange('F26').setValue(f3.getRange('X:AX'+ligne).getValue())//il ne fonctionne pas

il y a plusieurs problèmes

  • comme il y a plusieurs données, mets un s à getValues() et à setValues()
  • précise la ligne pour X : f3.getRange('X'+ligne+':AX'+ligne).getValues()
  • et pour la zone qui reçoit, précise la complètement par f2.getRange('F26:?26')en remplaçant ? par la colonne adhoc

Bonjour et merci pour ta solution au second problème, j'ai réadapté le code et ça fonctionne.

Concernant le premier, dans mon doc, j'ai dans mon onglet source plusieurs compagnies, chaque compagnies a à sa charge plusieurs artistes.

Sur mon modèle, j'ai mon tableau en B23 qui reprend les données de chaque artiste de la Cie tel que nom, prénom, régime alimentaire, etc.

Chaque feuilles de route créé reprend donc les données la concernant, si tu regardes bien dans mon onglet source j'ai en colonne C les noms des Cie et pour chaque compagnies j'ai plusieurs artistes que tu retrouves en colonne N toujours dans l'onglet source.

J'aimerai simplement que pour chaque compagnies, les donnés de chaque artistes viennent s'ajouter sur la feuille de route créé qui est dédiée à la Cie.

Donc pour chaque artiste supplémentaire les données qui les concernent sont en en N;O;P; W et sur la plage X:AX et elles doivent juste s'ajouter sur la feuille de route en B27;C27;D27;E27; et sur la plage F27:EF27 et ainsi de suite...

Et je sais pas du tout comment coder ça sur Sheet..

Je sais pas si j'ai été clair...je l'espère.

Merci encore pour le premier problème

ok, vu, mais je ne travaille pas avec des cellules fusionnées ... comment capter les différents artistes pour la compagnie Cie2 par exemple. Et l'autre problème est qu'il y a une case à cocher même quand la ligne e concerne pas la Cie mais un artiste de la Cie. La structure des données n'est pas adaptée.

J'ai défusionner les cellules, c'était une coquille dans mon doc, après pour les artistes je ne sais pas comment faire, est ce qu'il faut retirer les case à cocher pour les artistes supplémentaires ? Si c'est ça c'est pas un problème, je peux le faire manuellement. Si t'as une suggestion pour la structure je peux l'appliquer c'est pas un problème également.

Peut être avec une formule du type "if feuille existe" --> ajouter les donnés artistes à la suite du tableau en B23 ? je sais pas si c'est cohérent et possible?

Sinon créer les feuilles de routes compagnies dans un premier temps ?

Puis dans un second temps créer une colonne avec des cases à cocher spécifique aux artistes avec un script spécifiant que pour chaque artiste sélectionné il faut ajouter les données à la feuille de route de la compagnie correspondante ?

je regarderai ce soir pour une solution simple sans chambouler ton fichier

pourquoi y a t'il Cie2/Cie3/Cie4 ?

mieux vaut n'en mettre qu'un seul et laisser les autres vierges, et ajouter une colonne qui comptera le nombre d'artistes

image

J'ai corrigé, c'était une erreur également désolé.

J'ai développé une fonction spécifique pour déterminer le nombre d'artistes par compagnie. Je vais prendre la main sur ton fichier.

Après, tu me diras s'il est trop lent ... car normalement on ne copie pas des données aussi multiples de cette façon, on passe par des arrays, on verra cela plus tard si nécessaire. Pour l'instant je veux que tu maîtrises le code, que tu saches te l'approprier et le modifier si besoin.

Merci, oui l'idée c'est surtout de m'approprier le code avant tout et de le maitriser. J'ai pas du tout l'habitude de Google Sheet et je vais être amené à travailler de plus en plus dessus donc de monter en compétence.

Cela fonctionne, mais c'est lent à cause de la fin f2.getRange('XX').setValue(f3.getRange('YY').getValue())

function onEdit(event){
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  if (feuille.getName()=='source' && cellule.getColumn()==1 && cellule.getValue()==true) {
    if (cellule.offset(0,2).getValue()!='') {
      nouvelleFeuille(cellule.getRow())
    }
    else {cellule.setValue(false)}
  }
  if (feuille.getName()=='source' && cellule.getColumn()==2 && cellule.getValue()==true) {
    if (cellule.offset(0,1).getValue()!='') {
      supprimerFeuille(cellule.getRow())
      cellule.setValue(false)
      cellule.offset(0,-1).setValue(false)
    }
    else {cellule.setValue(false)}
  }
}

function nbArtistes(ligne){
  var f = SpreadsheetApp.getActiveSheet();
  var der = f.getLastRow()+1
  var cie = f.getRange('C'+(ligne+1)+':C'+der).getValues()
  var artistes = f.getRange('N'+(ligne+1)+':N'+der).getValues()
  var cpt = 0;
  while ( cie[cpt] && cie[cpt][0] == "" && artistes[cpt] && artistes[cpt][0] != "" ) {
    cpt++;
  }
  return (cpt+1);
}

function supprimerFeuille(ligne){
  var document = SpreadsheetApp.getActiveSpreadsheet();
  var f3 = document.getSheetByName('source');
  var nom = f3.getRange('C'+ligne).getValue();
  var f2 = document.getSheetByName(nom); 
  if (f2 != null) {
    document.deleteSheet(f2);
  }
}

function nouvelleFeuille(ligne) {
  var document = SpreadsheetApp.getActiveSpreadsheet();
  var nbArt = nbArtistes(ligne)
  var f1 = document.getSheetByName("modèle");
  var f3 = document.getSheetByName('source');
  var nom = f3.getRange('C'+ligne).getValue();
  var f2 = document.getSheetByName(nom); 

  if (f2 != null) {
    document.deleteSheet(f2);
  }
  f2 = document.insertSheet();
  f2.setName(nom);

  var plage = f1.getRange('A1:AY60')
  var cible = f2.getRange("A1:AG60")

  plage.copyTo(cible);
  var largeurColonnes = SpreadsheetApp.CopyPasteType.PASTE_COLUMN_WIDTHS
  plage.copyTo(cible,largeurColonnes,false);

  // tout ceci est anormalement long, devrait passer par des arrays
  f2.getRange('D2').setValue(f3.getRange('C'+ligne).getValue())
  f2.getRange('D3').setValue(f3.getRange('D'+ligne).getValue())
  f2.getRange('B7').setValue(f3.getRange('I'+ligne).getValue())
  f2.getRange('B8').setValue(f3.getRange('J'+ligne).getValue())
  f2.getRange('B9').setValue(f3.getRange('K'+ligne).getValue())
  f2.getRange('D7').setValue(f3.getRange('L'+ligne).getValue())
  f2.getRange('D8').setValue(f3.getRange('M'+ligne).getValue())
  f2.getRange('D11').setValue(f3.getRange('Q'+ligne).getValue())
  f2.getRange('F11').setValue(f3.getRange('R'+ligne).getValue())
  f2.getRange('D12').setValue(f3.getRange('T'+ligne).getValue())
  f2.getRange('F12').setValue(f3.getRange('U'+ligne).getValue())
  f2.getRange('D13').setValue(f3.getRange('S'+ligne).getValue())
  f2.getRange('B57').setValue(f3.getRange('V'+ligne).getValue())
  for (var i=0; i<nbArt; i++){
    f2.getRange('B26:D26').offset(i,0).setValues(f3.getRange('N'+ligne+':P'+ligne).offset(i,0).getValues())
    f2.getRange('E26').offset(i,0).setValue(f3.getRange('W'+ligne).offset(i,0).getValue())
    f2.getRange('F26:AF26').offset(i,0).setValues(f3.getRange('X'+ligne+':AX'+ligne).offset(i,0).getValues())
  }
};

Le nombre d'artistes est déterminé par le fait qu'on trouve des cases vierges sous Cie alors que les zones Artistes sont encore renseignées.

Tout premièrement merci,
c'est juste ce code là que j'arrive pas à comprendre... : "for (var i=0; i<nbArt; i++)"

nbArt a été établi grâce à la fonction que j'ai ajoutée

var nbArt = nbArtistes(ligne)
function nbArtistes(ligne){
  var f = SpreadsheetApp.getActiveSheet();
  var der = f.getLastRow()+1
  var cie = f.getRange('C'+(ligne+1)+':C'+der).getValues()
  var artistes = f.getRange('N'+(ligne+1)+':N'+der).getValues()
  var cpt = 0;
  while ( cie[cpt] && cie[cpt][0] == "" && artistes[cpt] && artistes[cpt][0] != "" ) {
    cpt++;
  }
  return (cpt+1);
}

il s'agit donc d'une boucle où i va varier de 0 à nbArt-1 et va être utilisé dans la fonction de décalage .offset(i,0) où i sera le décalage en lignes

Je pense avoir compris mais je vais essayer de le reproduire de mon côté et de m'exercer avec, merci encore !

Par ailleurs, quand tu auras intégré de ton côté ce premier script, on pourra retravailler de façon efficace les éléments aujourdh'ui chronophages qui sont les

f2.getRange('XX').setValue(f3.getRange('YY').getValue())

en passant par des tableaux (arrays)

Je pense que je vais mettre un petit temps à le maitriser mais oui pas de problème

J'ai commencé la version v2 sensée être plus rapide, mais il faudrait que je passe du temps à aligner donnees et resultat, l'idée est là, si tu as le temps tu peux tenter le coup...

J'ai jeté un œil et je pense avoir compris la conversion en arrays. Si je comprend bien, le gain de temps est pris parce qu'il collecte plusieurs informations en même temps et non 1 information par 1 information, c'est ça ?

Absolument ... mais dans ton cas la mise au point est un peu pénible. C'est super quand on a un tableau complet. En quelque sorte, on fait une image de la feuille que l'on travaille et que l'on réinjecte.

Rechercher des sujets similaires à "probleme ajouter lignes suite fonction variable"