Lister les fichiers d’un dossier et de ses sous-dossiers
Dans un article précédent intitulé Stocker tous les fichiers d’un répertoire dans une table Access, on a pu voir comment parcourir tous les fichiers d’un dossier, et stocker leur nom ou leur chemin complet dans une table de votre base de données.
Il était bien précisé dans l’article que l’exploration du dossier ne tenait pas compte de ses sous-dossiers. Dans ce nouvel article, on va lister les fichiers d’un dossier et de ses sous-dossiers, sur autant de niveaux de profondeur que nécessaire.
Mise en place
Le principe consiste donc à parcourir une arborescence inconnue de dossiers : on sait de quel dossier on part, mais pas du tout quels sont les sous-dossiers imbriqués. Il va donc falloir utiliser une fonction récursive. Là-dessus se greffe une limitation de VBA 🙁 : les appels de la fonction Dir ne peuvent pas être imbriqués. Avant de commencer, vous devez donc recopier les fonctions suivantes (traitées dans d’autres articles), dans un module standard de votre base…
- La fonction AddBackslash()
- La fonction CompterSousDossiers()
- La fonction ListerSousDossiers()
Lisez aussi l’article Stocker tous les fichiers d’un répertoire dans une table Access pour reprendre la structure de la table où les noms de fichiers seront stockés.
Le code
Le code nécessaire ici est réparti dans 2 procédures : la première est plus globale, et initialise le Recordset qui représentera la table (ceci évite d’ouvrir un nouveau Recordset à chaque dossier parcouru), la seconde s’occupe du parcours récursif. Deux constantes sont également nécessaires, en début de code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
' --- ' CONSTANTES ' --- ' Nom de la table et du champ Public Const TABLE_FICHIERS = "tbl Fichiers" Public Const CHAMP_FICHIER = "Fichier" ' --- ' LISTE DU CONTENU D'UN DOSSIER VERS UNE TABLE ' --- ' Sub ListerFichiersRec( _ ByVal strDossier As String, _ Optional ByVal strExtension As String = "*.*", _ Optional blnViderTable As Boolean = False, _ Optional blnCheminComplet As Boolean = True) ' Variables Dim rst As DAO.Recordset ' Vérifier que le dossier existe bien strDossier = AddBackslash(strDossier) If Dir(strDossier, vbDirectory) = "" Then MsgBox "Dossier introuvable !", vbExclamation Exit Sub End If ' Vider la table si nécessaire If blnViderTable Then CurrentDb.Execute "DELETE FROM [" & TABLE_FICHIERS & "];" End If ' Ouvrir la table Set rst = CurrentDb.OpenRecordset(TABLE_FICHIERS, dbOpenDynaset) ' Déclencher le parcours récursif des fichiers ListerFichiersRecDetail rst, strDossier, strExtension, blnCheminComplet ' On libère les ressources rst.Close Set rst = Nothing End Sub ' --- ' PARCOURS RECURSIF DE DOSSIERS ' --- ' Sub ListerFichiersRecDetail( _ rst As DAO.Recordset, _ ByVal strDossier As String, _ Optional ByVal strExtension As String = "*.*", _ Optional blnCheminComplet As Boolean = True) ' Quelques variables... Dim strFichier As String Dim varSousDossiers As Variant Dim intI As Integer ' Lister tous les fichiers du dossier DoEvents strDossier = AddBackslash(strDossier) strFichier = Dir(strDossier & strExtension, vbNormal) While strFichier <> "" ' Stocker le nom du fichier dans la table rst.AddNew rst(CHAMP_FICHIER) = IIf(blnCheminComplet, _ strDossier & strFichier, _ strFichier) rst.Update ' Lire le fichier suivant strFichier = Dir Wend ' Trouver les sous-dossiers éventuels varSousDossiers = ListerSousDossiers(strDossier) ' S'il y a des sous-dossiers, les parcourir aussi récursivement If (UBound(varSousDossiers) > 0) Then ' Traiter les sous-dossiers For intI = 1 To UBound(varSousDossiers) ListerFichiersRecDetail rst, varSousDossiers(intI), strExtension, blnCheminComplet Next End If End Sub |
Tester le code
La première procédure ci-dessus, est celle qui déclenche la lecture des dossiers. Elle prend les mêmes 4 paramètres que sa variante non récursive :
- Il faut d’abord fournir le chemin du dossier à inspecter. Ce chemin peut se terminer ou non par un anti-slash (ce dernier est de toute façon ajouté automatiquement).
- Donnez ensuite l’extension des fichiers à lister. Par défaut, tous les fichiers sont listés (
*.*
), mais vous pouvez ne lister que les images JPEG (*.jpg
). - Le troisième paramètre vaut
True
si la table cible doit être vidée avant de lister les fichiers, etFalse
sinon. Tout dépend de votre application : est-ce qu’il faut repartir à vide, ou est-ce que vous souhaiter cumuler le résultat de plusieurs listes. - Enfin, le dernier paramètre vaut
True
s’il faut stocker le chemin complet du fichier (dossier + chemin), ouFalse
s’il faut stocker uniquement le nom du fichier.
Par exemple, pour stocker les noms de toutes les images JPG de votre dossier Images :
1 2 3 4 |
Sub TestListerFichiersRec1() ListerFichiersRec "C:\Users\Hervé\Pictures\", "*.jpg", True MsgBox "Terminé !", vbInformation End Sub |
Et pour stocker les noms de tous les fichiers de votre dossier Documents (attention : ça peut faire beaucoup !) :
1 2 3 4 |
Sub TestListerFichiersRec2() ListerFichiersRec "C:\Users\Hervé\Documents", "*.*", True MsgBox "Terminé !", vbInformation End Sub |
Bonjour,
où est la fonction ListerSousDossiers(strDossier) ?
Le paragraphe « Mise en place » donne la liste des différentes fonctions requises. Il suffit de cliquer sur le nom de chacune pour accéder à l’article lié.
Ouala !
[EDIT commentaire du 10/07 à 14h43]
J’ai oublié de préciser que mon principal problème réside visiblement dans les boucles pour parcourir plusieurs dossiers successivement, et aussi dans la fourniture des paramètres (noms des répertoires comme cité précédemment, extensions voulues pour le filtrage) à un invite qui remplace la fourniture en dur des infos ci-dessus dans les 2 procédures de tests ci-dessus.
Bonjour,
Comment faire pour lister les fichiers de plusieurs répertoires à la fois et de leurs sous-répertoires, ces fichiers devant être d’un type bien précis (qui doit pouvoir être personnalisable, et faire l’objet d’une boucle lui aussi) ?
Exemple : j’aimerais parcourir plusieurs répertoires disséminés sur mon disque dur, qui contiennent des sous-répertoires.
Le tout, en ne remontant (et en n’inscrivant dans ma table Access) que les noms complets (chemin complet + nom fichier complet) de fichiers d’extensions vidéos (MP4, FLV, MKV, etc.), donc en filtrant lesdites extensions.
Merci par avance
Si les répertoires ne sont pas tous « enfants » d’un même répertoire de départ, il n’y a pas d’autres moyen que d’appeler plusieurs fois la procédure
ListerFichiersRec
. Par exemple :Le
False
à partir de la 2ème commande fait que la table des fichiers n’est plus vidée (sinon, on perd la liste de fichiers précédente à chaque fois).