Функция FilenamesCollection предназначена для получения списка файлов из папки, с учётом выбранной глубины поиска в подпапках.
Используется рекурсивный перебор папок, до заданного уровня вложенности.
В процессе перебора папок, пути у найденным файлам помещаются в коллекцию (объект типа Collection) для последующего перебора.
К статье прикреплено 2 примера файла с макросами на основе этой функции:
- Пример в файле FilenamesCollection.xls выводит список файлов на чистый лист новой книги (формируя заголовки)
- Пример в файле FilenamesCollectionEx.xls более функционален — он, помимо списка файлов из папки, отображает размер файла, и дату его создания, а также формирует в ячейках гиперссылки на найденные файлы.
Вывод списка производится на лист запуска, параметры поиска файлов задаются в ячейках листа (см. скриншот)
Смотрите также расширенную версию макроса на базе этой функции:
Макрос FolderStructure выводит в таблицу Excel список файлов и подпапок с отображением структуры (вложенности файлов и подпапок)
ПРИМЕЧАНИЕ: Если вы выводите на лист список имен файлов картинок (изображений), то при помощи этой надстройки вы сможете вставить сами картинки в ячейки соседнего столбца (или в примечания к этим ячейкам)
Внимание: если требуется, чтобы поиск не зависел от регистра символов в маске файла
(к примеру, обнаруживались не только файлы .txt, но и .TXT и .Txt),
поставьте первой строкой в модуле директиву Option Compare Text
Function FilenamesCollection(ByVal FolderPath As String, Optional ByVal Mask As String = "", _ Optional ByVal SearchDeep As Long = 999) As Collection ' © EducatedFool excelvba.ru/code/FilenamesCollection ' Получает в качестве параметра путь к папке FolderPath, ' маску имени искомых файлов Mask (будут отобраны только файлы с такой маской/расширением) ' и глубину поиска SearchDeep в подпапках (если SearchDeep=1, то подпапки не просматриваются). ' Возвращает коллекцию, содержащую полные пути найденных файлов ' (применяется рекурсивный вызов процедуры GetAllFileNamesUsingFSO) Set FilenamesCollection = New Collection ' создаём пустую коллекцию Set FSO = CreateObject("Scripting.FileSystemObject") ' создаём экземпляр FileSystemObject GetAllFileNamesUsingFSO FolderPath, Mask, FSO, FilenamesCollection, SearchDeep ' поиск Set FSO = Nothing: Application.StatusBar = False ' очистка строки состояния Excel End Function Function GetAllFileNamesUsingFSO(ByVal FolderPath As String, ByVal Mask As String, ByRef FSO, _ ByRef FileNamesColl As Collection, ByVal SearchDeep As Long) ' перебирает все файлы и подпапки в папке FolderPath, используя объект FSO ' перебор папок осуществляется в том случае, если SearchDeep > 1 ' добавляет пути найденных файлов в коллекцию FileNamesColl On Error Resume Next: Set curfold = FSO.GetFolder(FolderPath) If Not curfold Is Nothing Then ' если удалось получить доступ к папке ' раскомментируйте эту строку для вывода пути к просматриваемой ' в текущий момент папке в строку состояния Excel ' Application.StatusBar = "Поиск в папке: " & FolderPath For Each fil In curfold.Files ' перебираем все файлы в папке FolderPath If fil.Name Like "*" & Mask Then FileNamesColl.Add fil.Path Next SearchDeep = SearchDeep - 1 ' уменьшаем глубину поиска в подпапках If SearchDeep Then ' если надо искать глубже For Each sfol In curfold.SubFolders ' перебираем все подпапки в папке FolderPath GetAllFileNamesUsingFSO sfol.Path, Mask, FSO, FileNamesColl, SearchDeep Next End If Set fil = Nothing: Set curfold = Nothing ' очищаем переменные End If End Function
‘ Пример использования функции в макросе:
Sub ОбработкаФайловИзПапки() On Error Resume Next Dim folder$, coll As Collection folder$ = ThisWorkbook.Path & "Платежи" If Dir(folder$, vbDirectory) = "" Then MsgBox "Не найдена папка «" & folder$ & "»", vbCritical, "Нет папки ПЛАТЕЖИ" Exit Sub ' выход, если папка не найдена End If Set coll = FilenamesCollection(folder$, "*.xls") ' получаем список файлов XLS из папки If coll.Count = 0 Then MsgBox "В папке «" & Split(folder$, "")(UBound(Split(folder$, "")) - 1) & "» нет ни одного подходящего файла!", _ vbCritical, "Файлы для обработки не найдены" Exit Sub ' выход, если нет файлов End If ' перебираем все найденные файлы For Each file In coll Debug.Print file ' выводим имя файла в окно Immediate Next End Sub
Этот код позволяет осуществить поиск нужных файлов в выбранной папке (включая подпапки), и выводит полученный список файлов на лист книги Excel:
Sub ПримерИспользованияФункции_FilenamesCollection() ' Ищем на рабочем столе все файлы TXT, и выводим на лист список их имён. ' Просматриваются папки с глубиной вложения не более трёх. Dim coll As Collection, ПутьКПапке As String ' получаем путь к папке РАБОЧИЙ СТОЛ ПутьКПапке = CreateObject("WScript.Shell").SpecialFolders("Desktop") ' считываем в колекцию coll нужные имена файлов Set coll = FilenamesCollection(ПутьКПапке, ".txt", 3) Application.ScreenUpdating = False ' отключаем обновление экрана ' создаём новую книгу Dim sh As Worksheet: Set sh = Workbooks.Add.Worksheets(1) ' формируем заголовки таблицы With sh.Range("a1").Resize(, 3) .Value = Array("№", "Имя файла", "Полный путь") .Font.Bold = True: .Interior.ColorIndex = 17 End With ' выводим результаты на лист For i = 1 To coll.Count ' перебираем все элементы коллекции, содержащей пути к файлам sh.Range("a" & sh.Rows.Count).End(xlUp).Offset(1).Resize(, 3).Value = _ Array(i, Dir(coll(i)), coll(i)) ' выводим на лист очередную строку DoEvents ' временно передаём управление ОС Next sh.Range("a:c").EntireColumn.AutoFit ' автоподбор ширины столбцов [a2].Activate: ActiveWindow.FreezePanes = True ' закрепляем первую строку листа End Sub
Ещё один пример использования:
Sub ЗагрузкаСпискаФайлов() ' Ищем файлы в заданной папке по заданной маске, ' и выводим на лист список их параметров. ' Просматриваются папки с заданной глубиной вложения. Dim coll As Collection, ПутьКПапке$, МаскаПоиска$, ГлубинаПоиска% ПутьКПапке$ = [c1] ' берём из ячейки c1 МаскаПоиска$ = [c2] ' берём из ячейки c2 ГлубинаПоиска% = Val([c3]) ' берём из ячейки c3 If ГлубинаПоиска% = 0 Then ГлубинаПоиска% = 999 ' без ограничения по глубине ' считываем в колекцию coll нужные имена файлов Set coll = FilenamesCollection(ПутьКПапке$, МаскаПоиска$, ГлубинаПоиска%) Application.ScreenUpdating = False ' отключаем обновление экрана ' выводим результаты (список файлов, и их характеристик) на лист For i = 1 To coll.Count ' перебираем все элементы коллекции, содержащей пути к файлам НомерФайла = i ПутьКФайлу = coll(i) ИмяФайла = Dir(ПутьКФайлу) ДатаСоздания = FileDateTime(ПутьКФайлу) РазмерФайла = FileLen(ПутьКФайлу) ' выводим на лист очередную строку Range("a" & Rows.Count).End(xlUp).Offset(1).Resize(, 5).Value = _ Array(НомерФайла, ИмяФайла, ПутьКФайлу, ДатаСоздания, РазмерФайла) ' если нужна гиперссылка на файл во втором столбце ActiveSheet.Hyperlinks.Add Range("b" & Rows.Count).End(xlUp), ПутьКФайлу, "", _ "Открыть файл" & vbNewLine & ИмяФайла DoEvents ' временно передаём управление ОС Next End Sub
PS: Найти подходящие имена файлов в коллекции можно при помощи следующей функции:
Function CollectionAutofilter(ByRef coll As Collection, ByVal filter$) As Collection ' Функция перебирает все элементы коллекции coll, ' оставляя лишь те, которые соответствуют маске filter$ (например, filter$="*некий текст*") ' Возвращает коллекцию, содержащую только подходящие элементы ' Если элементы не найдены - возвращается пустая коллекция (содержащая 0 элементов) On Error Resume Next: Set CollectionAutofilter = New Collection For Each Item In coll If Item Like filter$ Then CollectionAutofilter.Add Item Next End Function
- 301880 просмотров
Не получается применить макрос? Не удаётся изменить код под свои нужды?
Оформите заказ у нас на сайте, не забыв прикрепить примеры файлов, и описать, что и как должно работать.
lenok Пользователь Сообщений: 39 |
Помогите, пожалуйста. |
Johny Пользователь Сообщений: 2737 |
А файл какой? Excel? There is no knowledge that is not power |
lenok Пользователь Сообщений: 39 |
да. в 2003 экселе пытаюсь написать |
Johny Пользователь Сообщений: 2737 |
#4 23.05.2013 11:40:58
There is no knowledge that is not power |
||
lenok Пользователь Сообщений: 39 |
|
lenok Пользователь Сообщений: 39 |
а как сделать, чтобы выбор варианта ответа при появлении диалогового окна был автоматический, или чтобы оно вообще не вылазило??? |
Johny Пользователь Сообщений: 2737 |
#7 24.05.2013 14:28:11
Изменено: Johny — 24.05.2013 14:28:36 There is no knowledge that is not power |
||
lenok Пользователь Сообщений: 39 |
а можно ли сделать, чтобы он искал документ в поддиректориях??? |
Johny Пользователь Сообщений: 2737 |
#9 31.05.2013 17:18:58 Ставим галку: Tools -> References -> Microsoft Scripting Runtime
Изменено: Johny — 31.05.2013 17:19:49 There is no knowledge that is not power |
||
Hugo Пользователь Сообщений: 23253 |
#10 31.05.2013 17:29:09 Я чего-то не понимаю?
|
||
Юрий М Модератор Сообщений: 60585 Контакты см. в профиле |
Я тоже не понимаю смысла в поиске… |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Я сам — дурнее всякого примера! … |
lenok Пользователь Сообщений: 39 |
Просто документов очень много. и постоянно открывать файлы под определенными названиями….. смысл тогда составления макроса… Пишу для автоматизации процессов обработки информации, и остановилась на этом моменте.
|
Hugo Пользователь Сообщений: 23253 |
Если например ситуации такие: |
lenok Пользователь Сообщений: 39 |
Есть огромный отчет. после обработки макросом, надо, чтобы он брал имя файла из определенной ячейки и открывал фаил с таким именем. информации много, и такой отчет обрабатывается каждый месяц. примерное кол-во файлов на один отчет больше 1000, поэтому, сами понимаете, что открывать каждый, это рутина. таких отчетов за один месяц 30 штук. соответственно, около 30000 существующих файлов…вот как-то так все глобально…… просто открыть, с этим мы разобрались….. но некоторые файлы находятся в поддиректориях, и постоянно происходят какие-то перемещения в этой директории… |
Hugo Пользователь Сообщений: 23253 |
#16 03.06.2013 11:32:43 В теме http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=8&TID=25457 есть файл http://www.planetaexcel.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=40202&action=download Там есть такой код:
и т.д. |
||
lenok Пользователь Сообщений: 39 |
что-то я не могу разобраться совсем |
anvg Пользователь Сообщений: 11878 Excel 2016, 365 |
Пробуйте, первый запуск будет долгим. Далее быстрее. Если есть подозрение, что файлы в папке и подпапках изменили положение или имя, то нажать «Обновить». Путь к начальной папке задаётся константой baseFolder в методе InitializeFindю |
lenok Пользователь Сообщений: 39 |
#19 04.06.2013 07:29:04
я так понимаю, здесь надо прописать адрес самой папки, это понятно… |
||
anvg Пользователь Сообщений: 11878 Excel 2016, 365 |
#20 04.06.2013 07:50:49
Из активной ячейки (в ней только имя, без расширения) Изменено: anvg — 04.06.2013 07:52:42 |
||
lenok Пользователь Сообщений: 39 |
#21 04.06.2013 08:07:46 все, поняла….. все работает…спасибо большое…. и еще один вопрос, если можно….: до этого было прописано так, но он только с одной папки так открывает….
Изменено: lenok — 04.06.2013 23:58:03 |
||
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
#22 04.06.2013 08:24:36 А на кой тут цикл? Если имя файла известно, зачем перебирать все файлы?
Я сам — дурнее всякого примера! … |
||
lenok Пользователь Сообщений: 39 |
он не открывает тогда файл в поддиректории |
KuklP Пользователь Сообщений: 14868 E-mail и реквизиты в профиле. |
Ага. А с циклом, следовательно, открывает? Я сам — дурнее всякого примера! … |
lenok Пользователь Сообщений: 39 |
неа… тоже не открывает…. а надо, чтобы открывал… там мне уже без разницы, есть цикл или нет… надо, чтобы он поддиректории просматривал |
anvg Пользователь Сообщений: 11878 Excel 2016, 365 |
#26 04.06.2013 09:43:56
|
|
lenok Пользователь Сообщений: 39 |
|
Sandero Пользователь Сообщений: 14 |
#28 18.06.2019 13:20:28
Добрый день!
|
||||
В папке с:отчеты лежат отчёты по дням:
«отчёт за 16.05.2017».xls
«отчёт за 15.05.2017».xls
«отчёт за 14.05.2017».xls
И т.д.
Пишу макрос, который будет искать по маске: «отчёт за » & Date — x».xls» , за какую дату был записан последний отчёт, то есть ‘x’. Перерыв в формировании отчёта может достигать 5 дней.
Что мешает: не могу понять, как выйти из двух циклов после первого вхождения.
У меня получается так, или не останавливается, цикл X и выдаёт последнее, а не первое совпадение, или наоборот не найдя х=1 не переходит к x=2.
Visual Basic | ||
|
Поиск файлов в папке и её подпапках |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
Получение списка файлов в указанной папке с помощью кода VBA Excel. Коллекция Files объекта Folder, возвращенного методом FileSystemObject.GetFolder.
Коллекция Files объекта Folder
Для получения списка файлов в указанной папке используется свойство Files
объекта Folder
. Объект Folder
в VBA Excel возвращается методом GetFolder
объекта FileSystemObject по полному имени папки в качестве аргумента.
Если в указанной папке нет файлов, применение свойства Folder.Files
приведет к возникновению ошибки. Для корректного завершения программы используйте обработчик ошибок или условие, проверяющее наличие файлов в папке.
Получение списка файлов в папке
Пример 1
Код VBA Excel для получения списка файлов в указанной папке и записи полных имен файлов в массив (с поздней привязкой объектов к переменным):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub Primer1() Dim fso, myPath, myFolder, myFile, myFiles(), i ‘Записываем в переменную myPath полное имя папки myPath = «C:DATAТекущая папка» ‘Создаем новый экземпляр FileSystemObject Set fso = CreateObject(«Scripting.FileSystemObject») ‘Присваиваем переменной myFolder ссылку на объект Folder Set myFolder = fso.GetFolder(myPath) ‘Проверяем, есть ли файлы в папке myFolder If myFolder.Files.Count = 0 Then MsgBox «В папке «» & myPath & «» файлов нет» Exit Sub End If ‘Задаем массиву размерность ReDim myFiles(1 To myFolder.Files.Count) ‘Загружаем в массив полные имена файлов For Each myFile In myFolder.Files i = i + 1 myFiles(i) = myFile.Path Next ‘Просматриваем первый элемент массива MsgBox myFiles(1) End Sub |
Используемые переменные:
- fso – ссылка на экземпляр объекта FileSystemObject;
- myPath – полное имя папки;
- myFolder – ссылка на объект Folder (папка);
- myFile – ссылка на один объект File из коллекции myFolder.Files;
- myFiles() – массив для записи имен файлов;
- i – счетчик элементов массива.
Пример 2
Получение списка файлов в указанной папке и запись имен файлов в ячейки первого столбца рабочего листа Excel (с ранней привязкой объектов к переменным):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub Primer2() Dim myPath, myFolder As Folder, myFile As File, i ‘Записываем в переменную myPath полное имя папки myPath = «C:DATAТекущая папка» ‘Создаем новый экземпляр FileSystemObject Dim fso As New FileSystemObject ‘Присваиваем переменной myFolder ссылку на объект Folder Set myFolder = fso.GetFolder(myPath) ‘Проверяем, есть ли файлы в папке myFolder If myFolder.Files.Count = 0 Then MsgBox «В папке «» & myPath & «» файлов нет» Exit Sub End If ‘Записываем имена файлов в первый столбец активного листа For Each myFile In myFolder.Files i = i + 1 Cells(i, 1) = myFile.Name Next End Sub |
Ранняя привязка позволяет использовать подсказки свойств и методов объектов при написании кода VBA Excel.
Как получить список папок до 3 уровней вложенности, смотрите в статье VBA Excel. Список папок.
Фразы для контекстного поиска: обход файлов.