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

nikonoel

Nouveau membre
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 :
[cpp]
Range("A3").Select
Range(Selection, Selection.End(xlDown)).Select
Range("A3:C24").Select[/cpp]

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 !
 

zeb

Modérateur
Meilleure réponse
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 :

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 :
Code:
Object.Select
Slection.Action
Transforme-le directement en :
Code:
Object.Action
Ça fait, pour les deux premières lignes de ton code :
Code:
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 :
Code:
Range("A1:B3").Select
Selection.Copy
Sheets("Feuil2").Activate
Range("C4").Select
ActiveSheet.Paste
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 :
Code:
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 :
Code:
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 :
Code:
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 :
Code:
Dim ws_source As Worksheets
Dim ws_target As Worksheets
Dim cell_source_1er As Range
Dim cell_source_der As Range
Dim cell_target As Range777

Set ws_source = Worksheets("Feuil1")
Set ws_target = Worksheets("Feuil2")

Set cell_source_1er = ws_source.Range("A3")
Set cell_source_der = cell_source_1er.End(xlDown)
Set cell_target = ws_target.Range("X12")

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 ?
 

nikonoel

Nouveau membre
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 !
 

zeb

Modérateur
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 :
Code:
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 :
Code:
Set cell_source_1er = ws_source.Range("A3" )
Set cell_source_der = cell_source_1er.End(xlDown).Offset(0, 2)

MsgBox ws_source.Range(cell_prems, cell_source_der).Address
 

QSE

Nouveau membre
est ce que je peux avoir ton adresse e-mail pour te poser des questions concernant les macros
 

zeb

Modérateur
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.
 

juso

Nouveau membre
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.

 

zeb

Modérateur
Salut Juso,

Je te propose de potasser ce topic :


Je pense que tu as été assez clair. Et moi ?
 

juso

Nouveau membre
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 :

Code:
ActiveCell.SpecialCells(xlLastCell).Select
ActiveCell.FormulaR1C1 = "=ROW(RC)"
NumLigne = ActiveCell

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

 

zeb

Modérateur
Aïe !
Relis ce que je dis à Nikonoel à propose des Select et autres ActiveCell.
Sinon, à bientôt :hello:
 

juso

Nouveau membre
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 !
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 055
Membres
1 586 282
Dernier membre
Yannick3553
Partager cette page
Haut