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

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

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

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

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

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

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

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

Функция имеет три параметра: путь к каталогу, маска поиска и признак поиска в подкаталогах. Все параметры, кроме первого, необязательны. Если маску не указать, вернутся все файлы и подкаталоги первого уровня.

НайденныеФайлы = НайтиФайлы("D:\Обмен\Входящие", "*.xml");

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

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

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

КонецЕсли;

КонецЦикла;

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

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

Маски поиска и фильтрация по типу файлов

Маска задаётся символами подстановки: — любая последовательность символов, ? — один любой символ. Типичные варианты: .xml — только XML-файлы, .jpg — изображения, .txt — текстовые выгрузки, . — всё содержимое.

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

Если требуется отобрать файлы нескольких типов, одной маской не обойтись — либо вызывайте НайтиФайлы несколько раз с разными масками и объединяйте массивы, либо забирайте всё и проверяйте расширение вручную:

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

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

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

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

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

КонецЕсли;

КонецЦикла;

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

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

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

Если нужно получить только структуру подкаталогов без файлов, отфильтруйте результат по методу ЭтоКаталог():

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

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

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

Сообщить("Папка: " + Элемент.ПолноеИмя);

КонецЕсли;

КонецЦикла;

Поиск на клиенте и на сервере: в чём разница

НайтиФайлы ищет там, где выполняется код. В клиент-серверном варианте серверный вызов видит файловую систему сервера, а не компьютера пользователя. Если пользователь указывает путь «D:\Документы», а код выполняется на сервере, поиск пойдёт по диску D сервера — и, скорее всего, вернёт пустой массив.

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

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

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

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

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

Вывод списка в таблицу значений и на форму

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

ТаблицаФайлов = Новый ТаблицаЗначений;

ТаблицаФайлов.Колонки.Добавить("Имя");

ТаблицаФайлов.Колонки.Добавить("ПолноеИмя");

ТаблицаФайлов.Колонки.Добавить("Размер");

ТаблицаФайлов.Колонки.Добавить("ДатаИзменения");

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

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

Продолжить;

КонецЕсли;

Строка = ТаблицаФайлов.Добавить();

Строка.Имя = Файл.Имя;

Строка.ПолноеИмя = Файл.ПолноеИмя;

Строка.Размер = Файл.Размер();

Строка.ДатаИзменения = Файл.ПолучитьВремяИзменения();

КонецЦикла;

ТаблицаФайлов.Сортировать("ДатаИзменения Убыв");

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

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

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

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

Полезно различать ситуации «каталога нет» и «каталог есть, но файлов нет». Для первой проверки создайте объект Файл с путём к каталогу и вызовите Существует(). Это упростит диагностику: пользователь получит понятное сообщение «папка недоступна», а не «файлы не найдены».

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

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

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

Массив содержит ожидаемое число элементов

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

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

Полнота путей
Норма

ПолноеИмя содержит абсолютный путь к файлу

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

Относительные пути — задайте полный путь к каталогу в вызове

Доступность каталога
Норма

Файл(Путь).Существует() возвращает Истина

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

Ложь — неверный путь или нет прав у учётной записи

Состав результата
Норма

В массиве только нужные типы файлов

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

Попали каталоги или лишние расширения — уточните маску или фильтр в цикле

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

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

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

Типичные ошибки
01
Вызов НайтиФайлы на сервере с путём к диску пользователя — результат всегда пустой
02
Отсутствие проверки Количество() = 0 — обработка молча ничего не делает
03
Маска *.xml при необходимости обойти подкаталоги — вложенные папки отфильтровываются маской
04
Синхронные файловые вызовы в тонком клиенте — ошибки при режиме запрета модальности
05
Поиск по сетевому пути через подключённый диск (Z:\) на сервере — диск не подключён для служебной учётной записи, используйте UNC-путь

FAQ

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

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

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

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

Можно ли искать файлы по части имени, а не по расширению?

Да, маска поддерживает любые шаблоны: «отчёт*.xlsx» найдёт файлы, начинающиеся со слова «отчёт», а «накладная» — содержащие это слово в любом месте имени.

Как получить список файлов в веб-клиенте?

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

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

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

Есть ли альтернатива НайтиФайлы?

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

Итог

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

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