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

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

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

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

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

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

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

Функция НайтиФайлы: синтаксис и параметры

Функция НайтиФайлы() — основной способ получить содержимое каталога. Она принимает до трёх параметров:

  • Путь — строка с каталогом поиска, например "C:\Обмен\" или "/mnt/exchange/";
  • Маска — шаблон отбора файлов, например ".xml" или ".*" для всех файлов; параметр необязательный, по умолчанию отбирается всё;
  • ИскатьВПодкаталогах — булево, определяет, нужен ли рекурсивный обход вложенных папок.

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

bsl
МассивФайлов = НайтиФайлы("C:\Обмен\", "*.xml", Ложь);
Если МассивФайлов.Количество() = 0 Тогда
    Сообщить("Файлы не найдены");
    Возврат;
КонецЕсли;
Для Каждого Файл Из МассивФайлов Цикл
    Сообщить(Файл.Имя + " — " + Файл.ПолноеИмя);
КонецЦикла;

Обратите внимание: в строковых литералах 1С обратный слэш не является управляющим символом, поэтому путь Windows записывается как есть, без удвоения. Завершающий слэш в пути желателен, но не обязателен.

Отбор файлов по маске и расширению

Маска поддерживает символы (любая последовательность символов) и ? (один произвольный символ). Чтобы получить только XML-файлы обмена, используйте ".xml"; чтобы найти файлы с определённым префиксом — "Прайс_*.xlsx".

Если нужно отобрать несколько типов файлов сразу (например, и XML, и TXT), одна маска не справится. Получите все файлы маской "." и отфильтруйте их в цикле по свойству Расширение:

bsl
Для Каждого Файл Из НайтиФайлы(Каталог, "<em>.</em>") Цикл
    Расширение = НРег(Файл.Расширение);
    Если Расширение = ".xml" Или Расширение = ".txt" Тогда
        // обработка файла
    КонецЕсли;
КонецЦикла;

Расширение возвращается с точкой, и регистр букв может отличаться в зависимости от того, как файл был создан. Поэтому сравнение всегда выполняйте после приведения к нижнему регистру через НРег().

Как получить файлы из всех подкаталогов

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

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

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

Чтение свойств найденных файлов

Каждый элемент массива — объект Файл с набором свойств, достаточных для большинства задач обработки:

  • Имя — имя файла с расширением, без пути;
  • ИмяБезРасширения и Расширение — части имени по отдельности;
  • ПолноеИмя — полный путь, который передаётся в методы чтения, копирования, удаления;
  • Путь — каталог, в котором лежит файл;
  • Размер() — метод, возвращающий размер в байтах;
  • ПолучитьВремяИзменения() — дата последней модификации, удобна для отбора «только новых» файлов.

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

Пустой массивФайлы не найдены

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

Массив содержит папкиМаска совпала с каталогами

Отфильтруйте через ЭтоКаталог() = Ложь

Ошибка доступаНет прав на каталог

Проверьте права учётной записи, под которой работает сервер 1С

Клиентский и серверный контекст: где искать файлы

Ключевой момент, который часто упускают: НайтиФайлы() ищет файлы в файловой системе того компьютера, где выполняется код. В серверной процедуре это сервер 1С, в клиентской — рабочая станция пользователя. Путь "C:\Обмен\", прекрасно работавший в файловой базе, в клиент-серверном варианте будет указывать на диск C сервера, а не пользователя.

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

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

Как выбрать действие

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

Для регламентных заданий учитывайте ещё одну деталь: задание выполняется под учётной записью службы агента сервера 1С. У этой учётной записи должны быть права на чтение сетевого каталога, и путь лучше указывать в формате UNC (\\server\share\), а не через подключённый сетевой диск — буквы дисков для служб часто недоступны.

Типичные ошибки и их последствия

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

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

Проверка результата и отладка

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

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

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

Количество элементов массива
Норма

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

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

Массив пуст или меньше ожидаемого — проверяйте путь и контекст выполнения

Значение ПолноеИмя
Норма

Путь читается и указывает на нужный каталог

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

Путь указывает на другой диск или компьютер — код выполняется не там

Обработка всех элементов
Норма

Цикл доходит до конца без исключений

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

Прерывание на конкретном файле — он занят или повреждён

Полезный приём — выводить найденные файлы в таблицу значений на форме обработки с колонками «Имя», «Размер», «Изменён», «Статус загрузки». Это даёт пользователю визуальный контроль и упрощает поиск причины, если какой-то файл не загрузился.

Итог

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

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

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

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

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

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

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

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

Чаще всего код выполняется на сервере, а каталог находится на компьютере пользователя. Также проверьте маску (регистр расширения в маске обычно не важен, но лишние пробелы ломают отбор) и права учётной записи, под которой работает сервер 1С.

Как работать с каталогом в веб-клиенте?

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

Как получить файлы, созданные после определённой даты?

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

Чем НайтиФайлы отличается от объекта Файл?

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