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