TL;DR —
Dirn'est pas une simple fonction. Le premier appel passe un chemin et obtient le premier nom de fichier correspondant ; chaque appel suivant ne passe rien et obtient le nom suivant, jusqu'à ce qu'il renvoie"". La boucle ressemble donc à ceci — et vous ne devez jamais y rappelerDir:
Sub ListWorkbooks()
Dim folder As String, name As String
folder = "C:\Reports\"
name = Dir(folder & "*.xlsx") ' premier appel : amorcer la recherche
Do While name <> ""
Debug.Print folder & name ' Dir renvoie le NOM seul - prefixez le dossier
name = Dir() ' sans argument : la correspondance SUIVANTE
Loop
End Sub
À l'instant où votre macro doit traiter beaucoup de fichiers — consolider douze classeurs régionaux,
importer chaque CSV d'un dossier de dépôt — vous vous tournez vers Dir. C'est le mot-clé intégré qui
n'exige aucune référence et aucune installation. Mais il cache une conception qui piège presque tout le
monde : Dir se souvient d'où il en était, globalement, et une seconde recherche efface cette mémoire
en silence. Comprenez ce seul fait et chaque bug du type « il a sauté la moitié de mes fichiers »
disparaît.
Ce que vous allez apprendre
- Le modèle mental —
Direst un itérateur à état déguisé en fonction - La règle unique qui piège tout le monde — ne jamais rappeler
Dirau milieu d'une boucleDir - Pourquoi
Dirne renvoie que le nom de fichier, et pourquoi vous devez préfixer le dossier vous-même - Le caractère générique (
*.xlsx) et commentDirgère l'absence de correspondance ("", pas une erreur) - Pourquoi
Dirne peut pas récurser dans les sous-dossiers — et quoi utiliser à la place - Pourquoi vous devriez d'abord rassembler les noms dans un tableau, puis ouvrir/déplacer/supprimer les fichiers
Le modèle mental : Dir est un itérateur, pas une consultation
La plupart des fonctions renvoient la même réponse chaque fois que vous les appelez avec la même entrée.
Pas Dir. Il conserve un unique curseur caché, à l'échelle du module, pointant vers une seule
recherche de dossier :
Dir("C:\Reports\*.xlsx")— l'argument lance une nouvelle recherche et renvoie la première correspondance.Dir()— sans argument, fait avancer la même recherche et renvoie la correspondance suivante.- Quand il ne reste plus rien,
Dir()renvoie une chaîne vide"".
Voyez-le comme un curseur que vous amorcez une fois, puis que vous faites avancer pas à pas. La boucle
Do While name <> "" ci-dessus en est la forme canonique : amorcez avec le chemin, puis appelez le Dir()
sans argument au bas de chaque passage. C'est tout le motif, et c'est la forme que vous devriez mémoriser.
La règle qui piège tout le monde : ne pas appeler Dir dans une boucle Dir
Parce qu'il n'y a qu'un seul curseur caché, appeler Dir avec un argument où que ce soit à l'intérieur
de la boucle lance une recherche toute neuve et jette votre position aux oubliettes. C'est le bug Dir
numéro un, et il est sournois parce qu'il paraît tout à fait raisonnable :
name = Dir(folder & "*.xlsx")
Do While name <> ""
If Dir(folder & "flag.txt") <> "" Then ' <- DESASTRE : reinitialise le curseur
Process folder & name
End If
name = Dir() ' continue desormais la recherche "flag.txt", pas la recherche *.xlsx
Loop
Le Dir(folder & "flag.txt") interne relance le moteur sur un motif différent. Quand la boucle appelle
ensuite Dir(), elle fait avancer cette recherche — si bien que vous traitez les mauvais fichiers, sautez
la plupart de vos fichiers .xlsx, ou tournez indéfiniment. La règle est absolue : à l'intérieur d'une
boucle Dir, le seul Dir que vous avez le droit d'appeler est le Dir() sans argument. Si vous devez
tester la présence d'un autre fichier en cours de boucle, utilisez plutôt
FileSystemObject.FileExists — il n'a aucun curseur partagé à
corrompre.
Dir renvoie le nom, pas le chemin
Dir vous rend le nom de fichier nu — March.xlsx, pas C:\Reports\March.xlsx. L'oublier est la deuxième
erreur la plus fréquente, car la chose que vous faites juste après, c'est généralement ouvrir le fichier :
Set wb = Workbooks.Open(name) ' error 1004 - "March.xlsx" n'est pas un chemin complet
Set wb = Workbooks.Open(folder & name) ' correct - reconstruire le chemin complet
Gardez toujours la chaîne du dossier à part et reconcaténez-la quand vous avez besoin du chemin complet.
C'est aussi pourquoi la variable de dossier se termine par une barre oblique inverse ("C:\Reports\") —
ainsi folder & name est un chemin valide sans séparateur manquant.
Le caractère générique et le cas « aucune correspondance »
L'argument du premier Dir est un chemin plus un motif. * correspond à n'importe quelle suite de
caractères, ? à un seul caractère :
Dir("C:\Reports\*.xlsx")— tous les.xlsxdu dossierDir("C:\Reports\Q?-2026.xlsx")—Q1-2026.xlsx,Q2-2026.xlsx, …Dir("C:\Reports\March.xlsx")— aucun caractère générique, il teste donc un seul fichier : renvoie"March.xlsx"s'il existe,""sinon (c'est le comportement d'une ligne derrière la vérification de l'existence d'un fichier)
Si rien ne correspond, Dir renvoie "" — il ne lève pas d'erreur. Voilà pourquoi Do While name <> ""
gère à la fois « aucun fichier du tout » et « fin atteinte » avec le même test.
Un piège : par défaut, Dir correspond aussi aux dossiers et ignore les fichiers cachés/système. Si un
sous-dossier se trouve correspondre à votre motif, vous pouvez récupérer son nom aussi. Quand cela compte,
passez explicitement l'attribut vbNormal ou vérifiez avec le
FileSystemObject.
Dir ne sait pas récurser — et modifier le dossier en cours de boucle le corrompt
Deux limites strictes vous éloignent de Dir dès que vous voulez autre chose qu'une liste plate :
Il n'est pas récursif. Dir parcourt un dossier. Il n'y a aucun argument pour descendre dans les
sous-dossiers, et vous ne pouvez pas imbriquer deux boucles Dir (un seul curseur, rappelez-vous). Pour
traiter une arborescence — C:\Reports\2026\Q1\..., Q2\... — il vous faut le
FileSystemObject, dont la collection SubFolders est faite pour la
récursion.
Modifier le dossier pendant la boucle casse l'énumération. Si vous faites Kill, renommez, déplacez, ou
même Open puis SaveAs des fichiers pendant une boucle Dir, vous mutez le dossier même que le curseur
caché est en train de parcourir. Des noms sont sautés ou répétés. Le correctif est un motif en deux passes —
rassembler d'abord, agir ensuite :
Dim names() As String, n As Long
ReDim names(1 To 1000)
Dim f As String: f = Dir(folder & "*.xlsx")
Do While f <> "" ' passe 1 : rassembler uniquement les noms
n = n + 1: names(n) = f
f = Dir()
Loop
Dim i As Long
For i = 1 To n ' passe 2 : desormais on peut ouvrir / deplacer / supprimer
Process folder & names(i)
Next i
Une fois les noms dans un tableau, le curseur fragile a fini son travail et vous pouvez faire ce que vous voulez des fichiers.
Le verdict honnête : à quoi sert vraiment Dir
Dir est le bon outil pour exactement une tâche — une boucle rapide et plate sur les fichiers d'un seul
dossier, sans référence à ajouter ni objet à créer. Pour « exécuter cette macro sur chaque .xlsx de ce
dossier », il est plus court et plus rapide que tout le reste. Cantonnez-le à cela, et suivez quatre règles :
- Amorcez une fois, avancez avec
Dir()— le seulDirà l'intérieur de la boucle ne prend aucun argument. - Préfixez le dossier —
Dirrenvoie des noms ;folder & namereconstruit le chemin. - Deux passes quand vous mutez — rassemblez les noms dans un tableau, puis ouvrez/déplacez/supprimez.
- Passez au
FileSystemObjectdès que vous avez besoin des sous-dossiers, de la taille ou de la date d'un fichier, ou d'une seconde vérification d'existence en cours de boucle.
À l'instant où vous vous surprenez à vouloir un second Dir dans la même boucle, c'est le signal que vous
avez dépassé Dir — non pas un bug à rustiner, mais un outil à changer.
Comment ExcelMaster aide
Réussir une boucle de fichiers, c'est amorcer Dir une fois, avancer avec l'appel sans argument,
reconstruire les chemins complets, et savoir quand la mutation du dossier impose un tableau en deux passes —
une quantité surprenante de cérémonie pour « juste parcourir les fichiers d'un dossier », et un seul Dir
égaré casse discrètement l'ensemble.
ExcelMaster écrit la boucle pour vous.
Décrivez la tâche — « ouvre chaque classeur de ce dossier, extrais les totaux, et ferme chacun » — et il
produit une boucle Dir correcte (ou un parcours FileSystemObject quand il vous faut les sous-dossiers),
avec la concaténation du dossier, le tableau en deux passes quand des fichiers sont déplacés, et un
wb.Close correspondant à chaque itération. Vous décrivez le résultat ; il
gère la mémoire de l'itérateur pour qu'elle ne vous morde jamais.
Questions fréquentes
Comment parcourir tous les fichiers d'un dossier en VBA ?
Amorcez Dir avec un chemin et un caractère générique, puis avancez avec le Dir() sans argument :
name = Dir("C:\Reports\*.xlsx"), puis Do While name <> "" … name = Dir() … Loop. Dir renvoie chaque
nom de fichier à tour de rôle et "" quand le dossier est épuisé. Rappelez-vous que Dir ne renvoie que le
nom, donc utilisez folder & name quand vous avez besoin du chemin complet.
Pourquoi ma boucle Dir en VBA saute-t-elle des fichiers ou tourne-t-elle sans fin ?
Presque toujours parce que vous avez appelé Dir avec un argument à l'intérieur de la boucle. Dir
conserve un unique curseur caché, et tout Dir(unChemin) lance une nouvelle recherche qui efface votre
position — le Dir() en bas de boucle fait alors avancer la mauvaise recherche. À l'intérieur d'une boucle
Dir, n'appelez jamais que le Dir() sans argument. Pour tester un autre fichier en cours de boucle,
utilisez FileSystemObject.FileExists, qui n'a aucun état partagé.
Dir en VBA cherche-t-il dans les sous-dossiers ?
Non. Dir parcourt un seul dossier et n'a aucune récursion, et vous ne pouvez pas imbriquer deux boucles
Dir car il n'existe qu'un seul curseur. Pour parcourir une arborescence de dossiers, utilisez le
FileSystemObject et itérez récursivement sa collection SubFolders.
Comment obtenir le chemin complet à partir de Dir en VBA ?
Dir renvoie le nom de fichier nu (March.xlsx), pas le chemin complet. Gardez le dossier dans sa propre
variable (terminée par une barre oblique inverse) et concaténez : folder & name donne
C:\Reports\March.xlsx. Passer le nom nu à Workbooks.Open lève l'erreur d'exécution 1004.
Dois-je utiliser Dir ou FileSystemObject pour parcourir des fichiers ?
Utilisez Dir pour une boucle rapide et plate sur un seul dossier, sans installation. Passez au
FileSystemObject quand vous avez besoin de descendre dans les
sous-dossiers, de lire la taille ou la date de modification de chaque fichier, ou de vérifier la présence
d'autres fichiers pendant la boucle — tout ce où l'unique curseur caché de Dir vous gêne.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 21/08/2026.
Guides associés : VBA FileSystemObject · VBA Check If File Exists · VBA Open Workbook · VBA Close Workbook · VBA For Loop
