Разработка и Конфигурация · 12 мин
Как получить все файлы в папке в 1С
Как получить список всех файлов в папке средствами 1С: метод НайтиФайлы, маски, рекурсивный обход подкаталогов, примеры кода на встроенном языке и типичные ошибки.
Задача получить список файлов в папке возникает в 1С постоянно: при загрузке прайсов из каталога обмена, при импорте фотографий номенклатуры, при обработке выгрузок из других учётных систем. Встроенный язык платформы предоставляет для этого штатные средства — глобальный метод НайтиФайлы() и объект Файл, которые работают и на клиенте, и на сервере без подключения внешних компонентов.
Основной инструмент — функция НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах). Она возвращает массив объектов типа Файл, из которых можно получить полное имя, расширение, размер, дату изменения и признак «это каталог». Дальше массив обычно перебирается в цикле, а каждый файл обрабатывается по своей логике: читается, копируется, удаляется или помещается в список значений.
Важный нюанс: код, работающий с файловой системой, выполняется в контексте той стороны, где он запущен. Если процедура выполняется на сервере, путь должен быть доступен серверу 1С, а не компьютеру пользователя. Это самая частая причина «пустого» результата в клиент-серверных базах, и её разбор включён в статью отдельным разделом.
Базовый способ: функция НайтиФайлы
Функция НайтиФайлы() принимает до трёх параметров. Первый — путь к каталогу, в котором выполняется поиск. Второй — маска отбора, например .xml или .csv; если маску не указать или передать ., будут возвращены все объекты каталога, включая подпапки. Третий параметр — булево: искать ли в подкаталогах рекурсивно.
Минимальный рабочий пример выглядит так:
НайденныеФайлы = НайтиФайлы("D:\Обмен", "*.xml", Ложь);
Для Каждого Файл Из НайденныеФайлы Цикл
Сообщить(Файл.ПолноеИмя);
КонецЦикла;
Если каталог не существует или в нём нет подходящих файлов, функция не вызывает исключение — она просто возвращает пустой массив. Поэтому после вызова полезно проверить НайденныеФайлы.Количество() и корректно обработать нулевой результат, а не падать с ошибкой дальше по логике.
Обратите внимание на слэши: платформа корректно понимает и прямые, и обратные слэши в путях, но в строковых литералах встроенного языка обратный слэш не требует экранирования, поэтому пути вида "D:\Обмен\Загрузка" записываются как есть.
НайденныеФайлы = НайтиФайлы("D:\Обмен", "*.xml", Истина);
Для Каждого Файл Из НайденныеФайлы Цикл
Если Не Файл.ЭтоКаталог() Тогда
Сообщить(Файл.ПолноеИмя + " — " + Файл.Размер() + " байт");
КонецЕсли;
КонецЦикла;Какие свойства файла доступны после поиска
Каждый элемент массива — это объект Файл с набором полезных свойств. Знание этих свойств избавляет от лишних вызовов и ручного разбора строк пути.
| Свойство / метод | Что возвращает | Пример значения |
|---|---|---|
ПолноеИмя | Полный путь с именем файла | D:\Обмен\price.xml |
Имя | Имя файла с расширением | price.xml |
ИмяБезРасширения | Имя без точки и расширения | price |
Расширение | Расширение с точкой | .xml |
Путь | Каталог, в котором лежит файл | D:\Обмен\ |
Размер() | Размер в байтах | 152043 |
ПолучитьВремяИзменения() | Дата последней модификации | дата и время |
ЭтоКаталог() | Истина, если объект — папка | Ложь |
Существует() | Проверка существования на диске | Истина |
Типичный сценарий — отфильтровать файлы по дате изменения, чтобы обрабатывать только новые выгрузки. Для этого в цикле сравнивают Файл.ПолучитьВремяИзменения() с граничной датой, например с датой последнего успешного обмена, которую хранят в константе или регистре сведений.
Отбор только файлов без подкаталогов
Маска . возвращает не только файлы, но и вложенные папки, что часто ломает последующую обработку: попытка прочитать каталог как текстовый файл приводит к ошибке. Надёжный шаблон — в каждой итерации проверять ЭтоКаталог() и пропускать папки.
НайденныеФайлы = НайтиФайлы(КаталогОбмена, ".", Ложь);
Для Каждого Элемент Из НайденныеФайлы Цикл
Если Элемент.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
// Обработка файла
КонецЦикла;
Если нужен отбор по нескольким расширениям, одной маски недостаточно: НайтиФайлы не поддерживает списки масок через точку с запятой на всех платформах одинаково. Практичное решение — выполнить поиск несколько раз с разными масками и объединить массивы, либо искать по . и фильтровать расширение в коде через НРег(Файл.Расширение).
Рекурсивный обход подкаталогов
Третий параметр ИскатьВПодкаталогах = Истина включает рекурсивный поиск: платформа сама обойдёт все вложенные папки и вернёт плоский массив результатов. Это удобно, когда структура подкаталогов заранее неизвестна — например, поставщик выгружает файлы в папки по датам.
Альтернатива — ручная рекурсия: сначала найти подкаталоги, затем для каждого вызвать НайтиФайлы снова. Такой подход нужен, когда требуется сохранить иерархию (например, вывести дерево папок пользователю) или ограничить глубину обхода, потому что встроенный рекурсивный поиск обходит дерево целиком.
При рекурсивном обходе больших деревьев учитывайте производительность: поиск по сетевому каталогу с тысячами файлов может занять заметное время. В таких случаях стоит сузить маску, ограничить стартовый каталог или перенести обработку в фоновое задание, чтобы не блокировать сеанс пользователя.
- 1Сформируйте путь к каталогу и убедитесь, что он существует (объект Файл + метод Существует)
- 2Вызовите НайтиФайлы с нужной маской и флагом поиска в подкаталогах
- 3Проверьте, что массив не пуст, иначе зафиксируйте причину в журнале
- 4В цикле отсекайте каталоги через ЭтоКаталог() и фильтруйте файлы по расширению и дате
- 5После обработки каждого файла помечайте его (перенос в архив, запись в регистр), чтобы не обработать повторно
Клиент, сервер и тонкий клиент: где выполняется поиск
В клиент-серверной базе НайтиФайлы на сервере видит только диски и сетевые пути, доступные учётной записи, под которой работает агент сервера 1С. Локальный диск C:\ пользователя серверу недоступен — поиск вернёт пустой массив без всякой ошибки. Это выглядит как «код не работает», хотя проблема в контексте выполнения.
Если файлы лежат на компьютере пользователя, есть два рабочих варианта. Первый — выполнять поиск на клиенте (директива &НаКлиенте), а затем передавать файлы на сервер через НачатьПомещениеФайлаНаСервер или помещение во временное хранилище. Второй — настроить общий сетевой каталог, доступный и пользователям, и серверу, и работать с ним по UNC-пути вида \\server\share.
В тонком и веб-клиенте действуют ограничения безопасности: доступ к файловой системе требует расширения работы с файлами, а в веб-клиенте прямой перебор каталога может быть недоступен вовсе. Для таких сценариев используют асинхронные методы НачатьПоискФайлов с описанием оповещения — синтаксис-помощник в конфигураторе показывает актуальную сигнатуру для вашей версии платформы.
Альтернативные подходы и смежные задачи
Для интерактивного выбора файлов пользователем вместо перебора каталога правильнее использовать ДиалогВыбораФайла в режиме «Открытие» с множественным выбором — тогда пользователь сам указывает нужные файлы, а код получает массив полных имён без сканирования папки.
Если требуется не просто список, а постоянный мониторинг каталога обмена, штатного «наблюдателя за папкой» в платформе нет. Практикуют регламентное задание, которое периодически вызывает НайтиФайлы и сравнивает результат с уже обработанными именами, сохранёнными в регистре сведений. Интервал опроса подбирают под интенсивность обмена.
Для временных файлов обработок не создавайте собственные папки вручную — используйте КаталогВременныхФайлов() и ПолучитьИмяВременногоФайла(): платформа сама управляет такими каталогами, и риск конфликтов имён между сеансами минимален.
Сравнение вариантов
Подходит для пакетной обработки известного каталога; ограничение — одна маска за вызов
Подходит, когда файлы выбирает пользователь; не применим для автоматических регламентных задач
Подходит для постоянного мониторинга каталога обмена; требует хранения истории обработки
Подходит, когда нужна иерархия или ограничение глубины; больше кода, чем встроенный рекурсивный поиск
Типичные ошибки и как их избежать
Первая группа ошибок связана с путями: отсутствующий завершающий слэш при склейке строк, опечатка в букве диска, использование локального пути на сервере. Перед поиском полезно проверить существование каталога через Файл.Существует() и выдать понятное сообщение, а не молча продолжать.
Вторая группа — логические: обработка каталогов как файлов, регистрозависимое сравнение расширений, повторная обработка уже загруженных файлов из-за отсутствия учёта. Третья группа — архитектурные: длительный перебор сетевой папки в интерактивном сеансе, блокирующий пользователя, и попытка использовать модальные и синхронные файловые методы там, где конфигурация работает в асинхронном режиме.
Как проверить результат
Совпадает с числом файлов нужного типа в проводнике
Массив пуст или файлов меньше, чем в папке
Только файлы, подкаталоги отфильтрованы
В списке присутствуют папки
Уже загруженные файлы пропускаются
Данные задваиваются в базе
Путь доступен стороне, где выполняется код
Сервер ищет на диске клиента
Что важно запомнить
Список файлов в папке получают через НайтиФайлы с маской и флагом рекурсии, результат — массив объектов Файл с полными сведениями о каждом элементе. Всегда проверяйте ЭтоКаталог(), приводите расширения к одному регистру, контролируйте контекст выполнения (клиент или сервер) и ведите учёт уже обработанных файлов.
Частые вопросы
Как получить файлы только определённого расширения?
Передайте маску вторым параметром: НайтиФайлы(Каталог, ".xlsx", Ложь). Для нескольких расширений выполните поиск с разными масками и объедините массивы либо фильтруйте результат поиска по .* через сравнение НРег(Файл.Расширение) со списком допустимых значений.
Почему НайтиФайлы возвращает пустой массив, хотя файлы есть?
Чаще всего код выполняется на сервере, а путь указывает на локальный диск пользователя, либо у учётной записи агента сервера нет прав на сетевой каталог. Проверьте контекст выполнения, доступность пути через Файл.Существует() и корректность маски.
Как искать файлы во всех вложенных папках?
Установите третий параметр функции в Истина: НайтиФайлы(Каталог, ".", Истина). Платформа рекурсивно обойдёт дерево и вернёт плоский массив. Если нужна иерархия или ограничение глубины, реализуйте ручную рекурсию по подкаталогам.
Как отличить файл от папки в результатах поиска?
Используйте метод ЭтоКаталог() объекта Файл: он возвращает Истина для каталогов. В цикле обработки каталоги обычно пропускают оператором Продолжить, чтобы не пытаться читать их как файлы.
Можно ли получить список файлов в тонком или веб-клиенте?
Да, но с ограничениями безопасности: требуется расширение работы с файлами, а в веб-клиенте прямой перебор каталогов может быть недоступен. Используйте асинхронные методы НачатьПоискФайлов и НачатьПомещениеФайлаНаСервер с описаниями оповещений.
Как не обработать один и тот же файл дважды?
Храните признаки обработки: записывайте полные имена или хеши загруженных файлов в регистр сведений либо перемещайте обработанные файлы в архивный подкаталог. Перед обработкой проверяйте наличие записи и пропускайте уже загруженные элементы.