Copier une colonne sous conditions d'une autre colonne

Copier une colonne sous conditions d'une autre colonne - VB/VBA/VBS - Programmation

Marsh Posté le 27-10-2014 à 10:28:44    

Bonjour
 
Je débute en VBA Excel et malgré toutes mes recherches sur internet je ne m'en sort pas
Si une âme charitable pouvez m'indiquer ce qui ne va pas dans mon code
 
J'ai un tableau avec une colonne A,B,C,D
 
Dans une autre feuille, il faudrait  que je reformate mon tableau  
Les colonnes A et B ne change pas; C'est de la recopie de ce coté ça va, mon code marche
Par contre pour les nouvelles colonnes C et D, il faut que :
dans mon nouveau tableau, la colonne D du tableau source soit répartie dans 2 colonnes, une colonne C et D selon la lettre qui est écrit dans mon tableau source dans la colonne C. (Si dans tableau source  colonne C ="D" alors mettre les chiffres de la colonne D dans la nouvelle colonne C et si  la colonne C="C" alors mettre les chiffres de la colonne D dans la nouvelle colonne D)
 
Voilà le code que j'ai fais pour l'instant qui me copie bien les colonnes A et B mais qui me recopie en colonne C et D toutes les données sans distinction. Je n'arrive pas à ce que ces 2 colonnes soient remplies selon la propriété de la colonne C du  tableau source.
 

Citation :


 
1. Sub Tableau()
2.
3. 'COPIE COLONNE A
4. Sheets("BMM" ).Select 'selectionner  feuille ma source
5. Range("A1" ).Select 'selectionner cellule
6.  Range(Selection, Selection.End(xlDown)).Select 'selectionner toute la colonne
7. Selection.Copy
8. Sheets("FINAL" ).Select 'selectionner feuille Final
9. Range("A1" ).Select
10. ActiveSheet.Paste
11.
12. 'COPIE COLONNE B
13. Sheets("BMM" ).Select 'selectionner  feuille ma source
14. Range("B1" ).Select 'selectionner cellule
15. Range(Selection, Selection.End(xlDown)).Select 'selectionner toute la colonne
16. Selection.Copy
17. Sheets("FINAL" ).Select 'selectionner feuille Final
18. Range("B1" ).Select
19. ActiveSheet.Paste
20.
21. 'NOUVELLE COLONNE C
22. Sheets("BMM" ).Select 'selectionner  feuille ma source
23. Range("D1" ).Select 'selectionner cellule
24. Range(Selection, Selection.End(xlDown)).Select 'selectionner toute la colonne
25. If Range("C1" ).Value = "D" Then Range("D1" ).Selection.Select
26. Selection.Copy
27. Sheets("FINAL" ).Select 'selectionner feuille Final
28. Range("C1" ).Select
29. ActiveSheet.Paste
30.
31.'NOUVELLE COLONNE D
32. Sheets("BMM" ).Select 'selectionner  feuille ma source
33. Range("D1" ).Select 'selectionner cellule
34. Range(Selection, Selection.End(xlDown)).Select 'selectionner toute la colonne
35. If Range("C1" ).Value = "D" Then Range("D1" ).Selection.Select
36. Selection.Copy
37. Sheets("FINAL" ).Select 'selectionner feuille Final
38. Range("D1" ).Select
39. ActiveSheet.Paste
40.
41. End Sub


Par avance merci pour votre aide
 
Isabelle


Message édité par isalili le 28-10-2014 à 07:53:53
Reply

Marsh Posté le 27-10-2014 à 10:28:44   

Reply

Marsh Posté le 27-10-2014 à 18:30:52    

 
           Bonjour, bonjour !
 
           Vu la foultitude de réponses, merci de se corroborer aux règles du forum
           en commençant par éditer le message et de baliser le code grâce à l'icône dédiée …
 
           Sinon une des possibilités seraient de filtrer la colonne C sur chacune des lettres pour effectuer la copie.
 

Reply

Marsh Posté le 28-10-2014 à 07:59:26    

Bonjour
 
