lister répertoire (amélioration du code)

francedemo

XLDnaute Occasionnel
bonjour à tous,
grâce au forum, j'ai assemblé de plusieurs sources un code qui fonctionne bien pour lister les fichiers d'un répertoire avec informations sur le contenu de chaque fichier (en fait, ça crée un sorte de BdD pour récapituler des données)

voici le code utilisé
Code:
Sub ListeFichiersContenu()
'macro par francedemo

Dim Fichier As String
Dim NomFichier As String
Dim Chemin As String
Dim Derligne As Long
Dim DerLigneA As Long

debut = Timer 'ça permet de voir le temps passé

Workbooks("ListeDevis.xls").Activate
'===Nettoyer la zone et sélectionner la cellule de début
Range("A2:F65536").Clear
Range("A2").Activate
'===Saisir le chemin complet du dossier où se trouvent les fichiers
Chemin = "\\Serveur\DATA\CARDIO\SAV\DevisSAV\"
'===Premier fichier
Fichier = Dir(Chemin & "*.xls")
Do While Fichier <> ""
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    Application.EnableEvents = False
    If Fichier <> "ListeDevis.xls" Then
        Workbooks.Open Filename:=Chemin & Fichier
'===Inserer lien hypertexte "Lien Fichier" + Copie de "Livraison"
        Windows(Fichier).Activate
        Range("G6").Copy
        Workbooks("ListeDevis.xls").Activate
        Sheets("Base").Select
        Derligne = Range("F65536").End(xlUp).Row + 1
        NomFichier = Left(Fichier, Len(Fichier) - 5)
        ActiveWorkbook.ActiveSheet.Hyperlinks.Add _
            Anchor:=Cells(Derligne, 1), Address:=Chemin & Fichier, _
            TextToDisplay:=NomFichier
        Range("B" & Derligne).PasteSpecial _
            Paste:=xlPasteValuesAndNumberFormats, _
            Operation:=xlNone, _
            SkipBlanks:=False, _
            Transpose:=False
'===Copie de "Facturation"
        Windows(Fichier).Activate
        Range("Q6").Copy
        Workbooks("ListeDevis.xls").Activate
        Sheets("Base").Select
        Range("C" & Derligne).PasteSpecial _
            Paste:=xlPasteValuesAndNumberFormats, _
            Operation:=xlNone, _
            SkipBlanks:=False, _
            Transpose:=False
'===Copie de "matériel"
        Windows(Fichier).Activate
        Range("H3").Copy
        Workbooks("ListeDevis.xls").Activate
        Sheets("Base").Select
        Range("D" & Derligne).PasteSpecial _
            Paste:=xlPasteValues, _
            Operation:=xlNone, _
            SkipBlanks:=False, _
            Transpose:=False
'===Copie de "Nb"
        Windows(Fichier).Activate
        Range("A13:A23").Copy
        Workbooks("ListeDevis.xls").Activate
        Sheets("Base").Select
        Range("E" & Derligne).PasteSpecial _
            Paste:=xlPasteValues, _
            Operation:=xlNone, _
            SkipBlanks:=False, _
            Transpose:=False
'===Copie de "Désignation"
        Windows(Fichier).Activate
        Range("B13:B23").Copy
        Workbooks("ListeDevis.xls").Activate
        Sheets("Base").Select
        Range("F" & Derligne).PasteSpecial _
            Paste:=xlPasteValues, _
            Operation:=xlNone, _
            SkipBlanks:=False, _
            Transpose:=False
'===Insérer une ligne après chaque fichier
        Derligne = Range("F65536").End(xlUp).Row
        Range("A" & Derligne, "F" & Derligne).Select
        With Selection.Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .Weight = xlMedium
            .ColorIndex = 6
        End With
'===Fermeture du fichier Devis ouvert
        Windows(Fichier).Activate
        Application.CutCopyMode = False
        ActiveWorkbook.Close savechanges:=False
'===Fichier suivant
    End If
    Fichier = Dir
Loop
'===Fin de la boucle
Workbooks("ListeDevis.xls").Activate
'===Nettoyage des lignes vides
Sheets("Base").Select
For n = Derligne + 10 To 2 Step -1
    If Range("F" & n) = "" Then Rows(n).Delete
