Vba : Copier certaines colonnes autre feuille
Résolu
Ariane
-
pijaku Messages postés 13513 Date d'inscription Statut Modérateur Dernière intervention -
pijaku Messages postés 13513 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour,
Je souhaite mettre en place une macro dans un fichier de suivi, cette macro doit me permettre de copier les colonnes A à D de ma feuille "Export" des lignes dont ma cellule C est égale à "2009".
Je ne m'y connais pas du tout en Vba alors merci de votre aide.
Je souhaite mettre en place une macro dans un fichier de suivi, cette macro doit me permettre de copier les colonnes A à D de ma feuille "Export" des lignes dont ma cellule C est égale à "2009".
Je ne m'y connais pas du tout en Vba alors merci de votre aide.
12 réponses
-
bonjour
peux tu envoyer une partie significative, sans données confidentielles, avec quelques explications sur ce que tu souhaites obtenir, au format excel 2003 sur cjoint.com et joindre le lien obtenu à ton prochain message, ça nous permettrait de voir comment tes données sont organisées
bonne suite -
Bonjour,
Un exemple de fichier a été déposé sur ce lien https://www.cjoint.com/?BHBjCsHvSIF
J'ai limité la taille des données car je peux monter juste 5000 lignes dans le futur.
Merci de votre aide. -
Bonjour,
Juste les colonnes A à D? Que deviennent E-F etc???
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Je souhaite conserver l'onglet principal (Export) intact et copier les colonnes 1 à 4 dans un onglet 2009 lorsque "Réf année" est égale à 2009, dans l'onglet 2010 lorsque "Réf année" est égale à 2010 et ainsi de suite.
Lors de ma copie dans les nouveaux onglets je ne souhaite pas conserver les colonnes suivantes. -
C'est exactement ça! Merci beaucoup
-
de rien,
on peut faire un petit peu mieux en ordonnant les feuilles selon l'année
https://www.cjoint.com/?3HBltOpiGL1
si c'est fini, peux tu mettre le problème à résolu (en haut à gauche de ton premier message)
bonne journée -
Avec test si feuille existe :
Option Explicit Sub CopieColleA_D() Dim FeuilleDepart As Worksheet, FeuilleArrivee As Worksheet Dim DonneesInitiales(), DonneesFiltrees() Dim MesAnnees As Object, Annee As Range, c Dim lig As Integer, Indice As Integer, col As Byte Set FeuilleDepart = ThisWorkbook.Worksheets("Export") '==> A Adapter.......... With FeuilleDepart Set MesAnnees = CreateObject("Scripting.Dictionary") For Each Annee In .Range("C2", .Range("C" & Rows.Count).End(xlUp)) MesAnnees(Annee.Value) = "" Next Annee DonneesInitiales = .Range("A1:D" & .Range("A" & Rows.Count).End(xlUp).Row) End With For Each c In MesAnnees.keys Indice = 1 If FeuilleExiste(ThisWorkbook, CStr(c)) Then Set FeuilleArrivee = ThisWorkbook.Worksheets(CStr(c)) Else ThisWorkbook.Worksheets.Add ActiveSheet.Name = c Set FeuilleArrivee = ThisWorkbook.Worksheets(CStr(c)) End If For lig = LBound(DonneesInitiales) To UBound(DonneesInitiales) If DonneesInitiales(lig, 3) = c Then ReDim Preserve DonneesFiltrees(4, 1 To Indice) For col = 0 To 3 DonneesFiltrees(col, Indice) = DonneesInitiales(lig, col + 1) Next col Indice = Indice + 1 End If Next lig With FeuilleArrivee .Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(UBound(DonneesFiltrees, 2), UBound(DonneesFiltrees, 1) + 1) = Application.Transpose(DonneesFiltrees) End With Next c End Sub Function FeuilleExiste(wk As Workbook, stFeuille) As Boolean On Error Resume Next FeuilleExiste = Not (wk.Sheets(stFeuille) Is Nothing) End Function
-
re
ou en plus rapide (5000 lignes en 1 s environ)
https://www.cjoint.com/?3HBrdNgVJh1
bonne fin de journée-
Salut ccm81,
Si tu veux gagner en vitesse, déjà faut en voir l'utilité parce que sur 5000 lignes la différence n'est pas probante.
Cependant, pour gagner encore en vélocité, il faut essayer de ne plus accèder aux feuilles de calcul.
Ainsi, pour remplir un Objet Dictionary, tu gagneras du temps en passant d'abord par une variable tableau et de boucler sur ta variable (en mémoire) plutôt que sur ta feuille.
Donc, préférer :Set mondico = CreateObject("Scripting.Dictionary") a = Range("a2:a" & [a65000].End(xlUp).Row) ' tableau a(n,1) For i = LBound(a) To UBound(a) mondico(a(i, 1)) = "" Next i
plutôt que :Set mondico = CreateObject("Scripting.Dictionary") For Each c In Range("a2", [a65000].End(xlUp)) mondico(c.Value) = "" Next c
Ensuite, s'agissant ici d'un fichier "Import", la question à se poser, enfin à poser à ArianeP, c'est l'évolution de son fichier...
Faut il supprimer les feuilles? Ajouter les nouvelles donénes en dessous de chacune?
-
-
bonjour pijaku
1. c'est ce que j'ai fait pour la ventilation des données dans les feuilles années, la différence est quand même sensible pour 5000 lignes, 1s au lieu de 5s (sur ma machine)
2. je n'ai pas (bêtement) fait la démarche pour la création du dico (merci de ta remarque, je m'y remets)
3. pour ce qui est de réaliser une MAJ plutôt qu'une reconstruction après destruction des feuilles, vu le temps que ça prend, est ce que ça vaut le coup?
cordialement-
est ce que ça vaut le coup?
On ne sait pas. Tout dépends de la destination de ce classeur.
S'il s'agit d'un import mensuel qu'il faut ventiler chaque fois dans les feuilles années, ça vaut certainement le coup que les données de février, mars etc se retrouvent dans les feuilles 2009, 2010 après les données de janvier.
D'où, dans le code que j'ai proposé, la ligne :.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(UBound(DonneesFiltrees, 2), UBound(DonneesFiltrees, 1) + 1) = Application.Transpose(DonneesFiltrees)
-
-
avec la création du dico depuis le tableau je gagne 0.15 s, c'est mieux.... mais pas tout à fait le temps d'aller boire un café !!!
cdlt-
-
De même, la ventilation des données en changeant de feuille quasiment à chaque ligne, te fait perdre 1 seconde.
' ventilation des données dans les feuilles annee For li = 1 To lifinFS - 1 nomf = td(li, coannFS) lifinFV = Sheets(nomf).Cells(Rows.Count, codebFS).End(xlUp).Row For co = codebFS To cofinFS Sheets(nomf).Cells(lifinFV + 1, co).Value = td(li, co) Next co Next li
peut être avantageusement remplacé par :
1- une boucle sur les années (dico)
2- une boucle sur les données (td)
3- le remplissage d'un tableau de sortie
4- remplissage de la feuille "année" par un Resize = Application.transpose(tableaudesortie)
5- next année
En fait, le plus rapide, et je me répète ça aurait vraiment de l'importance sur 20 000 lignes et plus, serait :Sub CopieColleA_D() Dim FeuilleDepart As Worksheet, FeuilleArrivee As Worksheet Dim DonneesInitiales(), DonneesFiltrees(), AnneesColC(), temp() Dim MesAnnees As Object, Annee Dim lig As Integer, Indice As Integer, i As Integer, col As Byte Dim t t = Timer Set FeuilleDepart = ThisWorkbook.Worksheets("Feuil1") '==> A Adapter.......... With FeuilleDepart Set MesAnnees = CreateObject("Scripting.Dictionary") AnneesColC = .Range("C2", .Range("C" & Rows.Count).End(xlUp)) For i = LBound(AnneesColC) To UBound(AnneesColC) MesAnnees(AnneesColC(i, 1)) = "" Next i temp = MesAnnees.keys 'http://boisgontierjacques.free.fr/pages_site/Dictionnaire.htm Call tri(temp, LBound(temp), UBound(temp)) DonneesInitiales = .Range("A1:D" & .Range("A" & Rows.Count).End(xlUp).Row) End With For Each Annee In temp Indice = 1 'http://www.developpez.net/forums/d269391/logiciels/microsoft-office/excel/macros-vba-excel/vba-e-feuille-existe/ If FeuilleExiste(ThisWorkbook, CStr(Annee)) Then Set FeuilleArrivee = ThisWorkbook.Worksheets(CStr(Annee)) Else ThisWorkbook.Worksheets.Add ActiveSheet.Name = Annee Set FeuilleArrivee = ThisWorkbook.Worksheets(CStr(Annee)) End If For lig = LBound(DonneesInitiales) To UBound(DonneesInitiales) If DonneesInitiales(lig, 3) = Annee Then ReDim Preserve DonneesFiltrees(4, 1 To Indice) For col = 0 To 3 DonneesFiltrees(col, Indice) = DonneesInitiales(lig, col + 1) Next col Indice = Indice + 1 End If Next lig With FeuilleArrivee .Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(UBound(DonneesFiltrees, 2), UBound(DonneesFiltrees, 1) + 1) = Application.Transpose(DonneesFiltrees) End With Next Annee MsgBox Timer - t End Sub Function FeuilleExiste(wk As Workbook, stFeuille) As Boolean 'http://www.developpez.net/forums/d269391/logiciels/microsoft-office/excel/macros-vba-excel/vba-e-feuille-existe/ On Error Resume Next FeuilleExiste = Not (wk.Sheets(stFeuille) Is Nothing) End Function Sub tri(a, gauc, droi) 'http://boisgontierjacques.free.fr/pages_site/Dictionnaire.htm Dim ref, g, d, temp ref = a((gauc + droi) \ 2) g = gauc: d = droi Do Do While a(g) < ref: g = g + 1: Loop Do While ref < a(d): d = d - 1: Loop If g <= d Then temp = a(g): a(g) = a(d): a(d) = temp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call tri(a, g, droi) If gauc < d Then Call tri(a, gauc, d) End Sub
Quoique je reste persuadé que l'on peux encore faire mieux.......
A suivre!
-
-