XL 2013 copier/coller d une selection multiple

floreli

XLDnaute Nouveau
Bonjour a tous,
pour ce premier message, je fais appelle aux personnes qui maitrisent mieux que moi VBA...Je chercher depuis une semaine sans trouver ma reponse.

je cherche a copier/coller une selection multiple (qui sera toujours la meme) d un classeur 1 feuille 1 vers un classeur X feuille 1. Ce classeur X est exactement le meme que classeur 1 sauf que je ne connais pas son nom a l avance, et qu il est vide. Mais les 2 ont la meme structure, memes noms de feuillles, ....

Donc concretement, je veux faire ca :

1/je parts d un classeur vierge.
2/je le renomme sous un nom par exemple classeur 1. je remplis ce dont j ai besoin.je sauve.
3/je reouvre mon classeur vierge 1semaine apres, je le renomme sous un nom par exemple classeur 2, mais sans le remplir.
J ai maintenant mes 2 classeurs ouverts en meme temps.
4/et je veux copier/coller une selection multiple du classeur 1 feuille 1 vers mon classeur 2 feuille 1. (les 2 feuille1 des mes 2 classeurs ont la meme structure)

je veux juste coller les valeurs et je veux que les positions ou adresses (je ne sais pas comment ont dit) des mes cellules suivent, si par exemple je veux copier range("A10:A20,F10:CG35") alors que ca aille bien coller aux memes adresses A10:A20 et F10:CG35


j ai essayé pas mal de chose, Union, Array,. ... essayé bcp de code trouvés sur des forums, rien n y fait.....je n y arrive pas. (La solution qui consiste a copier toute la feuille et ensuite effacer ne me va pas)


je suis parti dans mon idée avec 2 macros, placées dans mon classeur initial (donc qui seront aussi dans tous les classeurs pas la suite). Une macro "Copier" et une macro"Coller". Quand j ai mes 2 fichiers ouverts, je selectionne la feuille 1 du classeur 1, j active la mcaro "Copier", je selectionne la feuille 1 de mon classeur 2 et j active la macro "Coller".


j ai approximativement 1000-1500 cellules a copier/coller.

voila, j espere avoir été precis.

voici une de mes tentatives qui ne marche pas "

VB:
Sub copier()

Dim plagesmulti As Range
Dim plage1, plage2, plage....... As Range
Dim sh As Worksheet

Set sh = ThisWorkbook.Worksheets("1")
Set plage1 = Range("A5:A20")
Set plage2 = Range("C22:F32")
.......

Set plages = Array(plage1, plage2,.......)
plages.select
selection.copy

End Sub



et ma macro "COLLER"

VB:
Sub coller()

Selection.PasteSpecial PASTE:=xlPasteValuesAndNumberFormats, Operation:= _
        xlNone, SkipBlanks:=False, Transpose:=False
        
            
End Sub


merci a tous, floreli
 

Dranreb

XLDnaute Barbatruc
Bonjour.
je veux juste coller les valeurs et je veux que les positions ou adresses (je ne sais pas comment ont dit) des mes cellules suivent, si par exemple je veux copier range("A10:A20,F10:CG35") alors que ca aille bien coller aux memes adresses A10:A20 et F10:CG35
Je dirais :
VB:
Sub ParExemple()
   CopieValeurs ActiveSheet, Workbooks(X).Worksheets(Y).[A10:A20,F10:CG35]
   End Sub
Sub CopieValeurs(ByVal WshDest As Worksheet, ByVal RngSrc As Range)
   Dim RngA As Range
   For Each RngA In RngSrc.Areas
      WshDest.Range(RngA.Address).Value = RngA.Value
      Next RngA
   End Sub
À tester.
 

floreli

XLDnaute Nouveau
merci pour ton aide Dranreb. Si je comprends bien cette procedure me selection et copie les plages definies et leurs "adresses", c est bien ca ?
il me reste ensuite a coller ?

j ai essayé de l imbriquer dans mon code mais je n y arrive pas. Pour faire l exemple, je copie/colle de la feuille1 vers la feuille2. (Je pense que le principe est le meme qu entre 2 classeurs ?!)
 

Pièces jointes

  • classeur1.xlsm
    26.6 KB · Affichages: 7

Dranreb

