Transfert de données entre deux classeurs sans utilise la fonction activate

Bonjour à tous,

Tout d'abord merci à ceux et celles qui prennent le temps de répondre aux nombreuses questions qui listent ce forum ( j'espère un jour en avoir le niveau pour en faire partie ).

J'ai une question existentielle qui me rend dingue, c'est la raison pour laquelle je viens ici chercher de l'aide parce qu'après avoir lu des dizaines de problèmes similaires je n'arrive toujours pas à trouver la réponse, et je suis persuadé que la réponse est toute simple en plus.

Pour illustrer mon problème je vais donner un exemple très basique.

J'ai deux classeurs, que je nomme classeur1 et classeur2.

Je suis positionné sur le classeur2 ( en feuille 1 ) et j'aimerais importer des données du classeur 1 sans "bouger" de mon classeur 2, donc sans avoir à utiliser la fonction activate.

Si j'utilise la syntaxe ci-dessous cela fonctionne :

Rappel : mon classeur actif est le classeur2

Workbooks("Classeur1").Worksheets("Feuil1").Range("A1:A3").Copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")

Mais si j'utilise celle ci-dessous, cela ne fonctionne pas, j'ai le message d'erreur "Erreur d'exécution 1004, Erreur définie par l'application ou par l'objet", pourquoi ?!

Workbooks("Classeur1").Worksheets("Feuil1").Range(Cells(1, 1), Cells(3, 1)).Copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")

=> Par contre, si mon classeur actif est le classeur1, cette synthaxe fonctionne... je n'arrive pas à saisir parce que le chemin est le même ( je transmets des données classeur 1 vers le classeur 2.

Ce qui m'embête c'est que je me suis habité à utiliser cette manière de référencer les cellules qui est plus pratique quand on gère des variables, je n'ai donc pas envie de changer de méthode et j'aimerais surtout comprendre ce qui cloche.

Merci d'avance à ceux qui essaieront de m'aider

Florian

Bonsoir,

la syntaxe avec range(cells(1,1),cells(3,1)) pose problème car cells sans être qualifié fait référence à la feuille active. ce qui explique que parfois cela fonctionne et parfois pas, dépendant de la feuille active.

la syntaxe correcte est

range(Workbooks("Classeur1").Worksheets("Feuil1").cells(1,1),Workbooks("Classeur1").Worksheets("Feuil1").cells(3,1)).copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")

ou

with Workbooks("Classeur1").Worksheets("Feuil1")
range(.cells(1,1),.cells(3,1)).copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")
end with

la syntaxe suivante est également correcte d'un point de vue syntaxe, mais incorrecte d'un point de vue conceptuel.

Workbooks("Classeur1").Worksheets("Feuil1").range(Workbooks("Classeur1").Worksheets("Feuil1").cells(1,1),Workbooks("Classeur1").Worksheets("Feuil1").cells(3,1)).copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")

Bonjour et bienvenue sur le forum

Range(...) définit une plage

cells(... , ...) définit une cellule

Tu dois mettre le chemin complet devant les deux, ce que tu ne fais pas dans le second cas.

Tu peux simplifer ainsi en te servant du point comme raccourci :

With Workbooks("Classeur1").Worksheets("Feuil1")
    .Range(.Cells(1, 1), .Cells(3, 1)).Copy Destination:=Workbooks("Classeur2").Worksheets("Feuil1").Range("A1")
End With

OK ?

Bye !

Merci milles fois à vous deux, j'aurais encore appris quelque chose car je ne connaissais pas cette particularité

J'espère que ce sujet pourra en aider d'autres.

Bonnes fêtes

Cordialement,

Florian

Bonsoir,

et Salut à h2so4 et gmb !

Je suis positionné sur le classeur2 ( en feuille 1 ) et j'aimerais importer des données du classeur 1 sans "bouger" de mon classeur 2, donc sans avoir à utiliser la fonction activate.

Excellent réflexe !

Si tu programmes, c'est pour faire faire ce que tu dis (sans te déplacer pour aller le faire toi-même, si je puis dire !)

En outre, les déplacements (Activate, Select, etc.) constituent des opérations, qui prennent du temps, temps qui n'est pas consacré aux actions voulues, et donc allonge la durée d'exécution.

VBA étant capable de faire ce que tu lui demandes, sans déplacement inutile, ton réflexe est donc le bon !

La contrepartie est que cela t'oblige à qualifier tes expressions (selon les termes officiels), comme te l'ont expliqué h2so4 et gmb, c'est à dire à avoir toujours un rattachement explicite à la feuille (pour une plage), au classeur (pour une feuille, quand tu utilises plusieurs classeurs)... C'est aussi un réflexe à prendre. Il peut te sembler à première vue que cela t'oblige à écrire du code en plus... mais il y a diverses méthodes pour le raccourcir et au bout du compte tu en tireras bénéfice, car en ne qualifiant pas, tu fais remonter à Application (le sommet de la pyramide d'objets Excel toujours présent implicitement) puis rechercher l'élément actif... ce qui prendra nécessairement plus de temps que si l'élément cherché est désigné sans ambiguïté. Ton code gagnera en vitesse d'exécution et en fiabilité (plus d'erreur possible sur l'objet visé).

Cordialement.

Bonjour MFerrand,

Ravi que vous ayez aussi pris la peine de me répondre

Effectivement j'ai lu ce conseil ( celui de bannir au maximum les méthodes de déplacement lorsque l'on code ) tellement de fois qu'il serait idiot que je ne l'applique pas.

Merci pour ces conseils que je vais tâcher de garder en tête !

A vrai dire je ne pensais vraiment pas que mon code était ambiguë, dans le sens où je respectais le principe de la "poupée russe" lorsque l'on qualifie des objets, à savoir que je pars du classeur cible, puis je rentre dans la feuille cible pour arriver vers une cellule ou une plage de cellule cible.

Maintenant que j'ai la bonne synthaxe je devrais pouvoir m'en sortir à l'avenir

Cordialement,

Florian

Rechercher des sujets similaires à "transfert donnees entre deux classeurs utilise fonction activate"