Copier plage d'un classeur à un autre

Bonjour au forum,

Je rencontre un problème avec ce code me permettant de copier une plage de cellule d'un classeur à un autre :

Sub Copy()

ChDrive "O"
ChDir "O:\chemin\DONNEES BRUTES"

    Workbooks.Open Filename:=Application.GetOpenFilename 'on sélectionne le fichier qui comporte les données à copier
    ActiveSheet.Range("A3:G400").Copy
    Windows("fichier ou coller.xlsm").Activate
        With ActiveSheet
            .Unprotect "mdp"
           .Range("A11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
            .Protect "mdp", DrawingObjects:=True, Contents:=True, Scenarios:= _
                False, AllowFormattingCells:=True, AllowSorting:=True, AllowFiltering:= _
                True, AllowUsingPivotTables:=True
            .Range("A11").Select
        End With
End Sub

J'ai une fois sur deux une erreur sur la méthode .Pastespecial, et je ne comprends pas pourquoi...

Quelqu'un aurait une idée ?

Merci d'avance !

Bonsoir,

Il faudrait épurer ton code de tous les éléments inutiles, et qualifier plus précisément... Il suffit que la feuille active ne soit pas celle que tu penses...

Cordialement.

Bonsoir MFerrand,

Je ne vois pas vraiment quel bout de code est inutile malheureusement... Ni d’ailleurs comment qualifier plus précisément !

Eh bien !

    ActiveSheet.Range("A3:G400").Copy

Cette commande présuppose que le classeur que tu ouvres ne contient qu'une feuille... Mais même dans ce cas, une désignation plus précise de la feuille me semble préférable... (et on ne sait jamais, tu pourrais ajouter une feuille sans penser à ta macro...)

    Windows("fichier ou coller.xlsm").Activate
        With ActiveSheet

Je déconseille l'utilisation de l'objet Window pour autre chose que des questions d'affichage, on est plus sûr de ce qu'on fait avec les composants sur lesquels on agit : Workbook, Worksheet, Range...

Ici encore ActiveSheet présuppose que la feuille était antérieurement active et le redeviendra, voire qu'on a lancé la macro à partir de cette feuille, mais présupposer ne garantit pas une fiabilité absolue à long terme, cibler l'objet précis qu'on vise est toujours mieux...

Et évidemment le faire sans activer évite une opération parasite qui prend du temps et sera donc plus rapide.

        .Range("A11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

Comme d'hab. !

       .Range("A11").PasteSpecial xlPasteValues

suffisait, le reste est du superflu...

J'ajoute que si l'opération est un collage valeurs on n'a aucun intérêt au copier-coller, une affectation de valeurs sur le mode :

    PlageCible.Value = PlageSource.Value

sera infiniment plus rapide.

Cordialement.

Merci pour ta réponse MFerrand

Cette commande présuppose que le classeur que tu ouvres ne contient qu'une feuille... Mais même dans ce cas, une désignation plus précise de la feuille me semble préférable... (et on ne sait jamais, tu pourrais ajouter une feuille sans penser à ta macro...)

Le classeur que j'ouvre contient une seule feuille dont le nom change mensuellement (c'est un export d'un logiciel tiers), exemple : "janvier_Ana.xls"

C'est pourquoi je ne peux pas, du moins avec mes compétences, demander la copie en utilisant un nom de feuille spécifique.

Je déconseille l'utilisation de l'objet Window pour autre chose que des questions d'affichage, on est plus sûr de ce qu'on fait avec les composants sur lesquels on agit : Workbook, Worksheet, Range...

Je devrais donc simplement remplacer le :

Windows("fichier ou coller.xlsm").Activate

par :

Workbook("fichier ou coller.xlsm").Activate

?

Ici encore ActiveSheet présuppose que la feuille était antérieurement active et le redeviendra, voire qu'on a lancé la macro à partir de cette feuille, mais présupposer ne garantit pas une fiabilité absolue à long terme, cibler l'objet précis qu'on vise est toujours mieux...

Et évidemment le faire sans activer évite une opération parasite qui prend du temps et sera donc plus rapide.

J'ai effectivement crée un bouton sur chaque feuille de mon fichier de destination (importation mensuelle, tu l'auras certainement compris ) sur lesquelles j'ai affecté la même macro pour cette importation. Je voulais éviter de créer une macro pour chaque mois, mais ce n'est peut-être pas la bonne solution finalement ?

suffisait, le reste est du superflu...

Effectivement...

J'ajoute que si l'opération est un collage valeurs on n'a aucun intérêt au copier-coller, une affectation de valeurs sur le mode :

CODE : TOUT SÉLECTIONNER

PlageCible.Value = PlageSource.Value

sera infiniment plus rapide.

J'ai testé cela mais sans succès...

Merci pour ton aide

Bonjour,

Worksheets(1) cible très bien la feuille sans faire appel à son nom.

Il ne s'agit pas par ailleurs d'activer la fenêtre ou le classeur, mais de l'utiliser sans avoir à l'activer...

Tu peux également avec une variable Range lui affecter au départ la plage cible, ce qui évite diverses répétitions.

J'ai testé cela mais sans succès...

Comment donc l'as-tu testé ?

Ma suggestion :

Sub Copy()
    Dim PlgC As Range
    ChDrive "O"
    ChDir "O:\chemin\DONNEES BRUTES"
    With ActiveSheet
        Set PlgC = .Range("A11:G408")
        .Unprotect "mdp"
    End With
    With Workbooks.Open(Application.GetOpenFilename)
        PlgC.Value = .Worksheets(1).Range("A3:G400").Value
        .Close False
    End With
    PlgC.Worksheet.Protect "mdp", True, True, False, AllowFormattingCells:=True, _
     AllowSorting:=True, AllowFiltering:=True, AllowUsingPivotTables:=True
End Sub

Avec une variable Range pour la plage cible et une mise sous bloc With du classeur source à l'ouverture, on opère directement... Noter que l'on peut pointer à partir d'une plage la feuille qui la contient.

Cordialement.

Bonjour MFerrand,

Comme d'habitude, tu me sors une belle épine du pied... !

Worksheets(1) cible très bien la feuille sans faire appel à son nom.

Je ne connaissais pas cette subtilité qui va beaucoup m'aider, merci beaucoup !

Comment donc l'as-tu testé ?

Probablement mal, je ne me souviens plus exactement, mais je sais que j'ai eu des difficultés pour coder "Cette plage dans ce classeur = cette plage dans cet autre classeur". Je n'ai pas encore cet automatisme d'utiliser "Set"...

Merci beaucoup pour ton aide MFerrand, et une excellente semaine à toi !

Rechercher des sujets similaires à "copier plage classeur"