XLDnaute Barbatruc
Il n'existe pas de "Classeur1", il existe un "classeur1.xlsm". En remplaçant Workbooks("classeur1") par ThisWorkbook ça marche, depuis la feuille "2". Remarque les Copier et Coller ne sont plus distingués dans ma solution.
Si vous voulez les distinguer, notez par un Set, dans la partie qui copie, la plage à copier dans une variable globale As Range, voire Public, que vous transmettrez comme second argument au CopieValeurs dans la partie collage.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Comme ça par exemple :
VB:
Option Explicit
Private RngSrc As Range
Sub COPIER()
   Set RngSrc = ActiveSheet.[A5:A20,C22:F32]
   End Sub
Sub COLLER()
   If RngSrc Is Nothing Then MsgBox "Feuille source non définie", _
      vbCritical, "COLLER": Exit Sub
   CopieValeurs ActiveSheet, RngSrc
   Set RngSrc = Nothing
   End Sub
Sub CopieValeurs(ByVal WshDest As Worksheet, ByVal RngSrc As Range)
   Dim RngA As Range
   For Each RngA In RngSrc.Areas
      WshDest.Range(RngA.Address).Value = RngA.Value
      Next RngA
   End Sub
 

Dranreb

XLDnaute Barbatruc
Ou bien :
VB:
Option Explicit
Private WshSrc As Worksheet
Sub COPIER()
   Set WshSrc = ActiveSheet
   End Sub
Sub COLLER()
   If WshSrc Is Nothing Then MsgBox "Feuille source non définie", _
      vbCritical, "COLLER": Exit Sub
   CopieValeurs ActiveSheet, WshSrc.[A5:A20,C22:F32]
   Set WshSrc = Nothing
   End Sub
Sub CopieValeurs(ByVal WshDest As Worksheet, ByVal RngSrc As Range)
   Dim RngA As Range
   For Each RngA In RngSrc.Areas
      WshDest.Range(RngA.Address).Value = RngA.Value
      Next RngA
   End Sub
 

floreli

XLDnaute Nouveau
merci beaucoup pour votre aide !!! ca marche tres bien dans les 2 cas. C est exactement ce dont j ai besoin, mais entre 2 classeurs différents. car la évidemment entre 2 classeurs, quand je veux coller je me trouve sur ma feuille cible et donc la feuille source n est plus active....

je pensais pas que cela serait aussi compliqué....si ca peut faciliter la tache, le fait de copier coller entre 2 classeurs differents est le point clé indispensable mais par contre le fait de coller aux memes adresses, si il faut je pense que je peux me debrouiller sans, ca sera moins pratique mais je peux m en passer.

Merci beaucoup,
floreli
 

Dranreb

XLDnaute Barbatruc
Normalement ça n'a pas d'importance que le classeur source ne soit plus actif.
Sa feuille active avait été notée comme WshSrc, c'est tout ce qui compte. Par contre il faut bien veiller à ce que les macros COPIER et COLLER soit dans un seul classeur. Donc pour un des deux la macro affectée au bouton doit être celle de l'autre classeur. Ou alors mettez les macros dans un 3ième et affectez les à des commandes personnalisées du ruban.
 

floreli

XLDnaute Nouveau
Bonjour, alors je pense que je suis perdu...ou alors je ne comprends rien a rien....

Par contre il faut bien veiller à ce que les macros COPIER et COLLER soit dans un seul classeur.
=> dans un seul classeur ??
Donc pour un des deux la macro affectée au bouton doit être celle de l'autre classeur.
=> la j ai pas compris.

je resume ce que j ai fais :
j ai mis le meme code complet dans 2 classeurs differents, classeur 1 et classeur 2, et je veux copier/coller les plages (A5:A20;C22:F32) de la feuille 1 du classeur 1 vers la feuille 1 du classeur 2.

je mets le bouton copier dans le classeur source et le bouton coller dans le classeur cible.

j ouvre la feuille1 de mon classeur1 (source) et j actionne le bouton copier. A ce moment je definis cette feuille 1 classeur 1 comme WshSrc. jusque la ca va....

ensuite j ouvre ma feuille1 classeur2 qui est ma feuille cible, et j action le bouton coller. et la le message "feuille source non definie" apparait....


