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

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

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

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

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

Важно понимать, где именно выполняется код. В клиент-серверном режиме файловая система сервера и файловая система клиента — это разные каталоги. Если обработка запускается на сервере, путь C:\Загрузки будет искаться на сервере 1С, а не на компьютере пользователя. Это самая частая причина «пустого» результата при вроде бы верном коде.

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

Базовый способ: функция НайтиФайлы

Функция НайтиФайлы имеет три параметра: путь к каталогу, маска поиска и признак поиска в подкаталогах. Маска по умолчанию — ., то есть все файлы. Результат — массив объектов типа Файл, который можно перебрать в цикле.

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

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

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

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

КонецЕсли;

КонецЦикла;

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

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

bsl
Каталог = Новый Файл("D:\Обмен\");
Если Не Каталог.Существует() Тогда
    ВызватьИсключение "Каталог обмена не найден";
КонецЕсли;
Файлы = НайтиФайлы(Каталог.ПолноеИмя, "*.xml", Истина);

Фильтрация по маске и расширению

Маска позволяет отобрать только нужные файлы ещё на этапе поиска: .xml — только XML, .csv — только табличные выгрузки, прайс_*.xlsx — файлы с определённым префиксом. Это быстрее, чем получать всё и фильтровать в цикле, особенно в каталогах с сотнями файлов.

Если нужно несколько расширений одновременно (например, и .jpg, и .png), одна маска не справится — синтаксис перечисления не поддерживается. В этом случае либо вызывайте НайтиФайлы несколько раз и объединяйте массивы, либо получайте всё по маске . и проверяйте расширение в цикле:

Допустимые = СтрРазделить(".jpg,.png,.jpeg", ",");

Для Каждого Файл Из НайтиФайлы(Путь, ".") Цикл

Если Допустимые.Найти(НРег(Файл.Расширение)) <> Неопределено Тогда

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

КонецЕсли;

КонецЦикла;

Обратите внимание на регистр: расширение .JPG и .jpg — разные строки, поэтому сравнение надёжнее выполнять после приведения к нижнему регистру через НРег().

Рекурсивный обход вложенных папок

Третий параметр НайтиФайлы — булево «ИскатьВПодкаталогах». При значении Истина поиск выполняется по всему дереву каталогов, и в результат попадают как файлы, так и вложенные папки. Отличить их можно методом ЭтоКаталог().

ВсеЭлементы = НайтиФайлы(КорневойПуть, ".", Истина);

Для Каждого Элемент Из ВсеЭлементы Цикл

Если Элемент.ЭтоКаталог() Тогда

Продолжить; // пропускаем папки

КонецЕсли;

// работаем с файлом Элемент.ПолноеИмя

КонецЦикла;

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

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

В управляемом приложении директивы компиляции определяют, чью файловую систему видит код. Метод с &НаСервере работает с дисками сервера 1С, &НаКлиенте — с дисками компьютера пользователя. Путь, доступный пользователю в проводнике, может быть недоступен серверу, и наоборот.

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

В файловой базе с толстым клиентом разницы нет — код выполняется на машине пользователя. Но при переносе решения в клиент-серверный вариант такой код «молча» перестаёт находить файлы. Проектируйте обмен сразу с учётом разделения контекстов.

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

Как выбрать подход

Обработка работает на сервере, файлы лежат в общей сетевой папкеИспользуйте НайтиФайлы в серверном коде и убедитесь, что у пользователя службы сервера 1С есть доступ к шаре
Пользователь сам выбирает папку на своём компьютереОбходите файлы на клиенте и передавайте их на сервер через временное хранилище
Нужно работать в веб-клиентеИспользуйте асинхронные методы НачатьПоискФайлов и помещение файлов с расширением работы с файлами
Нужен разовый анализ каталога на своём ПКДостаточно внешней обработки с НайтиФайлы в толстом или тонком клиенте

Асинхронный поиск в тонком и веб-клиенте

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

&НаКлиенте

Процедура НайтиФайлыАсинхронно(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеПоискаФайлов", ЭтотОбъект);

НачатьПоискФайлов(Оповещение, ПутьККаталогу, ".", Истина);

КонецПроцедуры

&НаКлиенте

Процедура ПослеПоискаФайлов(НайденныеФайлы, ДопПараметры) Экспорт

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

// обработка

КонецЦикла;

КонецПроцедуры

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

Типичные ошибки и их диагностика

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

Вторая группа проблем — права доступа. Служба агента сервера 1С обычно работает под отдельной учётной записью, и у неё может не быть доступа к сетевой папке, которая открывается у пользователя. Проверяйте доступ именно от имени учётной записи службы, а не своей.

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

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

Проверка результата и безопасная обработка

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

Если обработка перемещает или удаляет файлы после загрузки, сначала убедитесь, что данные действительно записаны в базу. Безопасный порядок: прочитать файл → загрузить данные → зафиксировать транзакцию → только потом переместить файл в архивный каталог. Удаление без архива — риск безвозвратной потери данных при ошибке в логике загрузки.

При чтении содержимого файлов (XML, CSV, DBF) оборачивайте разбор в попытку-исключение по каждому файлу отдельно: один повреждённый файл не должен прерывать обработку всей папки. Информацию о сбойном файле записывайте в протокол с полным путём и текстом ошибки.

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

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

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

Количество соответствует числу файлов в папке при просмотре в проводнике

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

Массив пуст при наличии файлов — неверный путь или контекст выполнения

Протокол обработки
Норма

Каждый файл либо загружен, либо пропущен с указанной причиной

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

Есть файлы без статуса — цикл прервался исключением

Данные в базе
Норма

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

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

Файлы обработаны, объектов меньше — ошибки в логике загрузки

Альтернативы: выбор каталога пользователем и ДиалогВыбораФайла

Если папка не фиксированная, а выбирается пользователем, используйте ДиалогВыбораФайла в режиме РежимДиалогаВыбораФайла.ВыборКаталога (или асинхронный НачатьВыборКаталога). Полученный путь затем передаётся в НайтиФайлы. Это избавляет от ручного ввода путей и опечаток.

Для регулярных обменов путь к каталогу лучше хранить в настройках (константа, регистр сведений, параметры регламентного задания), а не зашивать в код. Тогда смена сервера или структуры папок не потребует доработки конфигурации.

Итог

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

Чтение файлов папки делается через НайтиФайлы с путём, маской и признаком рекурсии. Ключевые условия успеха: правильный контекст выполнения (клиент или сервер), права доступа учётной записи к каталогу, проверка ЭтоКаталог() и обработка каждого файла в отдельной попытке с протоколом результата.

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

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

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

Как получить только подкаталоги, без файлов?

Вызовите НайтиФайлы с маской . и в цикле оставляйте только элементы, для которых ЭтоКаталог() возвращает Истину. Отдельной маски «только папки» в платформе нет, отбор выполняется в коде.

Можно ли отсортировать найденные файлы по дате изменения?

Функция НайтиФайлы не гарантирует порядок. Скопируйте результаты в таблицу значений с колонками «Файл» и «ВремяИзменения» (значение из ПолучитьВремяИзменения()), затем отсортируйте таблицу методом Сортировать() и обрабатывайте в нужном порядке.

Почему обход сетевой папки на сервере не видит файлы, а с моего компьютера видит?

Агент сервера 1С работает под своей учётной записью, у которой может не быть прав на сетевой ресурс. Предоставьте доступ этой учётной записи к общей папке, используйте UNC-путь вида \\сервер\ресурс вместо подключённого диска и проверьте доступ, войдя на сервер под учётной записью службы.

Как не обработать файл, который ещё копируется в папку?

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

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

Синхронный вызов в веб-клиенте недоступен. Используйте асинхронный НачатьПоискФайлов с описанием оповещения и подключённым расширением работы с файлами в браузере. Без расширения доступ к локальной файловой системе пользователя невозможен.