TL;DR — Le
FileSystemObject(FSO) est un modèle objet pour le disque : créez-le une fois, puis parcourezFilesetSubFolderset lisez des propriétés commeSizeetDateLastModified. Créez-le en liaison tardive pour qu'il tourne sur toutes les machines — aucune référence à cocher :
Sub ListWithSizes()
Dim fso As Object, folder As Object, file As Object
Set fso = CreateObject("Scripting.FileSystemObject") ' liaison tardive - aucune reference requise
Set folder = fso.GetFolder("C:\Reports")
For Each file In folder.Files ' une vraie collection, pas un curseur
Debug.Print file.Name, file.Size, file.DateLastModified
Next file
End Sub
Là où Dir est un mot-clé intégré et laconique doté d'un unique curseur caché, le
FileSystemObject traite le système de fichiers comme le reste de VBA traite un classeur — comme des
objets dotés de propriétés que vous pouvez parcourir et inspecter. C'est cette montée en gamme que vous
achetez : sous-dossiers, métadonnées de fichiers, et boucles imbriquées sûres. Le prix, c'est un objet à
créer, et une décision — comment vous le liez — qui détermine discrètement si votre macro tourne sur
l'ordinateur de quelqu'un d'autre.
Ce que vous allez apprendre
- Le modèle mental — le système de fichiers vu comme des dossiers et des fichiers, chacun un objet doté de propriétés
- La décision unique qui piège tout le monde —
CreateObject(liaison tardive) contreDim … As New(liaison précoce) - Comment récurser dans les sous-dossiers, ce que
Dirne sait tout simplement pas faire - Lire les métadonnées —
Size,DateLastModified,Name,ParentFolder FileExistsetFolderExists— la façon propre de vérifier avant d'agir- Pourquoi FSO ouvre les fichiers texte mais jamais un classeur Excel
Le modèle mental : le disque comme modèle objet
Partout ailleurs en VBA, vous travaillez avec des objets — un Workbook a des Sheets, un Worksheet a un
Range. Le FileSystemObject étend cette même idée au disque :
- un
fsovous donneGetFolder(path)etGetFile(path) - un
Foldera une collection.Files, une collection.SubFolders, et un.Name - un
Filea.Name,.Size,.DateLastModified,.ParentFolder,.Path
Ainsi, au lieu d'amorcer un curseur et de le faire avancer, vous écrivez la boucle que vous connaissez déjà —
For Each file In folder.Files — et vous atteignez dans chaque objet ce dont vous avez besoin. Il n'y a
aucun état caché, si bien que vous pouvez imbriquer les boucles librement (des fichiers dans des
sous-dossiers dans des sous-dossiers) sans que rien ne se réinitialise sous vos pieds.
La décision unique qui piège tout le monde : CreateObject contre New
Il y a deux façons de fabriquer un fso, et la différence décide si votre macro survit à un envoi par
courriel à un collègue. C'est le bug FileSystemObject numéro un.
Liaison précoce — d'apparence propre, mais fragile :
Dim fso As New FileSystemObject ' necessite Tools > References > Microsoft Scripting Runtime
Cela compile uniquement si cette machine a la référence Microsoft Scripting Runtime cochée. Écrivez-le
sur votre PC où la case est cochée, envoyez le fichier à quelqu'un dont la case ne l'est pas, et il échoue à
compiler avec User-defined type not defined — avant qu'une seule ligne ne s'exécute. Vous obtenez
l'IntelliSense en échange, mais vous avez lié le classeur aux réglages d'une seule machine.
Liaison tardive — le choix par défaut portable :
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject") ' resolue a l'execution, aucune reference
CreateObject recherche le composant par son nom à l'exécution, si bien qu'aucune référence n'est
requise et que le classeur tourne partout où Windows Scripting est installé (c'est-à-dire partout). Vous
perdez l'IntelliSense à la compilation ; vous gagnez une macro qui fonctionne simplement une fois
distribuée. Pour tout ce que vous partagez, utilisez la liaison tardive et déclarez vos variables
As Object. Ce seul choix supprime toute la catégorie des rapports « ça marche sur ma machine ».
Sous-dossiers : ce que Dir ne sait pas faire
La raison la plus claire de laisser Dir derrière soi, c'est une arborescence de dossiers. La collection
SubFolders de FSO plus un Sub récursif parcourt n'importe quelle profondeur, ce que l'unique curseur de
Dir rend impossible :
Sub WalkTree(folderPath As String)
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
ProcessFolder fso.GetFolder(folderPath), fso
End Sub
Sub ProcessFolder(fld As Object, fso As Object)
Dim file As Object, sub_ As Object
For Each file In fld.Files
If LCase(fso.GetExtensionName(file.Name)) = "xlsx" Then Debug.Print file.Path
Next file
For Each sub_ In fld.SubFolders ' recursion - Dir ne peut pas imbriquer ainsi
ProcessFolder sub_, fso
Next sub_
End Sub
Chaque Folder porte ses propres .Files et .SubFolders, si bien que l'imbrication et la récursion sont
sûres — il n'y a aucun curseur partagé à corrompre. Notez fso.GetExtensionName et ses semblables
(GetBaseName, BuildPath, GetParentFolderName) — des utilitaires de chemin sans manipulation de chaînes
qui remplacent le fastidieux découpage à coups d'InStrRev.
Lire les métadonnées : taille, date, nom
L'autre raison de choisir FSO, c'est qu'un objet File sait des choses sur lui-même que Dir n'expose
jamais :
For Each file In folder.Files
If file.DateLastModified < Now - 30 Then ' plus vieux que 30 jours
Debug.Print file.Name & " - " & Format(file.Size / 1024, "0") & " KB"
End If
Next file
Size, DateLastModified, DateCreated, Type, Attributes — tous à une propriété de distance. Filtrer
« chaque classeur modifié cette semaine » ou « supprimer les fichiers temporaires de plus de 10 Mo » est
trivial avec FSO et pénible avec Dir.
FileExists et FolderExists : vérifier avant d'agir
FSO vous donne deux prédicats sans état qui sont la façon la plus propre de
tester la présence d'un fichier — et, ce qui est crucial, ils n'ont
aucun curseur caché, si bien que contrairement à Dir, vous pouvez les appeler n'importe où, même à
l'intérieur d'une boucle Dir :
If fso.FileExists("C:\Reports\March.xlsx") Then ...
If fso.FolderExists("C:\Reports\2026") Then ...
FileExists et FolderExists sont distincts — Dir confond les deux — si bien que vous dites exactement ce
que vous voulez dire et ne correspondez jamais par accident à un dossier alors que vous vouliez un fichier.
Le piège : FSO n'ouvre pas les classeurs
Voici la confusion qui fait tourner les gens en rond. Le FileSystemObject peut créer, lire et écrire des
fichiers texte bruts (CreateTextFile, OpenTextFile) — des journaux, des CSV traités comme du texte
brut, des fichiers .ini. Il peut faire CopyFile, MoveFile, DeleteFile. Ce qu'il ne peut pas
faire, c'est ouvrir un classeur Excel :
Set wb = fso.OpenTextFile("C:\Reports\March.xlsx") ' FAUX - vous obtenez des octets XML/zip bruts, pas un classeur
Set wb = Workbooks.Open("C:\Reports\March.xlsx") ' CORRECT - un classeur est ouvert par Excel, pas par FSO
FSO trouve et gère les fichiers ; c'est Workbooks.Open qui transforme un
fichier en classeur vivant dont vous pouvez lire les cellules. La macro par lots idiomatique utilise les
deux : FSO (ou Dir) pour énumérer le dossier, puis Workbooks.Open pour ouvrir chaque résultat.
Gardez les deux tâches séparées dans votre tête et tout le motif s'emboîte.
Le verdict honnête : quand FSO surpasse Dir
Dir l'emporte sur un seul axe — zéro installation pour une boucle plate sur un seul dossier. Le
FileSystemObject l'emporte partout ailleurs, et la décision est mécanique :
- Besoin de sous-dossiers ? FSO —
Dirne sait pas récurser. - Besoin de la taille, de la date ou du type ? FSO —
Dirne renvoie qu'un nom. - Copier, déplacer, supprimer, ou écrire des fichiers texte ? FSO — c'est une boîte à outils complète.
- Une boucle rapide
*.xlsxsur un seul dossier sans rien ajouter ?Dirconvient et il est plus court. - Quelle que soit la façon d'énumérer, ouvrez les classeurs avec
Workbooks.Open— jamais avec FSO.
Et quel que soit celui que vous distribuez, créez l'objet avec CreateObject, pas New, pour qu'il
tourne sur toutes les machines et pas seulement la vôtre.
Comment ExcelMaster aide
Le FileSystemObject est puissant précisément parce qu'il est un modèle objet — mais cela signifie penser à
le lier tardivement pour la portabilité, à récurser SubFolders pour une arborescence, à lire la bonne
propriété de métadonnée, et à confier chaque fichier à Workbooks.Open plutôt que d'attendre de FSO qu'il
l'ouvre. De petits choix, dont chacun décide discrètement si la macro tourne sur le PC de la personne
suivante.
ExcelMaster fait ces choix
pour vous. Décrivez la tâche — « parcours chaque sous-dossier sous Reports, trouve les classeurs modifiés ce
mois-ci, et copie leurs totaux dans une synthèse » — et il écrit un parcours FSO à liaison tardive avec la
boucle récursive SubFolders, le filtre DateLastModified, et un Workbooks.Open /
Close correspondant pour chaque résultat. Vous décrivez le résultat ; il
assemble le modèle objet correctement du premier coup.
Questions fréquentes
Qu'est-ce que le FileSystemObject en VBA ?
Le FileSystemObject (FSO) est un composant Windows Scripting qui expose le système de fichiers comme un
modèle objet — des objets Folder et File avec des collections (Files, SubFolders) et des propriétés
(Name, Size, DateLastModified). Vous le créez avec CreateObject("Scripting.FileSystemObject") et
l'utilisez pour énumérer, copier, déplacer, supprimer et lire des fichiers texte. Contrairement à
Dir, il n'a aucun curseur caché, si bien que les boucles s'imbriquent sans danger.
CreateObject ou Dim As New FileSystemObject — lequel utiliser ?
Utilisez Set fso = CreateObject("Scripting.FileSystemObject") (liaison tardive). Il n'exige aucune
référence et tourne sur n'importe quelle machine. Dim fso As New FileSystemObject (liaison précoce) exige
que la référence Microsoft Scripting Runtime soit cochée sous Tools ▸ References, si bien qu'un classeur
qui compile sur votre PC échoue avec User-defined type not defined sur celui d'un collègue. La liaison
tardive est le choix par défaut portable pour tout ce que vous distribuez.
Comment parcourir les sous-dossiers avec le FileSystemObject ?
Obtenez le dossier avec fso.GetFolder(path), parcourez sa collection .SubFolders, et appelez la même
routine récursivement sur chaque sous-dossier. Parce que chaque Folder a ses propres .Files et
.SubFolders, la récursion est sûre — il n'y a aucun état partagé à réinitialiser. C'est exactement ce que
Dir ne sait pas faire.
Le FileSystemObject peut-il ouvrir un classeur Excel ?
Non. FSO ouvre et écrit des fichiers texte (OpenTextFile, CreateTextFile) et peut copier, déplacer ou
supprimer n'importe quel fichier, mais il ne peut pas ouvrir un classeur. Utilisez-le pour trouver les
fichiers, puis ouvrez chacun avec Workbooks.Open. fso.OpenTextFile sur un
.xlsx renvoie des octets bruts, pas un classeur.
Comment obtenir la taille ou la date de modification d'un fichier en VBA ?
Utilisez le FileSystemObject : fso.GetFile(path).Size renvoie les octets et .DateLastModified renvoie
l'horodatage. À l'intérieur d'une boucle de dossier, lisez file.Size et file.DateLastModified directement
sur chaque objet File. Dir ne peut vous donner ni l'un ni l'autre — il ne renvoie que le nom — ce qui est
l'une des principales raisons de préférer FSO pour tout ce qui dépasse une liste plate.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 21/08/2026.
Guides associés : VBA Dir · VBA Check If File Exists · VBA Open Workbook · VBA Save Workbook · VBA On Error