Ca marche par contre tres bien en copiant/collant entre 2 feuilles d un meme classeur.


j ai du mal a comprendre pourquoi c est si compliqué, j avais fait la meme macro avec une plage unique et ca ne m avait pas posé de probleme, mais la quelle galere....

pourquoi 2 macros du style ci dessous ne marchent pas ??

SUB copier ()
plages_multi = union(range("A5:A20") , range("C22:F32"))
plages_multi.select
selection.copy
end sub

SUB coller ()
selection.paste....
end sub


bref j ai tant de question, je ne sais pas par ou commencer....

Merci en tout cas pour votre aide
floreli
 

Dranreb

XLDnaute Barbatruc
Ce n'est pas compliqué: La feuille source a été notée lors du COPIER comme variable WshSrc dans le projet VBA d'un certain classeur.
Elle n'est donc connue que dans celui là et le COLLER doit donc aussi être une macro de ce classeur qui contient cette variable WshSrc. Peut importe dans lequel doit se trouver l'ensemble de cette programmation: Le classeur source, le classeur cible ou encore un troisième classeur de macros. Comme c'est le plus commode à lancer. On peut tout à fait affecter à un bouton de formulaire une macro d'un autre classeur.
On peut aussi lors de la copie afficher un petit UserForm non modal avec juste un bouton pour coller, une fois la feuille cible activée.
 

floreli

XLDnaute Nouveau
ok j ai compris, j arrive a faire fonctionner entre 2 classeurs. mais comme moi dans mon cas je parts toujours d un seul et meme classeur que je renomme, forcement les 2 macros sont dans ce classeur et se retrouvent ensuite dans tous mes classeurs renommés, et donc dans ma source et dans ma cible. Je ne peux pas a chaque fois aller reaffecter le COLLER de la source dans la cible, c est trop compliqué pour les gens qui utiliseront les fichiers au final.

On peut tout à fait affecter à un bouton de formulaire une macro d'un autre classeur
=> ok mais donc dans mon pas tres pratique je pense.
On peut aussi lors de la copie afficher un petit UserForm non modal avec juste un bouton pour coller, une fois la feuille cible activée.
=> Oui ca, ca me parait tres bien !!!

J ai essayé de faire moi meme, l userform souvre bien, mais rien ne se passe apres.
 

Pièces jointes

  • classeur1.xlsm
    26.3 KB · Affichages: 3

Dranreb

XLDnaute Barbatruc
Bonjour.
J'ai un souci avec mon système actuel: lorsque j'active un autre classeur, un UserForm affiché non modal est masqué. On peut contourner mais c'est un peu compliqué. Alors j'ai pensé à une autre solution :
VB:
Option Explicit
Private RngSrc As Range
Public Sub COPIER()
   Set RngSrc = ActiveSheet.[A5:A20,C22:F32]
   Application.OnTime Now + TimeSerial(0, 0, 5), "COLLER"
   End Sub
Public Sub COLLER()
   Dim WshCbl As Worksheet
   Set WshCbl = ActiveSheet
   Select Case MsgBox("Voulez vous coller dans '[" & WshCbl.Parent.Name & "]" & WshCbl.Name & "'" _
      & vbLf & "les données " & RngSrc.Address(False, False, xlA1, True) & " ?", vbYesNoCancel, "COLLER")
      Case vbYes: CopieValeurs WshCbl, RngSrc
      Case vbNo: Application.OnTime Now + TimeSerial(0, 0, 5), "COLLER"
      End Select
   End Sub
Private Sub CopieValeurs(ByVal WshDest As Worksheet, ByVal RngSrc As Range)
   Dim RngA As Range
   For Each RngA In RngSrc.Areas
      WshDest.Range(RngA.Address).Value = RngA.Value
      Next RngA
   End Sub
Vous avez ainsi 5 secondes pour activez la feuille du classeur cible après le COPIER, qui seul fait l'objet d'un bouton.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Il m'est venue une idée encore meilleure, c'est de mettre la quasi totalité du code dans un module objet tel que ThisWorkbook, mais tout autre conviendrait aussi: module d'objet Worksheet, module de classe mais dont il faudrait alors préalablement créer un exemplaire, voire un UserForm :
VB:
Option Explicit
Private RngSrc As Range, WithEvents AppXls As Application
Public Sub ProposerColler(ByVal Rng As Range)
   Set RngSrc = Rng
   Set AppXls = Application
   End Sub
