🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Dir dans Excel — parcourir les fichiers d'un dossier, et l'itérateur à état qui vous piège

|

VBA Dir dans Excel — parcourir les fichiers d'un dossier, et l'itérateur à état qui vous piège

TL;DRDir n'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 rappeler Dir :

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 — Dir est un itérateur à état déguisé en fonction
  • La règle unique qui piège tout le monde — ne jamais rappeler Dir au milieu d'une boucle Dir
  • Pourquoi Dir ne 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 comment Dir gère l'absence de correspondance ("", pas une erreur)
  • Pourquoi Dir ne 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 .xlsx du dossier
  • Dir("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 seul Dir à l'intérieur de la boucle ne prend aucun argument.
  • Préfixez le dossierDir renvoie des noms ; folder & name reconstruit le chemin.
  • Deux passes quand vous mutez — rassemblez les noms dans un tableau, puis ouvrez/déplacez/supprimez.
  • Passez au FileSystemObject dè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