[VBA] Ouverture dossier

Résolu
Bonjour a tous,

je souhaiterais ecrire une macro qui me permette de copier tous les fichiers (.xls ou .txt) contenus dans un certain dossier et de les coller dans un autre document excel, chacun dans une feuille differente.

Deja, est-il possible de realiser le copier-coller sans ouvrir les fichiers ? Ensuite, comment m y prendre ? J e m embrouille un peu avec les commandes open, copy, paste et avec l ouverture de dossier.

Merci beaucoup pour votre aide

Charlotte
Configuration: Windows XP Internet Explorer 7.0

20 réponses

Résumé de la discussion

Une macro est recherchée pour copier tous les fichiers .xls et .txt contenus dans un dossier et les coller chacun dans une feuille distincte d’un autre classeur Excel, sans ouvrir les fichiers. Plusieurs interventions suggèrent de gérer la question de l’ouverture des fichiers et d’utiliser une boucle pour parcourir le répertoire et créer une feuille par fichier, avec gestion des extensions. Des propositions de code évoquent Activate/Open, copier-coller et effacement du presse-papiers, ainsi que des méthodes pour récupérer les fichiers sans connaître leur nom ni leur nombre. Des échanges évoquent aussi des détails comme le passage par AllFilesInFolder et les défis de la conversion des données des fichiers texte vers des feuilles Excel.

