Se connecter avec
S'enregistrer | Connectez-vous
Votre question
Résolu

Macro Excel: sélection d'un tableau selon sa longueur variable

Tags :
  • Enregistreur
  • Programmation
  • VB
Dernière réponse : dans Programmation
Partagez
12 Août 2010 12:03:13

Bonjour à tous,

Je suis en train de tenter de créer une macro pour mon travail. Le but est de copier un tableau et de le mettre dans une autre feuille (entre autre). Le souci est que le nombre de lignes de mon tableau est variable. Pour l'instant, en enregistrant ma macro grâce à l'utilitaire d'Excel j'obtiens le code suivant :
  1. Range("A3").Select
  2. Range(Selection, Selection.End(xlDown)).Select
  3. Range("A3:C24").Select


Cela ne me convient pas, car j'aimerais que C24 puisse aussi être C12, C87 ou encore C2398, etc... selon le nombre de lignes de mon tableau.

De la même manière, je cherche à sélectionner une seule colonne (ex : A3:A24) selon le nombre de lignes remplies qui est variable.

Merci d'avance de votre aide !

Autres pages sur : macro excel selection tableau longueur variable

Meilleure solution

a b L Programmation
12 Août 2010 16:54:52

Salut,

Se servir de l'enregistreur et adapter le code obtenu est une excellente chose. Mais l'on est vite limité si l'on ne connaît pas ni le VB, ni les objets VBA spécifiques à Excel.

Je t'invite tout d'abord à lire cet article : http://www.presence-pc.com/forum/ppc/Programmation/vous...

Revenons à ton code.
Tu sélectionnes telle cellule à seule fin de t'en servir pour définir telle autre. C'est peu productif. Par principe, dès que tu vois le code suivant :
  1. Object.Select
  2. Slection.Action
Transforme-le directement en :
  1. Object.Action

Ça fait, pour les deux premières lignes de ton code :
  1. Range(Range("A3" ), Range("A3" ).End(xlDown)).Select


Bon, là encore, il y a un Select. Je parie que tu ne peux rien sélectionner, mais juste référencer la zone.

Voici un exemple pour copier une zone, tel que l'enregistreur le code :
  1. Range("A1:B3").Select
  2. Selection.Copy
  3. Sheets("Feuil2").Activate
  4. Range("C4").Select
  5. ActiveSheet.Paste
  6. Application.CutCopyMode = False

Que c'est laid : D'une part on sélectionne des tas de cellules pour rien, il suffisait de les désigner sans les sélectionner, et d'autre part, on abuse du presse-papier qui est une zone de mémoire à disposition de l'utilisateur, certainement pas des programmes. Imagine que plusieurs programmes, pour leur besoin interne, passent par le presse-papier en même temps. Quelle pagaille en perspective !

Donc supprimons et les sélections et l'usage du presse-papier :
  1. Range("A1:B3").Copy Sheets("Feuil2").Range("C4")

Et oui, c'est tout. Bon, quand on jongle avec plusieurs feuilles, il est de bon ton de les préciser à chaque fois, en ne considérant que les feuilles de calcul, de surcroît :
  1. Worksheets("Feuil2").Range("A1:B3").Copy Worksheets("Feuil2").Range("C4")


Revenons maintenant à ton cas. Tu veux copier une zone de la feuille 1 (hypothèse) qui commence à une cellule donnée (A3), qui finit vers le bas dès qu'on trouve une ligne vide (End(xlDown)) vers une cellule (X42 - hypothèse) de la feuille 2 (hypothèse).

C'est parti :
  1. Worksheets("Feuil1").Range(Worksheets("Feuil1").Range("A3"), Worksheets("Feuil1").Range("A3").End(xlDown)).Copy Worksheets("Feuil2").Range("X12")


Bon, c'est un peu lourd comme écriture ! On va alléger ça en mettant des variables :
  1. Dim ws_source As Worksheets
  2. Dim ws_target As Worksheets
  3. Dim cell_source_1er As Range
  4. Dim cell_source_der As Range
  5. Dim cell_target As Range777
  6.  
  7. Set ws_source = Worksheets("Feuil1")
  8. Set ws_target = Worksheets("Feuil2")
  9.  
  10. Set cell_source_1er = ws_source.Range("A3")
  11. Set cell_source_der = cell_source_1er.End(xlDown)
  12. Set cell_target = ws_target.Range("X12")
  13.  
  14. ws_source.Range(cell_prems, cell_source_der).Copy cell_target


