Excel VBA - Création et remplissage d'un autre fichier
Bonjour à vous,
Je bosse actuelle sur une macro, qui a pour but d'organiser les réponses à un sondage.
Par ce sondage, mes répondants procèdent en fait à leur inscription sur un ou plusieurs ateliers.
Je vous explique mon souci :
J'ai un fichier source "Sondage" qui recense toutes les réponses au sondage.
Dans celui-ci, une colonne indique le nombre d'ateliers auxquels la personne s'est inscrite (entre 1 et 5).
En sortie de ma macro, j'ai besoin d'avoir créé 5 fichiers Excel distincts qui contiennent les informations de mes inscrits. Chaque fichiers contiendra les infos de toutes les personnes s'étant inscrites sur le même nombre de formations.
J'ai donc commencé par faire une boucle For, pour lire chaque case de ma colonne.
Ensuite, en faisant un Select, je réagis selon le nombre d'ateliers.
En utilisant un booléen par possibilité (donc de 1 à 5), j'arrive à empêcher la création d'autant de fichiers qu'il y a d'inscrits.
Malheureusement, ça ne m'en crée qu'un seul, au lieu de 5, et je pense savoir d'où vient l'erreur, sans savoir pour autant la résoudre :
Il crée et ouvre un fichier "1_Atelier", et donc, au second passage dans la boucle, doit sûrement chercher à lire la case dans celui-ci, et non dans le fichier source.
J'aurais donc besoin de vos lumières pour m'aider à :
Créer autant de fichiers que besoin (en l’occurrence 5)
Écrire la ligne contenant les infos de mon inscrit dans le fichier destinataire.
Je vous mets mon bout de code, si ça peut aider à éclairer un peu mes paroles, qui me semblent peu claires (et pourtant, j'ai fait de mon mieux !)
Sub Second_tri()
Dim taille As Integer
Dim x As Integer
Dim nbinscr As String
Dim f1 As Boolean
Dim f2 As Boolean
Dim f3 As Boolean
Dim f4 As Boolean
Dim f5 As Boolean
f1 = False
f2 = False
f3 = False
f4 = False
f5 = False
taille = Application.WorksheetFunction.CountA(Range("B2:B" & Range("B" & Rows.Count).End(xlUp).Row)) + 1
For x = 1 To taille
nbinscr = Range("O" & x).Value
Select Case nbinscr
Case 1:
If f1 = False Then
f1 = True
Workbooks.Add.SaveAs Filename:="D:\TestVBA\Listes_Destinataires\1_Atelier"
End If
'Ouvrir doc 1_Atelier et y coller la ligne N° x du fichier Sondage
Case 2:
If f2 = False Then
f2 = True
MsgBox ("28Atelier cree ?")
Workbooks.Add.SaveAs Filename:="D:\TestVBA\Listes_Destinataires\2_Ateliers"
End If
Case 3:
If f3 = False Then
f3 = True
Workbooks.Add.SaveAs Filename:="D:\TestVBA\Listes_Destinataires\3_Ateliers"
End If
Case 4:
If f4 = False Then
f4 = True
Workbooks.Add.SaveAs Filename:="D:\TestVBA\Listes_Destinataires\4_Ateliers"
End If
Case 5:
If f5 = False Then
f5 = True
Workbooks.Add.SaveAs Filename:="D:\TestVBA\Listes_Destinataires\5_Ateliers"
End If
Case Else
' Rien
End Select
Next x
End SubMerci à vous pour votre lecture, en espérant un petit coup de main !
Bonjour,
Select Case nbinscrVous permet de réaliser différentes actions suivant le nombre d'inscrits. Vous avez écrit les conditions pour 1,2,3,4 ou 5 inscrits, en créant un fichier différent dans chaque cas.
Si vos valeurs dans la colonne O sont différentes de {1,2,3,4,5}, alors la macro ne crée pas de fichier. Vérifier en exécution pas à pas ce qu'il se passe.
Pour info vous devriez pouvoir réaliser ce genre de processus via PowerQuery beaucoup plus simplement.
Bonjour,
Vous permet de réaliser différentes actions suivant le nombre d'inscrits. Vous avez écrit les conditions pour 1,2,3,4 ou 5 inscrits, en créant un fichier différent dans chaque cas.
Si vos valeurs dans la colonne O sont différentes de {1,2,3,4,5}, alors la macro ne crée pas de fichier. Vérifier en exécution pas à pas ce qu'il se passe.
La colonne O de mon document source ne contient que des 1, 2, 3, 4, ou 5. Aucune case n'est vide.
Lorsque je fais un pas à pas, lors de la première itération, ma macro va bien créer mon document "1_Atelier", car elle lit bien ma variable nbinscr, qui à ce moment-là vaut 1.
Par contre, lors de la seconde itération, ma variable ne contient plus rien.
Comme je l'ai souligné dans mon premier post, je suppose que ce vide vient de la source de lecture.
Comme si le programme cherchait à lire la case ("O", x) de mon document "1_Atelier", au lieu d'aller la chercher dans mon document Sondage.
Pour info vous devriez pouvoir réaliser ce genre de processus via PowerQuery beaucoup plus simplement.
J'ai regardé assez rapidement comment ça fonctionne, et cela m'a eu l'air plus compliqué que ce que j'essaye de faire. Ne disposant pas d'énormément de temps, j'ai préféré me rabattre sur une solution sur laquelle j'ai déjà quelques bases.
Bonne journée,
nbinscr = Range("O" & x).ValueRenvoie vers la feuille active, en réalité l'instruction complète équivalente est
nbinscr = ActiveWorkbook.Activesheet.Range("O" & x).ValueC'est pourquoi il est très recommandé d'utiliser des références complètes de cellules, surtout quand on travaille avec plusieurs classeurs.
Corrigez avec (en supposant que la macro est dans le classeur contenant la colonne O)
nbinscr = ThisWorkbook.Worksheets("nom de votre feuille").Range("O" & x).ValueEt voyez si ce problème est corrigé. (mettez le nom de la feuille contenant la colonne O dans les guillemets)
C'est donc bien ce que je pensais.
nbinscr = ThisWorkbook.Worksheets("nom de votre feuille").Range("O" & x).Value
J'ai cherché comment définir mes références complètes, mais après avoir suivi plusieurs discussions sur différents forums, j'ai fini par m'y emmêler les pinceaux.
Je vous remercie pour votre aide !
Auriez-vous également une idée pour la seconde partie de mon souci ? Sur l'intégration de la ligne I dans le fichier destinataire correspondant ?
C'est aussi là une manip dont j'ai trouvé plusieurs tournures différentes, sans trop savoir laquelle était la plus cohérente...
Bonne journée à vous,
Quelque chose comme ceci ?
Sub Second_tri()
' **** votre code ****
Dim taille As Integer
Dim x As Integer
Dim nbinscr As String
Dim f1 As Boolean
Dim f2 As Boolean
Dim f3 As Boolean
Dim f4 As Boolean
Dim f5 As Boolean
f1 = False
f2 = False
f3 = False
f4 = False
f5 = False
taille = Application.WorksheetFunction.CountA(Range("B2:B" & Range("B" & Rows.Count).End(xlUp).Row)) + 1
' **** votre code ****
' on cree un liste de classeurs
Dim wbExport(1 To 5) As Workbook
Dim i As Long
For i = 1 To 5
Set wbExport(i) = Workbooks.Add
wbExport(i).SaveAs Filename:= _
"D:\TestVBA\Listes_Destinataires\" _
& i & "_Atelier"
Next i
For x = 1 To taille
nbinscr = ThisWorkbook.Worksheets("nom de votre feuille").Range("O" & x).Value
' copie de la ligne x du classeur "mere" dans le classeur wbExport correspondant
ThisWorkbook.Worksheets("nom de votre feuille").Rows(x).Copy _
' (dans la 1e ligne dispo de la 1e feuille)
wbExport(nbinscr).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Offset(1,0)
Next x
End SubEn effet, quelque chose comme ceci.
Ça semble effectivement nettement moins brouillon que mon code, mais je vous avoue que j'aurais été bien incapable d'atteindre un tel résultat aussi bien optimisé.
Ça fonctionne à merveille, et répond à toutes mes difficultés, je vous remercie sincèrement pour votre aide !
Bonne journée à vous
Je vous en prie, si vous avez d'autres questions n'hésitez pas, et sinon n'oubliez pas de fermer le fil.
Ne jugez pas votre code trop vite, il est primordial de bien mettre les choses "a plat" afin de comprendre ce que l'on veut. L'optimisation vient dans un second temps. La base que vous avez fournie m'a permis de bien saisir le "principe", et je vous l'ai juste un peu simplifiée (car je déteste écrire 2x la meme chose ahah).
S'il y a une chose vraie en programmation, c'est qu'en général si vous vous retrouvez à écrire quasi la même chose 3x d'affilée, c'est qu'il est probablement possible de faire une boucle.