Bobot (l’IA à votre service)
  1. Application.EnableEvents = False
            Workbooks.Open Filename:= _
            "D:\***\**\***.xls"
            Application.EnableEvents = True
            Windows("***.xls").Activate
            
            'copie des données sygma
            Sheets(1).Activate
            Cells.Select
            Application.CutCopyMode = False
            Selection.Copy
            'colle les donnée
            Windows("TOTAL.xls").Activate
            Sheets("*****").Select
            ActiveSheet.Range("A1").Select
            ActiveSheet.Paste
             'vide le presse papier pour pouvoir fermer suivi des ofs
            Dim oDataObject As DataObject
    
            Set oDataObject = New DataObject
            oDataObject.SetText ""
            oDataObject.PutInClipboard
            Set oDataObject = Nothing


    puis surtout une boucle pour ton fichier de recepetionpour changer de feuille a chaque copie
    2
    1. J ai oublie de preciser que je ne connais pas a l avance le nom ni le nombre de fichiers dans mon dossier.
      1
      1. Workbooks(NomDoc).Activate
        Dim xlsSheet As Excel.Worksheet 'Variable objet "feuille"
        'Boucle sur toutes les feuilles du classeur actif:
        For Each xlsSheet In Worksheets
        xlsSheet.Activate

        If xlsSheet.Name <> "" Then

        OngletaOuvrir = xlsSheet.Name
        OngletaOuvrir = Left(OngletaOuvrir, 8)
        Windows("****").Activate

        For Each Sheet In Worksheets
        Sheet.Activate
        If Sheet.Name = OngletaOuvrir Then
        trouver = True
        Exit For
        Else
        'rien
        End If
        Next xlsSheet

        voilà la boucle à toi d'adapter :p
        1
        1. Merci beaucoup YATA !

          Je n arrive pas encore a le faire tourner. Il a l air de coincer sur le "Dim oDataObject As DataObject" : tu as une idee de la raison ?

          Ensuite, pourrais-tu m expliquer en quoi consiste ton code au niveau de l "OngletaOuvrir" stp ? Et ce que veut dire "If xlsSheet.Name <> """ (a quoi correspond le "") ?

          Enfin, si j ai bien compris, tu me permets ici de
          - copier les donnees de mon fichier d origine (dans le dossier d origine) et coller dans la feuille active de mon nouveau document Excel
          - changer de feuille Excel ensuite

          mais est ce que ton code comprend le fait de rechercher dans mon dossier d origine tous les documents d extension .xls ou .txt, quel que soit leur nom, afin de les copier chacun dans une feuille differente de mon nouveau document Excel ? Parce que si c est le cas j ai pas trop compris alors... ; )

          Merci beaucoup pour ton aide en tout cas !

          Charlotte
          1
          1. Ah oui, et puis j ai oublie de te dire que j aimerais bien refermer chaque fichier apres l avoir copie et colle dans la nouvelle feuille excel de mon nouveau document excel.
            1
            1. Bonjour Charlotte,

              Peux-tu être un peu plus précise stp.

              Si j'ai bien compris, tu veux récupérer des fichiers .xls et .txt dans un répertoire.

              1) Est-ce toujours le même répertoire ?
              2) Y-a-t-il des sous répertoires à scanner également ?

              Lorsque tu as récupéré les fichiers, tu veux copier le contenu dans un nouveau classeur, 1 onglet par fichier.

              1) La structure des fichiers .xls est-elle toujours la même ?
              2) Si c'est un fichier .xls, faut-il copier tous les onglets ou bien 1 seul onglet ?
              3) Si c'est un fichier .txt, leur structure est-elle toujours identique ? Comment doivent être recopiés les lignes
              du fichier .txt ? Tout dans la même cellule ou 1 ligne txt = 1 ligne xls ?

              ;o)
              1
              1. Bonjour Polux31,

                je vais detailler un peu plus :

                - mes fichier txt et xls sont dans un dossier qui est toujours le meme et ne contient pas de sous-dossier (en fait il s agit de fichiers de resultats de simulations contenant les coordonnees des points d une courbe I(V)) ; il n y a donc qu un seul dossier, fixe, a scanner.

                - les fichiers peuvent se trouver en format txt ou xls (a priori tout l un ou tout l autre) ; la structure des xls est toujours la meme, il n y a qu un seul onglet a copier (le premier) ; celle des txt est egalement toujours la meme (points d une courbe I(V)) et il vaut mieux que chaque donnee se retrouve dans une cellule differente (plus simple pour tracer la courbe ensuite) mais il me semble que cela se fait automatiquement quand j ouvre mon txt avec excel.

                - je souhaite copier-coller chacun des documents (ou premiere feuille de document) de mon dossier dans une feuille differente de mon nouveau document excel, en donnant a chaque feuille le nom du document d origine dans le dossier. A terme, j aimerais aussi en profiter pour tracer les courbes I(V) sur chaque feuille, apres avoir effectue le coller et avant de passer a la feuille suivante mais on va peut etre commencer par le commancement... ; )

                J espere avoir ete un peu plus precise.

                Merci beaucoup pour ton aide
                0
                1. Laisse moi un peu de temps et je te fais parvenir un exemple.

                  ;o)
                  0
                  1. Tu trouveras un exemple ici : https://www.cjoint.com/?inqmwvmZ7f

                    Bien sur il faut l'adapter à ton projet.

                    En espérant que cela réponde à ton besoin.

                    N'hésite pas à revenir poser des questions.

                    ;o)

                    Polux
                    0
                    1. Merci beaucoup, Polux31 !

                      Je suis en train de regarder ca de pres. Pour l instant je bloque surtout sur ton "mPath" : j ai du mal a voir ou tu le definis. Enfin je vois que tu le definis par exemple de la facon suivante "Private Sub traiteXLS(ByVal mPath As String)" mais je ne vois pas comment le code peut savoir exactement ce que c est quand tu l appelles ensuite pour la premiere fois "Set wkIn = Workbooks.Open(mPath)". Tu as du lui faire correspondre un chemin qqpart ailleurs mais je ne trouve pas...

                      Pareil pour mTabFiles et PathFolder : je ne vois pas a quel moment tu leur assignes une valeur.

                      Merci !
                      0
                      1. Bonjour,

                        Effectivement je n'ai pas trop commenté le code ^^

                        Option Explicit
                        
                        'L'objet ClipBoard n'existant pas en VBA, il faut utiliser les fonctions de l'API Windows :
                        '-- Déclaration des fonctions API
                        Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
                        Private Declare Function CloseClipboard Lib "user32" () As Long
                        Private Declare Function EmptyClipboard Lib "user32" () As Long
                         
                        Private mTabFiles()
                        Private pathFolder As String
                        
                        'Setter d'affection de valeur à pathFolder
                        'Cette valeur vient de la cellule C3
                        'Procédure appelée par cmdMenu_Click() de Feuil1
                        Public Sub setPathFolder(ByVal str As String)
                            pathFolder = str
                        End Sub
                        
                        'Procédure Main du traitement
                        'Procédure appelée par cmdMenu_Click() de Feuil1
                        Public Sub Main()
                        
                            initEnvironnement
                            traiteFichiers
                            
                        End Sub
                        
                        'Procédure d'initialisation du tableau mTabFiles()
                        'Procédure appelée par Main()
                        Private Sub initEnvironnement()
                        
                            'On récupère le chemin d'acces de tous les fichiers contenus dans le répertoire
                            '
                            If ModTools.AllFilesInFolder(pathFolder, mTabFiles()) = False Then
                            
                            End If
                            
                        End Sub
                        '
                        'Procédure qui traite tous les fichiers du répertoire
                        Private Sub traiteFichiers()
                        Dim i As Long
                        Dim ext As String
                        
                            'Pour tous les fichiers de mTabFiles()
                            For i = LBound(mTabFiles()) To UBound(mTabFiles())
                                'On extrait l'extension
                                'mTabFiles(i) contient le chemin d'acces et le nom d'un fichier
                                'ex mTabFiles(i) = "C:\MonDossier\MonSousDossier\MonFichier.XLS"
                                ext = ModTools.ExtractFileExt(mTabFiles(i))
                                'Si l'extension est XLS
                                If UCase(ext) = "XLS" Then
                                    'On lance la procédure pour traiter les fichiers Excel
                                    Call traiteXLS(mTabFiles(i))
                                End If
                                'Si l'extension est TXT
                                If UCase(ext) = "TXT" Then
                                    'On lance la procédure pour traiter les fichiers TXT
                                    Call traiteTXT(mTabFiles(i))
                                End If
                            Next i
                            
                        End Sub
                        '
                        'Procédure qui traite les fichier XLS
                        'Elle ouvre le fichier
                        'Elle créé un onglet dans le présent fichier
                        'Elle copie le contenu du fichier dans le nouvel onglet
                        'mPath = le chemin d'acces et le nom d'un fichier
                        '
                        Private Sub traiteXLS(ByVal mPath As String)
                        Dim nom As String
                        Dim wkIn As Workbook
                        Dim wsIn As Worksheet
                        Dim mWk As Workbook
                        Dim mWs As Worksheet
                        
                            'On déclare un objet wkIn et on l'ouvre
                            Set wkIn = Workbooks.Open(mPath)
                            'On déclare un objet wsIn appartenant à wkIn
                            Set wsIn = wkIn.Worksheets(1)
                            'On déclare un nouvel objet worksheet dans le présent fichier.
                            Set mWs = ThisWorkbook.Worksheets.Add(after:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
                        
                            'On extrait le nom du fichier pour nommer le nouvel onglet
                            nom = ModTools.ExtractFileName(mPath)
                            
                            'On active le fichier ouvert et l'onglet
                            wkIn.Activate
                            wsIn.Activate
                            'On copie
                            Range("A1:AA65000").Copy
                            'On colle dans le nouvel onglet
                            mWs.Paste
                            'On nomme le nouvel onglet
                            mWs.Name = Mid(nom, 1, Len(nom) - 4)
                            'On vide le presse papier
                            VideMemoire
                            'on ferme le classeur ouvert
                            wkIn.Close
                            'on libère les objets
                            Set wkIn = Nothing
                            Set wsIn = Nothing
                            Set mWs = Nothing
                        
                            
                        End Sub
                        
                        Private Sub traiteTXT(ByVal mPath As String)
                        
                            'on copie et on renomme le fichier en .xls
                            FileCopy mPath, Replace(UCase(mPath), "TXT", "XLS")
                            'on remplace l'extension du fichier dans le sPath
                            mPath = Replace(UCase(mPath), "TXT", "XLS")
                            'on traite le fichier comme un fichier .XLS
                            Call traiteXLS(mPath)
                            'on supprime le fichier créer
                            Kill (mPath)
                            
                        End Sub
                        
                        Private Sub VideMemoire()
                            OpenClipboard 0
                            EmptyClipboard
                            CloseClipboard
                        End Sub


                        Voilà, j'espère que c'est plus clair pour toi, sinon reviens poser tes questions.

                        ;o)
                        0
                        1. Merci, je comprends un peu mieux, meme si je ne suis pas encore tres familiere avec VBA.

                          Par exemple, dans ta procedure "Private Sub initEnvironnement()", il suffit que tu ecrives "mTabFiles()" en deuxieme position dans "ModTools.AllFilesInFolder()" pour que VBA comprenne ce qu est "mTabFiles" ?

                          Quand je n ai que des .xls dans mon dossier, ca marche impecable. En revanche, j ai un bug avec les .txt (a la ligne "FileCopy mPath, Replace(UCase(mPath), "TXT", "XLS")" il me dit qu il n a pas trouve le chemin - erreur 76). Je vais essayer de voir pourquoi...

                          Sinon, ou est-ce que tu as programme ton "bouton" (je ne sais pas trop comment ca s appelle) "Lancer le Traitement" (il faudrait que je le traduise en anglais ou en allemand ; ))

                          Merci infiniment, Polux31 !
                          0
                          1. Par exemple, dans ta procedure "Private Sub initEnvironnement()", il suffit que tu ecrives "mTabFiles()" en deuxieme position dans "ModTools.AllFilesInFolder()" pour que VBA comprenne ce qu est "mTabFiles" ?


                            La fonction AllFilesInFolder() demande en entrée 2 paramètres pour fonctionner: Le premier paramètre est le chemin d'accès au dossier à scanner, le 2ème paramètre est le tableau qui va stocker les chemins et noms de chaque fichier contenu dans le répertoire.
                            Le premier paramètre est passé par "valeur", c'est à dire le contenu de la variable. Cette variable peut être manipulée et même modifiée à l'intérieur de la fonction sans affecter la valeur initiale de la procédure appelante.

                            Le 2ème paramètre est passé par "référence", c'est à dire que c'est l'adresse mémoire qui est passée (c'est un pointeur dans d'autres langages). Ici on modifie directement le contenu de la variable.

                            Sinon, ou est-ce que tu as programme ton "bouton" (je ne sais pas trop comment ca s appelle) "Lancer le Traitement" (il faudrait que je le traduise en anglais ou en allemand ; ))

                            Dans la barre à outils Excel, il faut affichier le menu Visual Basic. Il faut cliquer sur l'icone qui représente une clé et un marteau pour faire apparître la boîte à outils. Sélectionne le bouton et place le dans la feuille. Pour affecté les propriétés, il faut cliquer sur la main qui pointe une feuille.

                            ;o)
                            0
                        2. Ah bah en fait, apparemment, en remplacant le nom de mon dossier contenant les .txt par un nom sans espace, ca marche.

                          Faut-il que je mette des "" quelquepart dans la cellule C3 pour que ca fonctionne avec un nom a espace ?
                          0
                          1. Non, pas besoin de mettre de "" dans le texte de la cellule.

                            ;o)
                            0
                        3. Merci pour tes explications !

                          Dans la barre à outils Excel, il faut affichier le menu Visual Basic. Il faut cliquer sur l'icone qui représente une clé et un marteau pour faire apparître la boîte à outils. Sélectionne le bouton et place le dans la feuille. Pour affecté les propriétés, il faut cliquer sur la main qui pointe une feuille.

                          Heu... Le bouton avec une cle et un marteau reste grise quoi aue je tente : tu as une idee ? Ensuite, qu entends-tu exactement par "Selectionne le bouton et place-le dans la feuille" ?
                          0
                          1. Peut etre que je peux abuser de ton amabilite aussi en te demandant de jeter un coup d oeil a la sous-procedure que j ai ecrite (ci-dessous) qui devrait me permettre de tracer la courbe I(V) dans chacune des feuilles generees, sachant que chaque fichier contient deux colonnes de chiffres, la premiere pour I et la deuxieme pour V.

                            Quand je fais tourner ce code localement, ca marche, mais en l inserant dans ton code, ca bloque parce que je ne suis pas sure d avoir bien indique le nom de la feuille dans laquelle il fallait inserer le graphique (sachant que cette feuille est variable). Je voudrais lui faire comprendre qu il doit dessiner ce graphe dans la feuille qui est active a l instant t.
                            Je ne sais pas non plus comment lui demander de me mettre le graphe a un certain endroit de la feuille (par exemple entre les cellules E15, E20, J15 et J20.

                            Merci beaucoup !

                            Private Sub DrawCurve()

                            Range("B2:C96").Select
                            Charts.Add
                            ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
                            ActiveChart.SetSourceData Source:=ThisWorkbook.Worksheets(1).Range("B2:C96"), PlotBy:=xlColumns

                            ActiveChart.Location Where:=xlLocationAsObject, Name:=ThisWorkbook.Worksheets(1)

                            With ActiveChart
                            .HasTitle = True
                            .ChartTitle.Characters.Text = "Kennlinie I(V)"
                            .Axes(xlCategory, xlPrimary).HasTitle = True
                            .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Spannung [V]"
                            .Axes(xlValue, xlPrimary).HasTitle = True
                            .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Strom [A]"
                            End With

                            End Sub
                            0
                            1. Le bouton avec une cle et un marteau reste grise

                              Aucune idée ... :o(

                              Ensuite, qu entends-tu exactement par "Selectionne le bouton et place-le dans la feuille" ?

                              En principe, quand tu cliques sur "la clé et le marteau", tu as la boîte à outils Contrôles qui s'ouvre. En passant le pointeur de la souris sur les icônes, tu peux lire le nom des contrôles ...

                              ;o)
                              0
                              1. OK, merci. Je vais essayer de resoudre ce grand mystere ; )

                                Je ne sais pas si tu as vu mon message ci-dessus vu qu on a du ecrire en meme temps...
                                0
                            2. Je viens de voir ...

                              Je te propose de rajouter dans la procédure traiteXLS(), juste après wkIn.Close la ligne suivante :

                              DrawCurve(mWs)

                              et de modifier ta fonction :

                              Private Sub DrawCurve(ByRef ws) 
                              
                              ws.Activate
                              ws.Range("B2:C96").Select 
                              Charts.Add 
                              ActiveChart.ChartType = xlXYScatterSmoothNoMarkers 
                              ActiveChart.SetSourceData Source:=ws.Range("B2:C96"), PlotBy:=xlColumns 
                              
                              ActiveChart.Location Where:=xlLocationAsObject, Name:=ws
                              
                              With ActiveChart 
                                 .HasTitle = True 
                                 .ChartTitle.Characters.Text = "Kennlinie I(V)" 
                                 .Axes(xlCategory, xlPrimary).HasTitle = True 
                                 .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Spannung [V]" 
                                 .Axes(xlValue, xlPrimary).HasTitle = True 
                                 .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Strom [A]" 
                              End With 
                              
                              End Sub


                              Je n'ai pas testé ... :os

                              ;o)
                              0
                              1. Il a fallu que j ecrive "Call DrawCurve(mWs)" pour que ca commence a marcher parce qu avant, il ne comprenait pas. Mais j ai encore une erreur au niveau de la ligne "ActiveChart.Location Where:=xlLocationAsObject, Name:=ws" : il ne comprend pas ou il doit tracer le diagramme donc il me le met en objet dans une feuille annexe.
                                0
                                1. Désolé mais je ne connais pas trop bien Excel et encore moins les graphiques ...

                                  Quelle erreur s'affiche sur la ligne "ActiveChart.Location Where:=xlLocationAsObject, Name:=ws" ?

                                  0
                                  1. Erreur 5 : "Ungültiger Prozeduraufruf oder ungültiges Argument" en allemand, donc ca doit etre qqchose comme "Mauvaise procedure d appel ou mauvais argument"
                                    0
                                2. Bonjour,

                                  Je ne peux t'être d'une grande utilité sur la création de graphique dans Excel.

                                  J'ai trouvé ça sur developpez.com : https://excel.developpez.com/faq/?page=Graphique#GraphCreate

                                  Peut être y trouveras-tu ta réponse.

                                  ;o)
                                  0
                                  1. Oui, je crois que c est de ce code que je m etais inspiree pour creer mon graphe local mais la le probleme reside dans le fait que je trace le graphe sur chaque feuille que j ouvre.

                                    Never mind, je vais tenter de debloquer ca.

                                    Je te remercie infiniment pour tout l aide que tu m as apporte ! C est adorable de ta part.

                                    A bientot peut etre,

                                    Charlotte
                                    0