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