Next n
'===Mise en forme des colonnes
Range("A2", "A" & Derligne + 1).ColumnWidth = 50
Range("B2", "C" & Derligne + 1).ColumnWidth = 40
Range("D2", "D" & Derligne + 1).ColumnWidth = 25
Range("E2", "F" & Derligne + 1).EntireColumn.AutoFit
With Selection.Font
    .Name = "Arial"
    .Size = 12
End With

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.CutCopyMode = False
Range("A2").Activate

MsgBox ("Terminé en " & Timer - debut & " seconde(s)")

End Sub

comme vous pouvez le voir dans le code, je fais des aller-retour entre le fichier ouvert à l'instant "t" et le fichier récap.
je voudrai savoir s'il n'existe pas une autre façon de faire pour éviter ces aller-retour gourmand en temps (la macro mets 90 sec pour faire le boulot sur mon répertoire qui n'est pas très gros = 140 fichiers)

d'avance merci
 

mromain

XLDnaute Barbatruc
Re : lister répertoire (amélioration du code)

Bonjour francedemo,

Les .Select, ou autre .Activate ralentissent la macro.

Tu peux les éviter en changeant ces lignes :
Code:
Windows(Fichier).Activate
Range("A13:A23").Copy
Workbooks("ListeDevis.xls").Activate
Sheets("Base").Select
Range("E" & Derligne).PasteSpecial _
    Paste:=xlPasteValues, _
    Operation:=xlNone, _
    SkipBlanks:=False, _
    Transpose:=False
par celle-ci :
Code:
Workbooks("ListeDevis.xls").Sheets("Base").Range("E" & Derligne & ":E" & Derligne + 10).Value = Windows(Fichier).Range("A13:A23").Value
Cela évite également le Copier / Collage Spécial.

Si tu fais ces modifications sur l'ensemble de la macro, tu devrais gagner du temps.
Il serait d'ailleurs intéressant de voir combien de temps tu gagnes...

a+
 

mromain

XLDnaute Barbatruc
Re : lister répertoire (amélioration du code)

Re,

bon, j'ai fais les modifs de code mais excel me répond :
"erreur 438 - propriété ou méthode non gérée par cet objet"

Sur quelle ligne de ton code ?
Sinon, il y a sûrement moyen d'écrire la macro autrement, mais il faudrait des fichiers exemples avec tes besoins bien expliqués.
(C'est plus facile -pour moi- de partir de 0, plutôt que de débugger/arranger un code existant)

a+
 

francedemo

XLDnaute Occasionnel
Re : lister répertoire (amélioration du code)

tu as raison, la macro fait pas mal de choses :)

1 - comme c'est un fichier "vivant", elle commence par tout nettoyer (sauf la première ligne)
2 - elle va chercher tous les fichiers du répertoire indiqué (sauf le fichier "listedevis.xls" qui est la récap)
3- dans chaque fichier, elle récupère dans l'ordre =
=> le nom du fichier ==> colonne A sous forme de lien hypertexte (avec affichage du nom seul)
=> la valeur de la cellule G6 pour l'adresse de livraison
=> la valeur de la cellule Q6 pour la facturation
=> la valeur de la cellule H3 pour le type de matériel concerné
=> les valeurs des cellules A13:A23 pour les nb
=> les valeurs des cellules B13:B23 pour les désignations
pour la suite, je dois pouvoir faire seul mais pour info
=> pour faciliter la lecture, insérer une ligne gras/jaune sous chaque changement de fichier
=> mise en forme des colonnes

voilà, tout ça par un click sur le bouton "mise à jour" !!!

c'est pas mal non ?
 

mromain

XLDnaute Barbatruc
Re : lister répertoire (amélioration du code)

Re,

Voici un essai :
VB:
Sub RefreshBase()
Dim feuilleBase As Excel.Worksheet, classeur As Excel.Workbook
Dim curLigne As Long, nbLignes As Long, Chemin As String


    '===Saisir le chemin complet du dossier où se trouvent les fichiers
    Chemin = "\\Serveur\DATA\CARDIO\SAV\DevisSAV\"


    'définir la feuille "Base"
    Set feuilleBase = ThisWorkbook.Sheets("Base")
    'effacer les données de la feuille base
    feuilleBase.Range("A1").CurrentRegion.Offset(1, 0).Clear
    'initialiser la ligne d'écriture
    curLigne = 2
    
    
    '===Premier fichier
    Fichier = Dir(Chemin & "*.xls")
    Do While Fichier <> ""
        If Fichier <> "ListeDevis.xls" Then
        'ouvrir le classeur
            Set classeur = Application.Workbooks.Open(Chemin & Fichier)
            
            'inscrire en colonne A le lien hypertexte
            feuilleBase.Hyperlinks.Add feuilleBase.Range("A" & curLigne), classeur.Path & "\" & classeur.Name, , , Left(classeur.Name, Len(classeur.Name) - 4)
            'inscrire l'adresse de livraison
            feuilleBase.Range("B" & curLigne).Value = classeur.Sheets(1).Range("G6").Value
            'inscrire la facturation
            feuilleBase.Range("C" & curLigne).Value = classeur.Sheets(1).Range("Q6").Value
            'inscrire le type de matériel concerné
            feuilleBase.Range("D" & curLigne).Value = classeur.Sheets(1).Range("H3").Value
            
            'calculer le nombre de lignes Nb/Désignation/Référence du fichier
            If classeur.Sheets(1).Range("A20").Text <> "" Then
                nbLignes = 8
            Else
                nbLignes = classeur.Sheets(1).Range("A20").End(xlUp).Row - 12
            End If
            'copier les données Nb/Désignation
            feuilleBase.Range("E" & curLigne).Resize(nbLignes, 2).Value = classeur.Sheets(1).Range("A13").Resize(nbLignes, 2).Value
            
            'incrémenter la ligne d'écriture
            curLigne = curLigne + nbLignes
            
            'colorier en jaune la ligne suivante
            feuilleBase.Range("A" & curLigne & ":F" & curLigne).Interior.Color = 65535
            
            'incrémenter la ligne d'écriture (pour le classeur suivant
            curLigne = curLigne + 1
            
            'fermer le fichier (sans enregistrer les modifications)
            classeur.Close False
    
    '===Fichier suivant
        End If
        Fichier = Dir
        
    Loop
    
    '===Mise en forme des colonnes
    feuilleBase.Range("A2").ColumnWidth = 50
    feuilleBase.Range("B2", "C2").ColumnWidth = 40
    feuilleBase.Range("D2").ColumnWidth = 25
    feuilleBase.Range("E2:F2").EntireColumn.AutoFit
    With feuilleBase.Range("A2:F" & curLigne - 1).Font
        .Name = "Arial"
        .Size = 12
    End With


End Sub
Je l'ai testé sur un fichier. La macro fonctionnait alors.
J'ai rajouté ta boucle sur les fichiers xls du répertoire, mais ensuite, je n'avais pas de données pour tester.


a+
 
Dernière édition:

francedemo

XLDnaute Occasionnel
Re : lister répertoire (amélioration du code)

re

j'ai continué à chercher de mon coté pour valider ton code, j'ai essayé avec :

Code:
Workbooks("ListeDevis.xls").Sheets("Base").Range("E" & Derligne & ":E" & Derligne + 10).Value = Workbooks(Fichier).Sheets("Base").Range("A13:A23").Value

là, ça fonctionne, du coup j'ai fais la modif sur tous les paramètres concernés

et là j'ai mon fichier en 38 sec !!! (et à jour!!! :D)

bon, je vais essayer ton nouveau code

à+
 

francedemo

XLDnaute Occasionnel
Re : lister répertoire (amélioration du code)

bonjour à tous,
je reviens pour donner suite à mon post :
après quelques ajustements sur certains codes, tout semble ok, j'ai le bon résultat !!!:)

je vous mets ci dessous le code commenté si ça peut aider quelqu'un (à adapter, bien sur, aux besoins réels)
Code:
Sub ListeFichiersContenu()
'macro par francedemo

Dim Fichier As String
Dim FichierBase As String
Dim FichierNom As String
Dim Chemin As String
Dim DerLigne As Long
Dim DerLigneA As Long
Dim FeuilleBase As Excel.Worksheet

'à utiliser pour visualiser la durée de la macro
debut = Timer

FichierBase = ThisWorkbook.Name
Set FeuilleBase = ThisWorkbook.Sheets("Base")

'===Nettoyer la feuille (sauf la première ligne) et sélectionner la cellule de début
FeuilleBase.Range("A1").CurrentRegion.Offset(1, 0).Clear

'===Saisir le chemin complet du dossier où se trouvent les fichiers
Chemin = "\\Serveur\xxx\xxx\xxx\xxx\"

'===Valider le premier fichier
Fichier = Dir(Chemin & "*.xls")
Do While Fichier <> ""
'===Désactiver les affichages et les macros
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    Application.EnableEvents = False
'===Valider les variables
    DerLigne = FeuilleBase.Range("F65536").End(xlUp).Row + 1
'===Autoriser le traitement sur tous les fichiers sauf celui en cours
    If Fichier <> FichierBase Then
        Workbooks.Open Filename:=Chemin & Fichier
        FichierNom = Left(Fichier, Len(Fichier) - 5) 'nota => ".xls" fait 4 caractères (moi, j'ai besoin de 5)

'===Inserer un lien hypertexte "Lien Fichier" + Copier "Livraison"
        FeuilleBase.Hyperlinks.Add _
            FeuilleBase.Range("A" & DerLigne), Chemin & Fichier, , , FichierNom
        FeuilleBase.Range("B" & DerLigne).Value = _
            Workbooks(Fichier).Sheets("Base").Range("G6").Value
'===Copier "Facturation"
        FeuilleBase.Range("C" & DerLigne).Value = _
            Workbooks(Fichier).Sheets("Base").Range("Q6").Value
'===Copier "Matériel"
        FeuilleBase.Range("D" & DerLigne).Value = _
            Workbooks(Fichier).Sheets("Base").Range("H3").Value
'===Copier "Nb" + "Désignation"
        FeuilleBase.Range("E" & DerLigne & ":F" & DerLigne + 10).Value = _
            Workbooks(Fichier).Sheets("Base").Range("A13:B23").Value

'===Nettoyer les lignes vides (boucle sur la dernière insertion)
        FeuilleBase.Activate
'===Valider les variables
        DerLigneA = FeuilleBase.Range("F65536").End(xlUp).Row
        For n = DerLigneA + 1 To DerLigne Step -1
            If Range("F" & n) = "" Or Range("F" & n) = "Désignation*hors référence :" Then
                Rows(n).Delete
            End If
        Next n
'===Valider les variables
        DerLigne = FeuilleBase.Range("F65536").End(xlUp).Row
'===Inserer une ligne *Gras* + *Jaune* sous chaque bloc inséré
        With FeuilleBase.Range("A" & DerLigne, "F" & DerLigne).Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = 6
        End With
       
'===Fermer le fichier Devis ouvert
        Windows(Fichier).Activate
        Application.CutCopyMode = False
        ActiveWorkbook.Close savechanges:=False
'===Valider le fichier suivant
    End If
    Fichier = Dir
Loop
'===Valider la fin de la boucle

'==Mettre en forme les colonnes
FeuilleBase.Activate
Columns("A:A").ColumnWidth = 50
Columns("B:C").ColumnWidth = 40
Columns("D:D").ColumnWidth = 25
Columns("E:F").EntireColumn.AutoFit

'===Mettre en forme les cellules
With Selection.Font
    .Name = "Arial"
    .Size = 12
End With

'===Activer les affichages + macros
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.CutCopyMode = False

Range("A2").Activate

MsgBox ("Terminé en " & Timer - debut & " seconde(s)")

End Sub

donc la macro fait =
- ouvrir tous les fichiers d'un répertoire (sauf celui en cours)
- recopier dans l'ordre :
- le nom du fichier (en lien hypertexte)
- recopier certaine cellules (moi, c'est "facturation", "livraison", "nb" et "désignation")
- supprimer les lignes vides (qui ne servent à rien)
- insérer une ligne en jaune gras pour faciliter la lecture en dessous de chaque bloc-fichier
- mettre en forme les colonnes pour que ce soit lisible

ça fonctionne :)

et surtout un grand merci à mromain pour l'aide apportée
 

Discussions similaires

Réponses
5
Affichages
136
Réponses
2
Affichages
127

Statistiques des forums

Discussions
312 361
Messages
2 087 625
Membres
103 608
dernier inscrit
rawane