Рекурсивный обход папок в VBA Excel с помощью FileSystemObject (FSO) из библиотеки Microsoft Scripting Runtime.
Рекурсивный обход папок — одна из самых востребованных задач при автоматизации Excel: массовая обработка файлов, сбор данных из вложенных директорий, анализ структуры каталогов, поиск документов по всей иерархии. Стандартная функция Dir в VBA не поддерживает рекурсию, поэтому для таких задач оптимальным решением является FileSystemObject (FSO)
Почему функция Dir не подходит
Функция Dir не подходит для рекурсивного обхода папок, так как имеет ряд ограничений:
- не умеет автоматически заходить во вложенные папки;
- поддерживает только один контекст перебора;
- не предоставляет расширенных сведений о файлах.
Для реализации рекурсивного поиска пришлось бы писать сложную логику с ручным хранением путей. FileSystemObject решает эти проблемы и делает код более читаемым и масштабируемым.
Что такое FileSystemObject
FileSystemObject — объект из библиотеки Microsoft Scripting Runtime, предназначенный для расширенной работы с файловой системой Windows. Он позволяет:
- получать доступ к файлам и папкам как к объектам;
- обходить вложенные директории;
- получать размер файлов, даты создания и изменения;
- создавать, удалять и перемещать файлы и папки.
Подключение библиотеки
Перед использованием FSO рекомендуется подключить библиотеку:
- В редакторе VBA откройте Tools → References.
- Отметьте Microsoft Scripting Runtime.
После этого станут доступны необходимые типы объектов (FileSystemObject, Folder, File).
Что такое рекурсия простыми словами
Рекурсия — это приём программирования, при котором процедура вызывает саму себя.
В контексте обхода папок логика выглядит следующим образом:
- Получаем текущую папку.
- Обрабатываем все файлы в ней.
- Для каждой подпапки вызываем ту же процедуру.
Процесс повторяется, пока не будут обработаны все уровни вложенности.
Базовая структура рекурсивного обхода папок
Универсальный шаблон рекурсивной процедуры:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub ScanFolder(ByVal folderPath As String) Dim fso As FileSystemObject Dim rootFolder As Folder Dim subFolder As Folder Dim fileItem As File Set fso = New FileSystemObject Set rootFolder = fso.GetFolder(folderPath) ' Обработка файлов в текущей папке For Each fileItem In rootFolder.Files Debug.Print fileItem.Path Next fileItem ' Рекурсивный обход подпапок For Each subFolder In rootFolder.SubFolders ScanFolder subFolder.Path Next subFolder End Sub |
Запуск процедуры:
|
1 2 3 |
Sub StartScan() ScanFolder "C:\Data" End Sub |
Пример 1. Рекурсивный обход всех файлов Excel
Частая практическая задача — найти и обработать все Excel-файлы во вложенных папках:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub ScanExcelFiles(ByVal folderPath As String) Dim fso As FileSystemObject Dim fld As Folder Dim subFld As Folder Dim f As File Set fso = New FileSystemObject Set fld = fso.GetFolder(folderPath) For Each f In fld.Files If LCase(fso.GetExtensionName(f.Name)) = "xlsx" Then Debug.Print "Найден файл: " & f.Path End If Next f For Each subFld In fld.SubFolders ScanExcelFiles subFld.Path Next subFld End Sub |
Запуск процедуры:
|
1 2 3 |
Sub StartScanExcel() ScanExcelFiles "C:\Data" End Sub |
Пример 2. Подсчёт количества файлов во всей структуре
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Dim TotalFiles As Long Sub CountFiles(ByVal folderPath As String) Dim fso As FileSystemObject Dim fld As Folder Dim subFld As Folder Set fso = New FileSystemObject Set fld = fso.GetFolder(folderPath) TotalFiles = TotalFiles + fld.Files.Count For Each subFld In fld.SubFolders CountFiles subFld.Path Next subFld End Sub |
Запуск процедуры:
|
1 2 3 4 5 |
Sub StartCount() TotalFiles = 0 CountFiles "C:\Data" MsgBox "Всего файлов: " & TotalFiles End Sub |
Пример 3. Рекурсивный поиск файлов по маске
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub FindFiles(ByVal folderPath As String, ByVal mask As String) Dim fso As FileSystemObject Dim fld As Folder Dim subFld As Folder Dim f As File Set fso = New FileSystemObject Set fld = fso.GetFolder(folderPath) For Each f In fld.Files If f.Name Like mask Then Debug.Print f.Path End If Next f For Each subFld In fld.SubFolders FindFiles subFld.Path, mask Next subFld End Sub |
Запуск процедуры:
|
1 2 3 |
Sub StartFindFiles() FindFiles "C:\Reports", "*.pdf" End Sub |
Важные нюансы и ограничения рекурсии
- Глубина вложенности
Очень глубокая структура папок может привести к переполнению стека. - Права доступа
При отсутствии прав на папку возникнет ошибка — рекомендуется обрабатывать исключения. - Производительность
Рекурсивный обход больших каталогов может занимать значительное время.
Когда FileSystemObject — лучшее решение
Используйте FileSystemObject, если вам нужно:
- рекурсивно обходить папки;
- получать расширенные свойства файлов;
- работать с тысячами файлов;
- писать поддерживаемый и масштабируемый VBA-код.
Для простых проверок существования файла функция Dir может быть быстрее, но для сложной логики FSO практически незаменим.
Заключение
Рекурсивный обход папок в VBA Excel с помощью FileSystemObject — это универсальный приём, который позволяет автоматизировать работу с файловой системой на профессиональном уровне.