Désolé mais j'avais lu les règles du forum et je pensais m'y être conformée.
La seule règle qui était du chinois pour moi (et oui je ne suis qu'un simple mortel) c'était la règle 14.
En parcourant le forum, j'ai vu que beaucoup mettait le code en citation avec un nombre devant les lignes.
J'ai corrigé mon post j'espère que celui ci est conforme maintenant.
 
Merci pour votre possibilité de filtrer la colonne C, je vais essayer de faire comme cela.
 
Isabelle

Reply

Marsh Posté le 28-10-2014 à 10:15:34    

 
           En fait il n'y a pas besoin d'une citation vu l'icône dédiée spécifiquement au code
           se chargeant automatiquement de la numérotation des lignes ! Dommage et, qui plus est,
           une autre manière consistant à taper manuellement les balises est pourtant décrite dans les règles du forum …
 
           Bref, les lignes n°4 à 10 peuvent se réduire à une seule ligne de code !
           D'une manière générale pour un code efficace, lire cette p'tite leçon et ce récapitulatif
           En fait, les lignes n°13 à 19 peuvent donc être aussi réduites dans cette même ligne de code
           car pourquoi copier séparément les colonnes A et B au lieu de les copier directement ensemble ?!
           Donc lignes n°4 à 19 : une seule ligne de code est nécessaire …
 
           Commentaire de la ligne n°6 : « selectionner toute la colonne »
                                                        Et non ! Car techniquement, c'est une partie de la colonne :
             celle délimitée entre le point de départ et la dernière saisie avant la première cellule vide.
             Si après cette cellule vide il y a d'autres saisies, elles ne sont donc pas prises en compte …
 
           D'une manière générale, comme indiqué dans le récapitulatif en lien ci-dessus, si l'intégralité des données est d'un seul bloc
           (donc sans colonne ni ligne vide), mieux vaut utiliser les propriétés CurrentRegion, Columns, Rows, Count
           Voir l'aide intégrée au VBA, tout y est !
 
           A partir de la ligne n°21, effacer tout ‼
           Oui car entre la ligne n°23 sélectionnant la cellule D1 puis la n°25 si la condition est remplie
           « tente de sélectionner la sélection de D1 » (traduction littérale du code) déclenche une erreur !
           Sans compter la logique inexistante par rapport au besoin …
           
           En résumé, une ligne de code est nécessaire pour copier les colonnes A & B.
           Pour les colonnes C & D, parcours des cellules avec une boucle For ou For Each (tout dépend s'il y a des titres ou pas)
           puis test avec un simple If pour alimenter une colonne finale …
 
           Ce genre de question se retrouve à la pelle un peu partout sur le net …
 
           Une présentation claire et exhaustive est nécessaire pour apporter une réponse technique.
           Sans tous les tenants et les aboutissants …
           
           Ce qui aurait dû être précisé initialement :
 
           • Deux feuilles : certes mais du même classeur ou pas ?
           • Où se trouve le code ? Dans quel classeur, celui d'une des feuilles, si oui, laquelle ? etc …
           • Données sources : en un seul bloc ou pas ? Ligne de titre ou pas ?
           • La feuille de destination contient-elle déjà des données et si oui, faut-il les conserver ou pas ? etc …
 
           A suivre …
 
           _________________________________________________________________________________________________________
           Il n'y a pas que les aigles qui atteignent les sommets, les escargots aussi mais ils en bavent !

 

Reply

Marsh Posté le 28-10-2014 à 17:33:44    

Merci beaucoup pour vos explications
 
J'ai déjà rectifié mon code des colonnes A et B selon vos recommandations et c'est bon, mes lignes 1a 19 sont donc devenus
 

Code :
  1. Sub Tableau()
  2. 'COPIE COLONNE A et B
  3. Sheets("BMM" ).Select 'selectionner  feuille ma source
  4.     Range("A2", [B2].End(xlDown)).Select 'selectionner cellule
  5.     Selection.Copy
  6.     Sheets("FINAL" ).Select 'selectionner feuille Final
  7.     Range("A1" ).Select
  8.     ActiveSheet.Paste
  9. End Sub


 
Je travaille maintenant sur la boucle, sachant que  
- Oui deux feuilles dans le même classeur
- Les données source sont des données brutes CSV donc pas de titre
- La feuille FINAL n'a aucune donnée, elle sert à récupérer les données de la macro
 
           Il n'y a pas que les aigles qui atteignent les sommets, les escargots aussi mais ils en bavent !  Cà c'est bien vrai
 
Isabelle

Reply

Marsh Posté le 28-10-2014 à 18:29:50    

 
           C'est mieux mais comme un bon code n'a pas besoin de Select et en lisant l'aide de la méthode Copy
           associée à un Range, une seule ligne de code est nécessaire pour les colonnes A et B !

Code :
  1. Worksheets("BMM" ).Cells(1).CurrentRegion.Columns("A:B" ).Copy Worksheets("FINAL" ).Cells(1)


 
           Sinon pour la globalité, voici la méthode la plus rapide via des variables tableau,
           code non testé car sans classeur de données en support …

Code :
  1. Sub Demo()
  2.     Dim TF()
  3.     With Worksheets("BMM" ).Cells(1).CurrentRegion
  4.         TF = .Columns("A:B" ).Value
  5.         VA = .Columns("C:D" ).Value
  6.         N& = .Rows.Count
  7.     End With
  8.     ReDim TF(1 To N, 1 To 4)
  9.     For R& = 1 To N
  10.         If VA(R, 1) = "C" Then
  11.             TF(R, 4) = VA(R, 2)
  12.         ElseIf VA(R, 1) = "D" Then
  13.             TF(R, 3) = VA(R, 2)
  14.         End If
  15.     Next
  16.     Worksheets("FINAL" ).[A1:D1].Resize(N).Value = TF
  17.     Erase TF, VA
  18. End Sub


           _________________________________________________________________________________________________________
           L'effort fait les forts.

 

Reply

Marsh Posté le 29-10-2014 à 08:39:14    

Un super grand merci pour votre code qui marche impec et qui va bien me faciliter la vie.
 
Isabelle

Reply

Marsh Posté le 29-10-2014 à 09:41:50    

 
          http://forum-images.hardware.fr/images/perso/actikool.gif
 
           Dans le cas de données sources pro où il y a forcément en colonne C soit la lettre "C" soit "D",
           les lignes n°12 à 18 peuvent se réduire ainsi :

Code :
  1. For R& = 1 To N:  TF(R, 3 - (VA(R, 1) = "C" )) = VA(R, 2):  Next


 
           Mais il y a mieux ! Hier j'étais un peu pressé et j'ai dû vouloir utiliser toutes les propriétés indiquées dans mon premier message …
           En réfléchissant au problème, mieux vaut utiliser une seule variable tableau contenant les colonnes sources
           en réorganisant les colonnes C & D, produisant alors un code réduit à l'essentiel :

Code :
  1. Sub Demo2()
  2.     VA = Worksheets("BMM" ).Cells(1).CurrentRegion.Columns("A:D" ).Value
  3.     For R& = 1 To UBound(VA)
  4.         If VA(R, 3) = "C" Then VA(R, 3) = "" Else VA(R, 3) = VA(R, 4): VA(R, 4) = ""
  5.     Next
  6.     Worksheets("FINAL" ).[A1:D1].Resize(UBound(VA)).Value = VA
  7.     Erase VA
  8. End Sub


           A comparer avec le code du premier message …
 
           Ceci dit, je ne critique pas l'utilisation du Générateur de macros, je l'encourage même !
           Formidable outil pour les débutants et même pour les chevronnés pour se remémorer le fonctionnement interne d'Excel …
 
           Mais une fois un code ainsi obtenu, ne pas hésiter à l'améliorer avec une logique "objet" et en consultant l'aide VBA,
           exemple d'un de mes liens dans mon premier message comme dans ce cas avec la méthode Copy,
           une seule ligne remplaçant les lignes sources n°4 à 19 rendant ainsi le code bien plus efficace …
 
          _________________________________________________________________________________________________________
           Le savoir est la seule matière qui s'accroit quand on la partage. (Socrate)

 

Reply

Marsh Posté le 29-10-2014 à 11:10:37    

Encore un grand merci, ce nouveau code marche et m'évite de fastidieuse manipulation que je faisais à la main.
 
Ca faisait plusieurs jours que j'essayais de m'en sortir par moi même mais je ne serais jamais arrivé à votre code.
 
 

Reply

Marsh Posté le 29-10-2014 à 15:10:12    

 
           Une dernière remarque : si dans la feuille source il n'y a que quatre colonnes ou si la colonne E est vide,
           alors il est inutile dans la ligne n°2 du dernier code de préciser .Columns("A:D" )
           la propriété CurrentRegion renvoyant uniquement ces quatre colonnes …
 
          _________________________________________________________________________________________________________
           L'expérience, c'est une connerie par jour, mais jamais la même …

 

Reply

Marsh Posté le 29-10-2014 à 15:10:12   

Reply

Marsh Posté le 29-10-2014 à 18:17:18    

Oui la colonne E est vide, je vais modifier le code  
 
Merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed