Copier/coller données classeur B à Classeur A

FlorianQ

XLDnaute Nouveau
Bonjour à tous,
je travaille en ce moment sur une macro et je fais face à quelques difficultés. Le but de ma macro est d'automatiser un ensemble de tâche qui vise à donner des résultats sous forme de tableaux croisés dynamiques à des non-initiés d'Excel, je dois donc tenter de faire au plus simple. Pour ce faire, j'utilise des macro. Je pars d'un classeur qu'on va nommé A.xlsx (nom fixe) et j'importe une base de données au choix, avec ce code
Code:
Sub CommandButton1_Click() ' RECHERCHE DU CLASSEUR SOURCE

Dim Classeur_choisi As Long
Static Classeur_choisi_bis As String

Select Case UserForm1.CommandButton1.Caption

    Case "Copier la requête"
    
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = False
            .Show
                   For Classeur_choisi = 1 To .SelectedItems.Count
                   Workbooks.Open (.SelectedItems(Classeur_choisi))
                   Next Classeur_choisi
        End With
    Classeur_choisi_bis = ActiveWorkbook.Name
        
    ActiveWorkbook.Saved = True ' Pour éviter le message de re-calcul des formules d'une version antérieure.
    
    UserForm1.CommandButton1.Caption = "Copier cette Feuille"
    
    ' ICI ON PEUT CHOISIR LA FEUILLE A COPIER
    
    Case "Copier cette Feuille"
    
    ActiveWorkbook.ActiveSheet.Copy after:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
    Windows(Classeur_choisi_bis).Activate
    Application.DisplayAlerts = False
    ActiveWorkbook.Close
    MsgBox ("Votre feuille est copiée dans le classeur !")
    
    Unload UserForm1
    Sheets("Macro et mode d'emploi").Select
    Application.DisplayAlerts = True
    ActiveWorkbook.Save

End Select
End Sub
Ce code n'est peut-être pas parfait (je débute en VBA et je suis prêt à recevoir des astuces si vous en avez) mais il est fonctionnel.
Maintenant cela fonctionne mais je dois aussi importer une base qui n'est pas standardisée et c'est là que se présente mon problème, j'utilise une syntaxe quasiment similaire
Code:
Private Sub CommandButton2_Click()

Dim Classeur_choisi As Long
Static Classeur_choisi_bis As String

Select Case UserForm1.CommandButton2.Caption

    Case "Copier la requête pour auto"
    
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = False
            .Show
                   For Classeur_choisi = 1 To .SelectedItems.Count
                   Workbooks.Open (.SelectedItems(Classeur_choisi))
                   Next Classeur_choisi
        End With
    Classeur_choisi_bis = ActiveWorkbook.Name
    n = Workbooks(Classeur_choisi_bis).Sheets("DP_NACRE_Synthèse").Range("A65536").End(xlUp).Row
    
    ActiveWorkbook.Saved = True ' Pour éviter le message de re-calcul des formules d'une version antérieure.
    
    UserForm1.CommandButton1.Caption = "Copier cette Feuille"
    
    ' ICI L'ON PEUT CHOISIR LA FEUILLE A COPIER
    
    Case "Copier cette Feuille"
    
    ActiveWorkbook.ActiveSheet.Range("A24" & ":AF" & n).Copy after:=ThisWorkbook.Sheets("Autos").Range("A6")
    Windows(Classeur_choisi_bis).Activate
    Application.DisplayAlerts = False
    ActiveWorkbook.Close
    'MsgBox ("Votre feuille est copiée dans le classeur !")
    
    Unload UserForm1
    Sheets("Macro et mode d'emploi").Select
    Application.DisplayAlerts = True
    ActiveWorkbook.Save

End Select
End Sub

Cependant je fais peut-être une erreur bête mais le bouton ne fonctionne pas du tout, je n'ai pas d'erreur mais je n'ai même pas l'explorateur de fichier qui s'ouvre.

En clair je cherche à faire, dans l'ordre :
Ouverture de mon classeur A (qui dispose des macro), import d'une feuille d'un autre classeur dans une nouvelle feuille avec le premier code, puis importation dans une feuille (dans A) déjà créée cette fois, d'une partie d'une feuille d'un classeur B (qui lui a un nom variable).
C'est un peu flou mais c'est de cette manière que j'en ferai une première approche, si vous avez besoin de plus de précisions, n'hésitez pas.

Merci d'avance ! :cool:
 

FlorianQ

XLDnaute Nouveau
Re : Copier/coller données classeur B à Classeur A

Petite précision pour ce qui est des fichiers. Lors de la première importation, je veux le prendre en brut, donc ça marche parfaitement. Pour ce qui est du second fichier j'ai un énorme entête qui donne des description. Serait-il plus simple d'importer le tout dans ma feuille "Auto" de mon classeur, de supprimer l'entête et de remettre les données restantes un peu plus haut en terme de ligne ? (Les données commence à la ligne 24 dans la requête alors que j'aimerai qu'elles apparaissent à la ligne 6 ou bien à la ligne 2 si c'est trop complexe, dans mon classeur de destination)

Merci.
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Copier/coller données classeur B à Classeur A

Bonjour Florian, bonjour le forum,

Plutôt que d'utiliser le nom des fichier dans tes variable je te conseille de les déclarer de type Workbook et de les définir à l'aide de Set. Je n'ai pas modifié la fin du code car je ne sait plus qui est qui, mais ça donnerait :

Code:
Private Sub CommandButton2_Click()
Dim CS As Workbook 'déclare la variable CS (Classeur Source)
Dim CC As Workbook 'déclare la variable CC (Classeur Cible)

Set CS = ThisWorkbook
Select Case UserForm1.CommandButton2.Caption
    Case "Copier la requête pour auto"
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = False
            .Show
            Workbooks.Open (.SelectedItems(1))
        End With
        Set CC = ActiveWorkbook
        n = CC.Sheets("DP_NACRE_Synthèse").Range("A65536").End(xlUp).Row
        CC.Saved = True 
        UserForm1.CommandButton1.Caption = "Copier cette Feuille"
        ' ICI L'ON PEUT CHOISIR LA FEUILLE A COPIER
    
    'là, je ne sais plus qui est qui. Normalement ActiveWorkbook = ThisWorrkbook = CS. Je ne comprend pas ton code
    Case "Copier cette Feuille"
        ActiveWorkbook.ActiveSheet.Range("A24" & ":AF" & n).Copy after:=ThisWorkbook.Sheets("Autos").Range("A6")
        Windows(Classeur_choisi_bis).Activate
        Application.DisplayAlerts = False
        ActiveWorkbook.Close
        'MsgBox ("Votre feuille est copiée dans le classeur !")
        Unload UserForm1
        Sheets("Macro et mode d'emploi").Select
        Application.DisplayAlerts = True
        ActiveWorkbook.Save
End Select
End Sub
 

FlorianQ

XLDnaute Nouveau
Re : Copier/coller données classeur B à Classeur A

Bonjour Robert et merci pour votre réponse.

Je pense que dans le fond, il est préférable de déclarer les variables comme vous l'avez fait, cependant après modification le code ne s'exécute toujours pas pour une raison que j'ignore, je n'ai pas de boite de dialogue qui s'ouvre pour sélectionner un fichier, alors que dans le premier bouton, si.
 

FlorianQ

XLDnaute Nouveau
Re : Copier/coller données classeur B à Classeur A

Quelle bêtise, je n'avais pas vu que j'avais mis une majuscule en trop sur mon second bouton. Merci infiniment.

Lorsque que l'utilisateur annule l'action en cours cela affiche un message d'erreur, existe-t'il une boucle pour sortir sans erreur si l'utilisateur n'a pas sélectionné de fichier ?
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Copier/coller données classeur B à Classeur A

Re,

Corrige cette partie :

Code:
With Application.FileDialog(msoFileDialogOpen)
    .AllowMultiSelect = False
    .Show
    If .SelectedItems.Count = 0 Then Exit Sub
    Workbooks.Open (.SelectedItems(1))
End With
 

FlorianQ

XLDnaute Nouveau
Re : Copier/coller données classeur B à Classeur A

Re,

ce n'était pas vraiment une question à proprement parlé mais si vous voulez lorsque j'appuie sur mon bouton, je peux sélectionner le fichier, je choisis ma feuille et lorsque j'appuie sur "Copier cette feuille", j'ai une erreur : variable objet ou bloc With non définie
à ce niveau
Code:
        CC.Sheets("DP_NACRE_Synthèse").Range("A24" & ":AF" & n).Copy after:=CS.Sheets("Autos").Range("A6")
        Windows(CC).Activate
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Copier/coller données classeur B à Classeur A

Re,

les propriétés Before ou After ne s'appliquent qu'à la copie d'onglets. Pour une plage, la syntaxe est
PlageSource.Copy CelluleDestination.
Soit :

Code:
CC.Sheets("DP_NACRE_Synthèse").Range("A24:AF" & n).Copy CS.Sheets("Autos").Range("A6")
CC.Activate
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Copier/coller données classeur B à Classeur A

Re,

Ce qui bon à savoir aussi c'est que j'ai perdu ma boule de cristal !...
Par conséquents, des explications claires avec le code complet et la ligne qui plante seraient les bienvenues. Si en plus on a les fichiers qui vont bien alors là, c'est la merise sur le râteau !...
 

FlorianQ

XLDnaute Nouveau
Re : Copier/coller données classeur B à Classeur A

Re,

j'ai essayé de vous faire une représentation de mon problème, le code qui nous intéresse est celui affectué au Command_Button2, ce qui devrait fonctionner est l'ouverture de "Données factices" avec le 2ème bouton de la Macro en ne prenant que la plage de cellule indiquée en vert, qui peut être amenée à changer au jour le jour (en terme de lignes).
 

Pièces jointes

  • Macro démonstration.xlsm
    24.3 KB · Affichages: 17
  • Données factices.xlsx
    78.3 KB · Affichages: 13

Robert

XLDnaute Barbatruc
Repose en paix
Re : Copier/coller données classeur B à Classeur A

Re,

Je pense avoir compris... Tu avais un problème de portabilité. En effet, les variables sont déclarées à l'intérieur de la procédure : Private Sub CommandButton2_Click(). Cela signifie qu'à la fin de celle-ci elles perdent leur valeur. Donc, au deuxième clic sur le bouton, qui a changé de [Caption], seule la variable CS était définie tandis que les variables CC et n ne l'étaient plus. D'où le plantage sur la ligne :
Code:
 CC.Sheets("DP_NACRE_Synthèse").Range("A24:AF" & n).Copy CS.Sheets("Autos").Range("A6")

Pour éviter cela j'ai déclarée les trois variables CS, CC et n au niveau module en les mettant au tout début du code (après Option Explicit) et en les déclarant Private pour bien montrer qu'elles gardent leur portabilité dans tout le module (Dim aurait fonctionné aussi mais Private est plus explicite).
Ce qui donne pour ton code (que j'ai aussi légèrement modifié) :

Code:
Option Explicit
Private CS As Workbook 'déclare la variable CS (Classeur Source)
Private CC As Workbook 'déclare la variable CC (Classeur Cible)
Private n As Long

Private Sub CommandButton2_Click()
'BOUTON IMPORTE UNE PLAGE DE CELLULES

Set CS = ThisWorkbook
Select Case UserForm1.CommandButton2.Caption
'Si le bouton se nomme ...
    Case "Feuille à copier pour auto"
    'alors selection d un fichier
        With Application.FileDialog(msoFileDialogOpen)
            .AllowMultiSelect = False
            .Show
            If .SelectedItems.Count = 0 Then Exit Sub
            Workbooks.Open (.SelectedItems(1))
        End With
        Set CC = ActiveWorkbook
        'Pour calculer le nombre de lignes du fichier
        n = CC.Sheets("DP_NACRE_Synthèse").Range("A65536").End(xlUp).Row
        CC.Saved = True
        'Le bouton change de libellé
        UserForm1.CommandButton2.Caption = "Copier cette Feuille"
        ' ICI ON PEUT CHOISIR LA FEUILLE A COPIER
        'si le bouton se nomme ... (si le premier case est effectué en clair)
    Case "Copier cette Feuille"
        'Copier les lignes dans le range dans la feuille auto du classeur contenant les macros
        CC.Sheets("DP_NACRE_Synthèse").Range("A24:AF" & n).Copy CS.Sheets("Autos").Range("A6")
        'Pour aller sur le classeur et le fermer
        CC.Close False
        Unload Me
        Sheets("Macro et mode d'emploi").Select
        CS.Save
        MsgBox ("Votre feuille est copiée dans le classeur !")
End Select
End Sub
 

Discussions similaires

Statistiques des forums

Discussions
311 725
Messages
2 081 940
Membres
101 845
dernier inscrit
annesof