К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как перебрать все файлы в папке в 1С

Как перебрать все файлы в папке в 1С с помощью НайтиФайлы: перебор с подкаталогами, фильтры по маске, обработка ошибок, примеры кода для тонкого и веб-клиента.

Перебор файлов в папке — типовая задача при загрузке данных из обменных каталогов, импорте прайсов, обработке сканов документов и выгрузке отчётов. В 1С для этого используется встроенная функция НайтиФайлы(), которая возвращает массив объектов типа Файл, и объект ОбходДереваФайлов для сложных сценариев. Оба подхода работают на толстом, тонком и веб-клиенте, но с ограничениями, которые нужно учитывать заранее.

Главная развилка при выборе способа — где физически лежит папка: на компьютере пользователя или на сервере 1С. От этого зависит, помещать ли файлы во временное хранилище, какие права нужны учётной записи и будет ли код работать в веб-клиенте. Ниже разобраны рабочие варианты кода, фильтрация по маске, рекурсивный обход подкаталогов, типичные ошибки и способы проверить результат.

Как работает функция НайтиФайлы

Функция НайтиФайлы() — основной инструмент перебора. Она принимает три параметра: путь к каталогу, маску поиска (по умолчанию . — все файлы) и признак поиска в подкаталогах. Результат — массив объектов Файл, у каждого из которых доступны свойства: Имя, ИмяБезРасширения, ПолноеИмя, Путь, Расширение, Размер(), ЭтоКаталог().

Минимальный пример перебора всех файлов каталога:

