Vous utilisez un navigateur non à jour ou ancien. Il ne peut pas afficher ce site ou d'autres sites correctement. Vous devez le mettre à jour ou utiliser un navigateur alternatif.
C'est possible et facile à faire en VBA.
Et comme en posant ta question dans le forum programmation, tu t'adresses ici à des personnes qui ne font rien qu'en programmant, une seule réponse : OUI.
Avant même que tu ne te plonges dans le VBA je vais te donner une piste.
La commande que tu cherches s'appelle copy.
Pour commencer, démarre l'enregistreur de macro, et fais à la main ce que tu cherches à faire faire par la macro. Du code (tout pourri) va s'enregistrer. Essaie de le comprendre avec l'aide de l'aide en ligne.
Dès que tu bloques, viens nous voir. On a des trucs à te montrer
--------------
Attention, le modo est chiant sur un point : il faut utiliser la balise
L'enregistreur me donne cette structure.
J'ai donc multiplier ces actions par 7 pour effectuer toutes les copies.
Mais sur les colonnes à copier seule la 1ère se copie normalement, pour les 6 autres il sélectionne bien la colonne d'arrivé mais il n'y copie rien.
Second soucis, je copie la colonne du fichier source sans l'en-tête pour la copier à partir de la 3eme ligne de la colonne cible.
-> Erreur de taille entre les 2 objets :
-------------
Si le modo voit que t'as utilisé [quote] au lieu de [code], ça va barder.
Modifie ton message : clique sur le petit crayon en bas à droit de ton message.
Comme le modo, c'est moi, j'ai plein de droits ! Dont celui de modifier vos messages (c'est fou non ?!) J'en ai abusé. Regarde j'ai ajouté =vb dans tes balises =>
Code:
et c'est tout de suite tellement plus joli.
;)
-------------------------
Or donc, je regarde ton code, et j'y vois une certaine logique.
Tu sélectionnes (Select) un truc, tu copies (Copy <-- ne t'en avais-je pas parlé ? ;) ) et tu colles (Paste).
Ça semble logique.
Avant de le faire 7 fois, on va le faire 1 fois correctement.
En lignes 1 et 2, tu sélectionnes un truc, puis t'en sélectionnes un autre. A mon avis, tu aurais pu t'économiser une étape.
Tiens des devoirs à la maison : lis l'aide sur [b]Range()[/b], [b]End()[/b] et [b]Copy()[/b].
Regarde surtout le paramètre de [b]Copy()[/b].
Mais dorénavant la fin du code est devenue obsolète , Erreur 9 l'indice n'appartient pas à la selection. Alors que je n'ai toujours pas rajouté la contrainte du décallage d'une ligne entre Fichier 1 et 2.
D'abord, on revoit ton code.
J'y vois deux erreurs, que l'enregistreur de macro t'a fait faire.
La première, c'est de se servir du presse-papier comme variable temporaire.
Le presses-papier ne doit être utilisé que par l'utilisateur et à son initiative.
Imagine un peu si tous les programmes s'en servaient à leur guise !
Donc pour ça, il y a une solution - mainte fois discutée sur ce forum, dont je t'ai déjà donné une piste.
As-tu lu l'aide sur copy() ?
L'autre erreur, c'est de sélectionner un truc, pour ensuite agir sur la sélection. Autant directement agir sur le truc. T'as compris ? t1cable: t1cable: t1cable: (moi non plus !)
Alors je te donne un exemple :
Code:
' // Pas bon
Range("R2").End(xlDown).Select
Selection.Copy
' // Bien :
Range("R2").End(xlDown).Copy
C'est mieux, non.
Il y a un autre problème. C'est l'utilisation de la fonction Windows() qui dépend du nombre de fois qu'on a ouvert un même document. Il faut proscrire son utilisation.
A la place, on utilisera l'objet Workbook qui représente un classeur.
Comme on jongle avec plusieurs classeurs, plusieurs feuilles et plusieurs plages de cellules, on va être explicite et tout préciser :
Code:
Dim cellule1 As Range
Dim cellule2 As Range
Set cellule1 = Workbook("nom du classeur source").Worksheets(1).Range("R2")
Set cellule2 = Workbook("nom du classeur source").Worksheets(1).Range("R2").End(xlDown)
Workbook("nom du classeur source").Worksheets(1).Range(cellule1, cellule2).Copy
Workbook("nom du classeur destination").Worksheets(1).Range("Y2").End(xlDown).Paste
Bon, il y a trop de répétitions dans ce code. C'est moche.
Code:
Dim wk_source As Workbook
Dim wk_cible As Workbook
Dim ws_source As Worksheet
Dim ws_cible As Worksheet
Dim rg_source as Range
Dim rg_cible as Range
Set wk_source = Workbooks("nom du classeur source")
Set wk_cible = Workbooks("nom du classeur cible")
Set ws_source = wk_source.Worksheets(1)
Set ws_cible = wk_cible.Worksheets(1)
Set rg_source = ws_source.Range(ws_source.Range("R2"), ws_source.Range("R2").End(xlDown))
Set rg_cible = ws_cible.Range("Y2").End(xlDown)
rg_source.Copy
rg_cible.Paste
Regarde bien ce code. Il est trop détaillé, mais très didactique.
Voici une version plus condensée :
Code:
Dim ws_source As Worksheet
Dim ws_cible As Worksheet
Set ws_source = Workbooks("nom du classeur source").Worksheets(1)
Set ws_cible = Workbooks("nom du classeur cible").Worksheets(1)
ws_source.Range(ws_source.Range("R2"), ws_source.Range("R2").End(xlDown)).Copy
ws_cible.Range("Y2").End(xlDown).Paste
Tu suis ?
Alors si on relis l'aide de la commande Copy, comment améliorer ce code ?
(OUI JE SAIS, TU AS UN PROBLEME DE TAILLE DE COLONNE, ON VA Y VENIR)
Dim ws_source As Worksheet
Dim ws_cible As Worksheet
Set ws_source = Workbooks("nom du classeur source").Worksheets(1)
Set ws_cible = Workbooks("nom du classeur cible").Worksheets(1)
ws_source.Range(ws_source.Range("R2"), ws_source.Range("R2").End(xlDown)).Copy _
Destination:=ws_cible.Range("Y2").End(xlDown)
Après j'ai pensé à ... sans grande conviction mais ça me paraissait pas mal :
Code:
Dim ws_source As Worksheet
Dim ws_cible As Worksheet
Set ws_source = Workbooks("nom du classeur source").Worksheets(1).Range(("R2"),("R2")).End(xlDown)
Set ws_cible = Workbooks("nom du classeur cible").Worksheets(1).Range(("Y2"),("Y2")).End(xlDown)
ws_source.Copy _
Destination:=ws_cible
Yiiiiha !
T'as tout compris. Le fait d'utiliser une destination avec Copy permet de ne pas toucher au presse-papier.
-------------
Range(("R2"),("R2")).End(xlDown)
Ça, ça ne veut rien dire.
End(xlDown) permet, partant d'une cellule, d'aller à la dernière (End) cellule du même bloc de cellules, vers le bas (...je te laisse deviner...).
Donc il faut l'appliquer à une cellule.
Range() permet de désigner une plage de cellules, cette plage pouvant être réduite à 1 cellule. Range() s'applique à une feuille ou à un autre plage de cellule.
objet.Range(("R2"),("R2")) Mets autant de parenthèses inutiles que tu veux, c'est comme en maths, si ça sert à rien, ça ne gêne pas.
Ce que tu écris revient à : objet.Range("R2","R2")
Et "R2" dans un Range(..) revient à dire : ActiveSheet.Range("R2")
Or si l'objet n'est pas la feuille active ou une plage de la zone active, ça va planter : objet1.Range(objet2.Range("R2"), objet3.Range("R2"))
Il faut écrire : objet.Range(objet.première_cellule, objet.dernière_cellule)
Tu sais que Range("R2") est ta première cellule.
Tu calcules que Range("R2").End(...) est ta dernière cellule.
Donc tu copies toute la plage : Range(Range("R2"), Range("R2").End(...)).Copy ...
Puisqu'on jongle avec plusieurs classeurs et plusieurs feuilles, on précise : mafeuille1.Range(mafeuille1.Range("R2"), mafeuille1.Range("R2").End(...)).Copy destination:=mafeuille2.première_cellule
T'as compris ? (moi, en me relisant, je m'y pers un peu)
-------------
Si oui, passons à la taille de la colonne.
1°) Ouvre un classeur plein de colonnes qui ne sont pas à la bonne taille.
2°) Démarre l'enregistreur de macro
3°) Mets une colonne à la bonne taille
4°) Arrête l'enregistreur de macro
5°) Va lire le code enregistré
6°) Reste dubitatif devant le code pendant quelques instants
7°) Publie-le ici qu'on rigole
"[Question_Bete=On]
Par contre je ne comprends pas bien comment je peux mettre une colonne à la bonne taille;
cela équivaut à sélectionner le bon nombre de cellule correspondant à la bonne taille?
[Question_Bete=Off]"
Edit :
J'obtiens donc quelque chose mais sans certitude !
1°) Le Môssieu te demande de ne pas faire de Select, de ne pas utiliser Selection.
[:zeb:4]
2°) Qu'est-ce que ClearContents vient-il faire là ?
:heink:
Qu'est-ce que tu appelles mettre une colonne à la bonne taille ?
:??:
-----------------------------
Pour "mettre une colonne à la bonne taille", je double-clique sur le bord droit de l'entête de la colonne.
Et ça fit la colonne automatiquement
:spamafote:
Quand je parlais d'un problème de taille de colonne, c'étais le nombre de cellule.
Quand je sélectionne toutes les cellules de la colonne A et que je souhaite les copier dans la colonne B mais a partir de la cellule 2 => Problème de taille ma colonne ne peut s'insérer.
Ah, oki. La solution est pourtant dans ce que je t'ai écrit. Je viens de relire l'aide d'Excel. Le baratin te conforte dans ton erreur, l'exemple, lui est correct.
Pour copier une plage de cellules vers une autre, il faut donner exactement la plage à copier, et soit donner une zone exactement de la même taille, soit ne donner que la première cellule.
J'ai contourné le problème en rajoutant une ligne.
Mais après la copie des colonnes je souhaitais qu'Excel me remplisse automatiquement des colonnes avec des constantes. J'ai donc réaliser une boucle For pour parcourir le bon nombre d'itération.
Mais j'ai deux problèmes :/
1) Rien ne s'ecrit dans les colonnes :x
2) Quand j'adresse les coordonnées des cellules, j'ai une erreur si je dépasse la colonne C ( 3 )
cells(i,1) et cells(i,2) compilent, mais lorsque je passe à cells(i,3) j'ai l'erreur 1004
Code:
Sub test()
Dim ws_source As Worksheet
Dim ws_cible As Worksheet
Dim i As Integer
Dim x As Long
Set ws_cible = Workbooks("f13").Worksheets(1)
Set ws_source = Workbooks("Macro_AVEX").Worksheets(1)
'Je compte le nombre de ligne de mon fichier source
x = WorksheetFunction.CountA(ws_source.Columns(1))
'Pour compenser la taille de la colonne on ajoute une ligne au fichier source
ws_source.Rows("1:1").Insert Shift:=xlDown
'Certaines colonnes sont à remplir avec des constantes , et une colonne avec une incrémentation (numéro de ligne )
For i = 1 To x + 2
ws_cible.Range(Cells(i, 2)).Value = "YA6"
ws_cible.Range(Cells(i, 5)).Value = "09-00"
ws_cible.Range(Cells(i, 7)).Value = "09-00"
ws_cible.Range(Cells(i, 24)).Value = i - 2
Next
'Copie des 7 colonnes dans le fichier cible
ws_source.Range(ws_source.Range("R3"), ws_source.Range("R3").End(xlDown)).Copy Destination:=ws_cible.Range("Y3")
ws_source.Range(ws_source.Range("V3"), ws_source.Range("V3").End(xlDown)).Copy Destination:=ws_cible.Range("Z3")
ws_source.Range(ws_source.Range("U3"), ws_source.Range("U3").End(xlDown)).Copy Destination:=ws_cible.Range("AA3")
ws_source.Range(ws_source.Range("W3"), ws_source.Range("W3").End(xlDown)).Copy Destination:=ws_cible.Range("AB3")
ws_source.Range(ws_source.Range("S3"), ws_source.Range("S3").End(xlDown)).Copy Destination:=ws_cible.Range("AC3")
ws_source.Range(ws_source.Range("AC3"), ws_source.Range("AC3").End(xlDown)).Copy Destination:=ws_cible.Range("AI3")
ws_source.Range(ws_source.Range("AD3"), ws_source.Range("AD3").End(xlDown)).Copy Destination:=ws_cible.Range("AJ3")
End Sub
Une petite idée du pourquoi du comment ? je m'arrache les cheveux depuis pas mal de temps sans pouvoir expliquer l'apparition de l'erreur et pourquoi rien ne s'écrit.