Private Sub AppXls_WorkbookActivate(ByVal Wb As Workbook)
   AppXls_SheetActivate Wb.ActiveSheet
   End Sub
Private Sub AppXls_SheetActivate(ByVal Sh As Object)
   If TypeOf Sh Is Excel.Worksheet Then ConfirmerColler Sh
   End Sub
Private Sub ConfirmerColler(ByVal WshCbl As Worksheet)
   Select Case MsgBox("Voulez vous coller dans '[" & WshCbl.Parent.Name & "]" & WshCbl.Name & "'" _
      & vbLf & "les valeurs " & RngSrc.Address(False, False, xlA1, True) & " ?", vbYesNoCancel, "COLLER")
      Case vbYes: CopieValeurs WshCbl, RngSrc
      Case vbNo: Exit Sub
      End Select
   Set RngSrc = Nothing: Set AppXls = Nothing
   End Sub
Private Sub CopieValeurs(ByVal WshDest As Worksheet, ByVal RngSrc As Range)
   Dim RngA As Range
   For Each RngA In RngSrc.Areas
      WshDest.Range(RngA.Address).Value = RngA.Value
      Next RngA
   End Sub
Dans le module standard, la macro COPIER se réduit à ça :
VB:
Option Explicit
Public Sub COPIER()
   ThisWorkbook.ProposerColler ActiveSheet.[A5:A20,C22:F32]
   End Sub
Mais s'il n'y a qu'une feuille source possible dans chaque classeur, vous auriez intérêt à mettre tout le code dans le module de l'objet Worksheet qui la représente, avec, pour COPIER, un CommandButton ActiveX plutôt qu'un bouton de formulaire.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Le code dans le module de l'objet Worksheet de la feuille source, avec un CommandButton ActiveX nommé CBnCopier :
VB:
Option Explicit
Private WithEvents AppXls As Application
Private Sub CBnCopier_Click()
   Set AppXls = Application
   End Sub
Private Sub AppXls_WorkbookActivate(ByVal Wb As Workbook)
   AppXls_SheetActivate Wb.ActiveSheet
   End Sub
Private Sub AppXls_SheetActivate(ByVal Sh As Object)
   Dim WshCbl As Worksheet, RngSrc As Range, RngA As Range
   If TypeOf Sh Is Excel.Worksheet Then
      Set WshCbl = Sh: Set RngSrc = Me.[A5:A20,C22:F32]
      Select Case MsgBox("Voulez vous coller dans '[" & WshCbl.Parent.Name & "]" & WshCbl.Name & "'" _
         & vbLf & "les valeurs " & RngSrc.Address(False, False, xlA1, True) & " ?", vbYesNoCancel, "COLLER")
         Case vbYes: For Each RngA In RngSrc.Areas
               WshCbl.Range(RngA.Address).Value = RngA.Value
               Next RngA
         Case vbNo: Exit Sub
         End Select
      Set AppXls = Nothing: End If
   End Sub
 
Dernière édition:

floreli

XLDnaute Nouveau
alors la !!! un grand merci , j aurais jamais reussi tout seul :( tout marche exactement comme je veux. C est parfait.
Ca fait des jours (voire +) que je cherchais des infos sur internet sans trouver ce qu il me fallait...Vraiment merci beaucoup !!!

J ai juste une derniere petite question, dans :

Select Case MsgBox("Voulez vous coller dans '[" & WshCbl.Parent.Name & "]" & WshCbl.Name & "'" _
& vbLf & "les valeurs de " & RngSrc.Address(False) & " ?", vbYesNoCancel, "COLLER")

qu est ce que je dois enlever pour ne pas voir apparaitre le detail de toutes les ranges copier/coller, comme j en ai bcp, le message n est pas tres lisible.

j ai essyé comme ca mais sans succes :

Select Case MsgBox("Voulez vous coller dans '[" & WshCbl.Parent.Name & "]" & WshCbl.Name & " ' " _
& vbLf & "les valeurs de '[" & WshSrc.Parent.Name & "]" & " ?", vbYesNoCancel, "COLLER") '
 

Discussions similaires