Explorateur Windows et recopie d'un fichier
Bonjour à tous,
J'ai une problématique sur laquelle je galère mais je pense que vous pouvez m'aider. J'ai un fichier Excel de base (A), j'aimerai créer un bouton dessus (jusqu’à là je sais faire :)). Quand on clique sur ce bouton, j'aimerai que ça ouvre l'explorateur Windows pour aller sélectionner un autre fichier Excel (B). En sélectionnant le fichier B, j'aimerais que les données qui s'y trouvent se copient automatiquement sur le fichier A. Exemple, la cellule A3 du fichier B se copie sur la cellule D4 du fichier A.
Est-ce que vous pouvez m'aider sur ce coup ? Merci à vous !
Bonjour Jul997,
En l'absence de fichier posté je te présente un bout de code qui te permettra selon ton exemple la copie de la cellule A3 du dernier fichier ouvert en D4 du 1ier fichier.
La macro est affectée au bouton du fichier 1.
Sub CopData()
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
if fichier <> False then Workbooks.Open fichier Else Exit sub
Windows(1).ActiveSheet.Range("A3").Copy Windows(2).ActiveSheet.Range("D4")
End SubNote que Windows(1) représente la dernière fenêtre ouverte. Donc le 2ième fichier.
Bons tests, bonne continuation.
Merci beaucoup pour votre réponse. J'ai pris votre macro et l'ai adapté à mes feuilles et mes cellules, c'est top ! Par contre, la recopie ne se fait pas sur des cellules fusionnées et la macro se met de débogage.
Par exemple, je dis à ma macro de recopier la cellule A8 dans laquelle il y écrit "Fruit" sur la cellule fusionnée "C14/D14". Du coup dans ma macro je l'appelle juste "C14" et c'est là que la macro en comprend pas je pense. Si vous avez une idée ?
Le message d'erreur est "cette action ne peut pas être appliquée à une cellule fusionnée". Sachant qu'il est impossible pour moi d'enlever la fusion...
Bonjour Jul997,
Les cellules fusionnées sont bien pratiques pour la présentation des données mais très pénibles en VBA.
Surtout si elles sont nombreuses. Dans le cas ou elles sont minimes, il est possible par VBA de dé-fusionner ces cellules avant toute opération puis
de les re-fusionner après l'opération de copie par exemple. Au prix d'un alourdissement du code.
Mais je préfère faire autrement. Je laisse aux cellules fusionnées le soin de la présentation des données.
Par contre elles se réfèrent à des cellules intermédiaires (pouvant être masquées) pour obtenir leurs données.
Ainsi dans ton exemple ta cellule fusionnée C14/D14 obtiendra sa valeur ou son texte (par = case X) d'une cellule non fusionnée hors tableau.
Exemple Z14 (ou autre) qui va gérer la donnée. Tu peux le faire pour toutes tes cellules fusionnées en utilisant d'autres cellules intermédiaires.
En résumé c'est donc tes cellules intermédiaires qui reçoivent les données et tes cellules fusionnées qui les présentent.
Donc pour ton cas
Sub CopData()
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
if fichier <> False then Workbooks.Open fichier Else Exit sub
Windows(1).ActiveSheet.Range("A8").Copy Windows(2).ActiveSheet.Range("Z14")
End SubDans ta cellule fusionnée C14/D14 tu auras simplement =Z14. Elle reprendra la valeur copiée sans être touchée par l'utilisation directe de la macro.
La colonne Z peut être masquée comme Zorro par un masquage de colonne entière ou seulement de la cellule (police blanche) si fond blanc.
Bons tests, bonne continuation.
Je vois ce que tu veux dire malheureusement je n'ai pas la possibilité de rentrer par exemple "=Z14" dans la cellule car celle-ci a une liste déroulante en choix de base et du coup la valeur ne correspond pas aux restrictions...
Il y a une autre possibilité ?
Merci beaucoup...
A nouveau,
Ton titre de sujet est plus général que ta demande réelle. Dont je te rappelle un extrait de ton premier message.
En sélectionnant le fichier B, j'aimerais que les données qui s'y trouvent se copient automatiquement sur le fichier A. Exemple, la cellule A3 du fichier B se copie sur la cellule D4 du fichier A.
Pourquoi ne pas avoir directement fait part de cellules fusionnées avec en plus une liste de validation. Ou posté un fichier, cela aurait plus simple.
D'abord, le fait de copier directement (en omettant le souci de fusion) sur une liste de validation va en fait l'écraser.
Et subsidiairement il faut que la donnée copiée soit conforme à la liste déroulante de validation. Sinon elle sera rejetée.
Donc on reste avec la cellule intermédiaire Z14 (ou autre) récupérant la donnée de l'autre fichier mais en évitant de l'insérer directement dans la cellule de la liste.
Voir code ci-dessous ajouté.
'Suite du dernier code posté. Placement sur la cellule fusionnée.
Range("C14").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([Z14])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([Z14], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("Z14")=""
End SubNote que je suppose que tu récupères bien une donnée conforme à la liste de validation.
Bons tests, bonne continuation.
Tu as raison, pour être honnête je ne pensais pas que cela entrainerait ces bugs donc je n'ai pas précisé les paramètres détaillés de mon fichier.
Voilà le code que j'ai essayé de mettre en place avec ton aide :
Private Sub CommandButton1_Click()
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
If fichier <> False Then Workbooks.Open fichier Else Exit Sub
'''''''Ci-dessous, je veux copier la cellule B2 de mon fichier dans la cellule M8 (cellule dite intermédiaire sans liste déroulante ni rien). Ensuite je veux donc envoyer à la cellule fusionnée "B8". Malheuresement, j'ai un message d'erreur qui apparait : "La méthode Select de la classe Range a échoué au niveau de la ligne "Range("B8").Select
""""Je refais ensuite ce processus plusierus fois car j'ai plusieurs cellules à recopier autre part.
Windows(1).ActiveSheet.Range("B2").Copy Windows(2).ActiveSheet.Range("M8")
Range("B8").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([M8])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([M8], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("M8") = ""
Windows(1).ActiveSheet.Range("B3").Copy Windows(2).ActiveSheet.Range("N8")
Range("E8").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([N8])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([N8], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("N8") = ""
Windows(1).ActiveSheet.Range("B4").Copy Windows(2).ActiveSheet.Range("M12")
Range("B12").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([M12])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([M12], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("M12") = ""
Windows(1).ActiveSheet.Range("B5").Copy Windows(2).ActiveSheet.Range("O8")
Range("G8").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([O8])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([O8], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("O8") = ""
Windows(1).ActiveSheet.Range("B6").Copy Windows(2).ActiveSheet.Range("M15")
Range("B15").Select
'Ou autre cellule (Z14) intermédiaire à choisir
Lg = Len([M15])
'Envoi à la cellule fusionnée façon saisie clavier
For L = 1 To Lg
Lettre = Mid([M15], L, 1)
SendKeys Lettre
Next L
SendKeys "{ENTER}"
'Effacement ensuite de la cellule intermédiaire
Range("M15") = ""
End Sub
Bonjour Jul997,
Etant sur une feuille Excel et non un USF. Il n'y a pas besoin de passer par un Private Sub et un bouton Activex (CommandButton).
Insères juste le code dans une macro Sub d'un module. Macro ci-dessous réduite que que tu auras affectée à un simple bouton.
Sub CopData()
'Choix du fichier
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
If fichier <> False Then Workbooks.Open fichier Else Exit Sub
'Copie des Données sur "classeur client" puis fermeture du "classeur fournisseur"
RG = "B2B3B4B5B6Z2Z3Z4Z5Z6"
For N = 1 To 9 Step 2
Rg1 = Mid(RG, N, 2): Rg2 = Mid(RG, N + 10, 2)
Windows(1).ActiveSheet.Range(Rg1).Copy Windows(2).ActiveSheet.Range(Rg2)
Next N
Workbooks(2).Close
'Replacement des Données sur les cellules fusionnées des listes de validation
RG = "B8 E8 B12G8 B15Z2 Z3 Z4 Z5 Z6 "
For M = 1 To 13 Step 3
Rg1 = RTrim(Mid(RG, M, 3)): Rg2 = RTrim(Mid(RG, M + 15, 3))
Range(Rg1).Select
Lg = Len(Range(Rg2))
For L = 1 To Lg
Lettre = Mid(Range(Rg2), L, 1)
SendKeys Lettre
Next L
SendKeys "{Enter}"
Range(Rg2) = ""
Next M
End SubDans le 2ième RG, bien garder l'espace après l'adresse des cellules ne comportant que 2 caractères.
Il est possible ensuite de ne faire qu'une seule boucle. Pour l'instant c'est différencié afin que tu vois la séparation des traitements Copie puis Replacement.
Vérifié sans souci avec des données conformes aux restrictions des listes de validation.
Bons tests, bonne continuation.
Alors pour être très honnête je n'ai pas bien compris le dernier code mais j'ai quand même essayé de l'adapter à mon fichier.
Cela donne ça :
Sub CommandButton1_Click()
'Choix du fichier
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
If fichier <> False Then Workbooks.Open fichier Else Exit Sub
'Copie des Données sur "classeur client" puis fermeture du "classeur fournisseur"
RG = "B2 B3 B4 B5 B6"
For N = 1 To 9 Step 2
Rg1 = Mid(RG, N, 2): Rg2 = Mid(RG, N + 10, 2)
Windows(1).ActiveSheet.Range(Rg1).Copy Windows(2).ActiveSheet.Range(Rg2)
Next N
Workbooks(2).Close
'Replacement des Données sur les cellules fusionnées des listes de validation
RG = "B8 E8 B12 G8 B15 "
For M = 1 To 13 Step 3
Rg1 = RTrim(Mid(RG, M, 3)): Rg2 = RTrim(Mid(RG, M + 15, 3))
Range(Rg1).Select
Lg = Len(Range(Rg2))
For L = 1 To Lg
Lettre = Mid(Range(Rg2), L, 1)
SendKeys Lettre
Next L
SendKeys "{Enter}"
Range(Rg2) = ""
Next M
End SubIl y a une erreur au niveau de la ligne ç "Windows 1 ..." ==> erreur définie par l'application ou par l'objet
Ce que je comprends c'est que je copie les cellules B2, B3, B4, B5 et B6 de mon fichier fournisseur sur mon fichier de base, par contre je n'ai pas bien compris ou je les colle. Et ensuite ces valeurs sont replacés sur les cellules fusionnées telles que B8, E8...
C'est bien cela ?
Merci,
A nouveau,
Faire attention quand tu supprimes ou adapte une partie du code. Le 1ier RG n'a pas d'espace.
RG = "B2B3B4B5B6Z2Z3Z4Z5Z6"Ensuite les cellules intermédiaires vont De Z2 à Z6. Or dans ta modification, tu les supprimes!
De même pour le 2ième RG, pas d'espace si la cellule a 3 caractères comme B15.
Note que tu dois avoir seulement 2 classeurs, le premier qui comporte la macro et le second qui sera choisie et sera donc Windows(2).
A suivre...
D'accord merci pour les modifs, voilà ce que donne mon code :
Sub CommandButton1_Click()
'Choix du fichier
fichier = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*")
If fichier <> False Then Workbooks.Open fichier Else Exit Sub
'Copie des Données sur "classeur client" puis fermeture du "classeur fournisseur"
RG = "B2B3B4B5B6M2M3M4M5M6"
For N = 1 To 9 Step 2
Rg1 = Mid(RG, N, 2): Rg2 = Mid(RG, N + 10, 2)
Windows(1).ActiveSheet.Range(Rg1).Copy Windows(2).ActiveSheet.Range(Rg2)
Next N
Workbooks(2).Close
'Replacement des Données sur les cellules fusionnées des listes de validation
RG = "B8 E8 B12G8 B15M2M3M4M5M6"
For M = 1 To 13 Step 3
Rg1 = RTrim(Mid(RG, M, 3)): Rg2 = RTrim(Mid(RG, M + 15, 3))
Range(Rg1).Select
Lg = Len(Range(Rg2))
For L = 1 To Lg
Lettre = Mid(Range(Rg2), L, 1)
SendKeys Lettre
Next L
SendKeys "{Enter}"
Range(Rg2) = ""
Next M
End SubCa bloque sur la ligne Range(Rg1).select
Il me dit que la méthode Range de l'objet Worksheet a échoué, penses-tu savoir d'ou ca peut venir ?
Merci
Bonjour Jul997,
Oui, cela vient de ton inattention... Je te rappelle une ligne de mon dernier message. Ainsi que plus après le code transmis.
De même pour le 2ième RG, pas d'espace si la cellule a 3 caractères comme B15.
Or est ce que pour le 2ième RG ton code
'Replacement des Données sur les cellules fusionnées des listes de validation
RG = "B8 E8 B12G8 B15M2M3M4M5M6"est conforme à la structure donnée?
'Replacement des Données sur les cellules fusionnées des listes de validation
RG = "B8 E8 B12G8 B15Z2 Z3 Z4 Z5 Z6 "Ensuite la donnée que tu copie s'accorde bien à la liste des données de validation. Exemple: Si ta liste comprend que ces cinq données comme titi tata toto tutu tyty.
Et que tu veuilles placer tonton cela ne passera pas.
A suivre...
Bonjour,
J'ai essayé de comprendre la macro mais je suis arrivé à des erreurs encore...
Du coup j'ai fait des fichiers test que vous pouvez regarder pour me dire ce qui ne va pas. Il y a le fichier source dans lequel les données doivent être recopiées (fichier "test" de C2 à C7) et le fichier "données" dans lequel les données vont être recherchées.
En gros je veux recopier les cellules B2 à B7 du fichier "données" dans les cellules C2 à C7 qui sont elles fusionnées du fichier "test".
Merci encore...