НайденныеФайлы = НайтиФайлы("D:\Обмен\", ".", Ложь);

Для Каждого Файл Из НайденныеФайлы Цикл

Если Файл.ЭтоКаталог() Тогда

Продолжить;

КонецЕсли;

Сообщить(Файл.ПолноеИмя + " — " + Файл.Размер() + " байт");

КонецЦикла;

Обратите внимание: НайтиФайлы возвращает не только файлы, но и вложенные каталоги. Если ваша логика предполагает обработку именно файлов, проверка ЭтоКаталог() обязательна — иначе попытка прочитать папку как файл вызовет ошибку.

Перебор с подкаталогами и фильтрация по маске

Третий параметр НайтиФайлы включает рекурсивный поиск: при значении Истина функция обходит всё дерево подкаталогов и возвращает плоский массив. Это удобно, когда структура вложенности неизвестна заранее — например, поставщик выкладывает файлы в папки по датам.

Маска позволяет отобрать только нужные типы файлов. Маска .xml вернёт XML-файлы, .xls? — xls и xlsx. Несколько масок в одном вызове передать нельзя, поэтому для смешанного набора (например, xml и csv) либо вызывайте функцию дважды и объединяйте массивы, либо берите . и фильтруйте по расширению внутри цикла:

НайденныеФайлы = НайтиФайлы(КаталогОбмена, ".", Истина);

Для Каждого Файл Из НайденныеФайлы Цикл

Расширение = НРег(Файл.Расширение);

Если Расширение <> ".xml" И Расширение <> ".csv" Тогда

Продолжить;

КонецЕсли;

// обработка файла

КонецЦикла;

Сравнение расширения делайте через НРег() — регистр расширения в файловой системе не гарантирован, и файл PRICE.XML не пройдёт проверку на равенство строке «.xml» без приведения регистра.

Базовый порядок перебора файлов
  1. 1
    Определите путь к папке и проверьте её существование через объект Файл и метод Существует()
  2. 2
    Вызовите НайтиФайлы с нужной маской и флагом поиска в подкаталогах
  3. 3
    Переберите массив циклом Для Каждого, пропуская каталоги через ЭтоКаталог()
  4. 4
    Отфильтруйте файлы по расширению или имени, если маска недостаточна
  5. 5
    Обработайте каждый файл и зафиксируйте результат в журнале или регистре

Клиент или сервер: где выполнять перебор

Это самая частая точка отказа у начинающих разработчиков. Код с директивой &НаСервере видит только файловую систему сервера 1С — папка C:\Загрузки пользователя для него не существует. И наоборот, клиентский код не имеет доступа к дискам сервера.

Если папка находится на компьютере пользователя, перебор выполняйте на клиенте. В тонком и веб-клиенте для этого требуется расширение работы с файлами, а современные версии платформы используют асинхронные методы: НачатьПоискФайлов() с описанием оповещения. Синхронный вызов НайтиФайлы на клиенте в управляемом приложении может быть недоступен в зависимости от режима использования модальности и синхронных вызовов.

Если файлы лежат в сетевой папке, доступной и клиенту, и серверу, предпочтительнее серверный вариант: он не зависит от расширения работы с файлами и быстрее при большом количестве объектов. Учётная запись, под которой работает служба агента сервера 1С, должна иметь права чтения на этот сетевой ресурс — это проверяется в первую очередь при ошибках доступа.

Маршрут решения

Где выполнять перебор

Папка на компьютере пользователя и нужен клиентский сценарийИспользуйте НачатьПоискФайлов с расширением работы с файлами на клиенте
Папка на сервере или в сетевом каталоге, доступном серверуВыполняйте НайтиФайлы в серверной процедуре
Нужно загрузить файлы с клиента на сервер для обработкиСначала поместите файлы через НачатьПомещениеФайлов, затем обрабатывайте на сервере

Проверки, которые стоит сделать до и во время перебора

Перед вызовом НайтиФайлы убедитесь, что каталог существует. Если путь указан с ошибкой или сетевая папка недоступна, функция может вернуть пустой массив без какого-либо сообщения — и программа молча «не найдёт» файлы. Явная проверка избавляет от долгой диагностики:

Каталог = Новый Файл(ПутьКПапке);

Если Не Каталог.Существует() Или Не Каталог.ЭтоКаталог() Тогда

ВызватьИсключение "Каталог обмена недоступен: " + ПутьКПапке;

КонецЕсли;

Внутри цикла полезно оборачивать обработку каждого файла в Попытка...Исключение. Тогда один повреждённый или заблокированный другой программой файл не прервёт обработку всей папки, а ошибка попадёт в журнал с указанием конкретного имени. После цикла сравните количество найденных и успешно обработанных файлов — расхождение покажет, что часть данных потерялась.

Контрольные точки

Как проверить результат перебора

Количество найденных файлов
Норма

Совпадает с числом файлов в папке при просмотре в проводнике с тем же фильтром

Тревожный признак

Массив пуст или файлов меньше — проверьте путь, маску и права доступа

Состав массива
Норма

Все элементы — файлы, каталоги отфильтрованы проверкой ЭтоКаталог()

Тревожный признак

В обработку попадают папки — добавьте проверку в начало цикла

Обработанные файлы
Норма

Число обработанных равно числу найденных, ошибки зафиксированы поимённо

Тревожный признак

Часть файлов пропущена без записи в журнал — нет обработки исключений

Альтернатива: объект ОбходДереваФайлов

Когда важна не только выборка, но и структура вложенности — например, нужно воспроизвести иерархию папок в дереве значений, — удобнее объект ОбходДереваФайлов. Он создаётся конструктором Новый ОбходДереваФайлов(Путь) и перебирается циклом Пока Обход.Следующий() Цикл. Текущий файл доступен через свойство Обход.Файл, а Обход.Уровень() возвращает глубину вложенности.

Для простой задачи «взять все xml из папки» этот объект избыточен — НайтиФайлы короче и быстрее. Обход дерева оправдан при построении интерфейсных деревьев, архивации с сохранением структуры и поэтапной обработке каталогов по уровням.

Способы перебора файлов

НайтиФайлы с маской

Подходит для плоской выборки по шаблону; не сохраняет структуру подкаталогов

НайтиФайлы с рекурсией

Один вызов для всего дерева папок; при очень большом числе файлов массив занимает заметную память

ОбходДереваФайлов

Даёт уровни вложенности и последовательный обход; кода больше, выборку по маске придётся делать вручную

Типичные ошибки и ограничения

Самая распространённая ошибка — выполнение НайтиФайлы на сервере с путём к локальной папке пользователя. Вторая по частоте — отсутствие проверки ЭтоКаталог(), из-за чего обработка падает на первой же вложенной папке. Третья — сравнение расширений без приведения регистра.

Отдельная группа проблем связана с правами и блокировками. Служба сервера 1С обычно работает под служебной учётной записью, у которой может не быть доступа к сетевым папкам и «расшаренным» ресурсам пользователей. Файл, открытый в другой программе, иногда нельзя прочитать или переместить — такие ситуации нужно перехватывать исключением и повторять попытку позже, а не прерывать весь процесс.

Ещё одно ограничение: в веб-клиенте без установленного расширения работы с файлами прямой перебор каталога невозможен в принципе. Пользователю придётся выбирать файлы через диалог помещения, либо переносить обработку на сервер, либо использовать регламентное задание по серверной папке обмена.

Типичные ошибки
01
Вызов НайтиФайлы на сервере с клиентским путём — массив пуст, файлы «не находятся»
02
Отсутствие проверки ЭтоКаталог() — исключение при попытке прочитать папку как файл
03
Сравнение расширения без НРег() — файлы с расширением в верхнем регистре пропускаются
04
Нет обработки исключений внутри цикла — один заблокированный файл останавливает обработку всей папки
05
Игнорирование проверки существования каталога — тихий пропуск обработки без диагностики

Безопасная организация промышленной обработки

В рабочих базах перебор папки обмена обычно оформляют регламентным заданием. Практичный шаблон: файлы, которые удалось обработать, перемещаются в подпапку «Архив», проблемные — в «Ошибки» с записью причины в журнал регистрации или специальный регистр сведений. Так папка не разрастается, а повторная обработка одних и тех же файлов исключается.

Перемещение выполняйте через ПереместитьФайл() только после успешного завершения обработки конкретного файла. Если переносить файл до чтения и загрузка упадёт, данные окажутся в архиве необработанными — восстановить факт потери будет сложно. Перед массовым запуском на рабочей базе отладьте сценарий на копии папки с несколькими тестовыми файлами.

Итог

Что важно запомнить

Основной инструмент — НайтиФайлы с маской и флагом рекурсии; каталоги отсекайте через ЭтоКаталог(), расширения сравнивайте через НРег(). Выбирайте место выполнения (клиент или сервер) по реальному расположению папки, проверяйте существование каталога и оборачивайте обработку каждого файла в попытку с журналированием ошибок.

Частые вопросы

НайтиФайлы возвращает пустой массив, хотя файлы в папке есть. В чём причина?

Чаще всего код выполняется не там, где лежит папка: серверная процедура не видит локальный диск пользователя. Также проверьте путь на опечатки, слэш в конце, права учётной записи сервера 1С на сетевой каталог и корректность маски — например, маска «*.xml» не найдёт файл с расширением «.XML» на некоторых сетевых ресурсах с чувствительностью к регистру.

Как перебрать файлы нескольких типов за один проход?

Передайте маску «.», а внутри цикла проверяйте расширение через НРег(Файл.Расширение) на вхождение в список допустимых значений. Альтернатива — несколько вызовов НайтиФайлы с разными масками и объединение массивов, но это медленнее на больших каталогах.

Работает ли НайтиФайлы в веб-клиенте?

Только с установленным расширением работы с файлами и через асинхронный вариант НачатьПоискФайлов с описанием оповещения. Синхронный вызов в веб-клиенте обычно недоступен. Если расширение установить нельзя, перенесите обработку на сервер или используйте диалог помещения файлов.

Как исключить повторную обработку уже загруженных файлов?

Самый надёжный способ — перемещать обработанный файл в подпапку архива сразу после успешной загрузки. Дополнительно можно хранить в регистре сведений имена, размеры или хеши обработанных файлов и сверяться с ним перед загрузкой.

Что делать, если файл заблокирован другой программой?

Перехватите ошибку через Попытка...Исключение, запишите имя файла в журнал и продолжите цикл. Такой файл можно повторно обработать при следующем запуске — не прерывайте весь перебор из-за одной блокировки.

Чем ОбходДереваФайлов лучше НайтиФайлы?

Он возвращает уровень вложенности каждого элемента и обходит структуру последовательно, что удобно для построения дерева значений или архивации с сохранением иерархии. Для простой выборки по маске НайтиФайлы проще и требует меньше кода.