En étudiant ce code, tu conviendras que la préparation est un peu laborieuse, mais dans un programme un peu plus long, d'un part ce sera plus facile à relire, et d'autre part, il est fort probable que tu n'ais pas à refaire certains calculs.

Cela t'aide-t-il ?
partage
12 Août 2010 17:26:17

En effet, ça m'aide ! Merci pour ta réponse claire et bien expliquée.

Quant au lien que tu m'as donné, je l'ai trouvé après avoir posté et j'ai déjà commencé à en appliquer le premier conseil : découper ma grosse macro en plusieurs petites macros dont je peux comprendre le code. :) 

Petite question supplémentaire (désolé si j'abuse de ta gentillesse et de celle des autres sur le forum, si je n'obtiens pas de réponse je persévérerai de mon côté :whistle:  ) : comment pourrait-on faire en sorte de copier également la colonne B et C en même temps ? Je veux dire par là étendre la zone à copier à deux colonnes vers la droite.

Par exemple, si mon tableau descend jusqu'à la ligne 24 j'aimerais pouvoir copier les cellules (A3:C24) en une seule fois...

Encore merci pour toutes tes explications !
m
0
l
Contenus similaires
a b L Programmation
16 Août 2010 11:28:50

Salut,

Petite réponse supplémentaire :
1°) Tu n'abuses pas ;) 
2°) La zone à copier est définie par les deux cellules cell_source_1er et cell_source_der.
Vois ce que nous avons défini :
  1. MsgBox ws_source.Range(cell_prems, cell_source_der).Address


Il faudrait donc décaler de deux colonnes d'une des deux bornes (un décalage se dit offset en anglais).

En VB aussi :
  1. Set cell_source_1er = ws_source.Range("A3" )
  2. Set cell_source_der = cell_source_1er.End(xlDown).Offset(0, 2)
  3.  
  4. MsgBox ws_source.Range(cell_prems, cell_source_der).Address
m
0
l
23 Août 2010 09:14:43

Meilleure réponse sélectionnée par nikonoel.
m
0
l
27 Septembre 2012 16:17:04

est ce que je peux avoir ton adresse e-mail pour te poser des questions concernant les macros
m
0
l
a b L Programmation
1 Octobre 2012 17:01:35

Plop,

Non.
Ce site a pour vocation de faire partager des questions et des réponses, formant des problèmes et leurs solutions.
Tout doit être publié ici.

Nous ne sommes pas un site de mise en relation.
m
0
l
26 Novembre 2012 15:29:10

Bonjour,

je débute dans les macros mais je ne désespère pas ^^
Par rapport au 1er problème exposé par nikonoel, j'ai une contrainte de plus : certaines cellules de mon tableau initial sont vides et je ne veux donc pas que la sélection s'arrête dès que j'ai une cellule vide, mais plutôt lorsque la dernière cellule utilisée est atteinte ... j'espère avoir été assez clair.

m
0
l
7 Décembre 2012 09:57:34

Bonjour,
J'avais déjà lu ce topic mais je pensais ne pas y trouver mon bonheur ...

Au final, j'ai relu et j'ai donc pu faire :

  1. ActiveCell.SpecialCells(xlLastCell).Select
  2. ActiveCell.FormulaR1C1 = "=ROW(RC)"
  3. NumLigne = ActiveCell


ça répond à ma demande ... donc merci beaucoup et à bientôt car j'ai plein d'autres questions ^^

m
0
l
a b L Programmation
7 Décembre 2012 10:05:42

Aïe !
Relis ce que je dis à Nikonoel à propose des Select et autres ActiveCell.
Sinon, à bientôt :hello: 
m
0
l
7 Décembre 2012 10:27:30

J'ai bien compris pour les Select et Selection (ce n'était pas très compliqué ^^) mais pour les autres améliorations, j'avoue que je nage encore .. je me sers beaucoup de l'enregistrement des manipulations en macro et je ne comprends pas encore toutes les lignes de code ... mais j'y travaille ^^

Merci encore !
m
0
l