Разработка и Конфигурация · 11 мин
Как в 1С получить список файлов в каталоге
Как в 1С получить список файлов в каталоге: функция НайтиФайлы, маски, рекурсивный поиск, работа на клиенте и сервере, типичные ошибки и готовые примеры кода.
Задача получить список файлов в каталоге возникает в 1С постоянно: при загрузке прайсов из папки обмена, при обработке выгрузок из других систем, при подборе изображений товаров, при архивации журналов. Во встроенном языке для этого есть штатная функция НайтиФайлы(), которая работает и в тонком клиенте, и на сервере, и в веб-клиенте с рядом ограничений.
Функция возвращает массив объектов типа Файл, из которых можно прочитать имя, полный путь, расширение, размер, время изменения и признак «это каталог». Дальше эти данные обычно складывают в таблицу значений, показывают пользователю или перебирают в цикле для пакетной обработки.
Главные подводные камни — неочевидное поведение масок, разница между поиском на клиенте и на сервере, права доступа к сетевым папкам и обязательность асинхронных методов в тонком клиенте. Ниже разобраны рабочие примеры кода, варианты фильтрации и способы проверки результата.
Функция НайтиФайлы: синтаксис и базовый пример
Функция имеет три параметра: путь к каталогу, маска поиска и признак поиска в подкаталогах. Все параметры, кроме первого, необязательны. Если маску не указать, вернутся все файлы и подкаталоги первого уровня.
НайденныеФайлы = НайтиФайлы("D:\Обмен\Входящие", "*.xml");
Для Каждого Файл Из НайденныеФайлы Цикл
Если Не Файл.ЭтоКаталог() Тогда
Сообщить(Файл.ПолноеИмя + " — " + Файл.Размер() + " байт");
КонецЕсли;
КонецЦикла;
Объект Файл даёт доступ к свойствам: Имя (имя с расширением), ИмяБезРасширения, Расширение, Путь (каталог без имени файла), ПолноеИмя, а также методам Размер(), ПолучитьВремяИзменения(), ЭтоКаталог(). Этого достаточно, чтобы построить полноценный реестр содержимого папки.
НайденныеФайлы = НайтиФайлы("D:\Обмен", "*.xml", Истина);
Для Каждого Файл Из НайденныеФайлы Цикл
Если Не Файл.ЭтоКаталог() Тогда
Сообщить(Файл.ПолноеИмя);
КонецЕсли;
КонецЦикла;Маски поиска и фильтрация по типу файлов
Маска задаётся символами подстановки: — любая последовательность символов, ? — один любой символ. Типичные варианты: .xml — только XML-файлы, .jpg — изображения, .txt — текстовые выгрузки, . — всё содержимое.
Важная особенность: маска применяется и к именам каталогов. Поэтому вызов НайтиФайлы(Путь, ".xml", Истина) в рекурсивном режиме вернёт XML-файлы даже из вложенных папок, но сами подкаталоги в результат не попадут, если их имена не совпадают с маской. Если нужно получить и папки, и файлы, используйте маску . или , а фильтрацию выполняйте в цикле по расширению.
Если требуется отобрать файлы нескольких типов, одной маской не обойтись — либо вызывайте НайтиФайлы несколько раз с разными масками и объединяйте массивы, либо забирайте всё и проверяйте расширение вручную:
ВсеФайлы = НайтиФайлы(КаталогОбмена, ".", Истина);
Для Каждого Файл Из ВсеФайлы Цикл
Расширение = НРег(Файл.Расширение);
Если Расширение = ".xml" Или Расширение = ".csv" Тогда
// обработка файла
КонецЕсли;
КонецЦикла;
Рекурсивный обход подкаталогов
Третий параметр функции включает поиск во всех вложенных папках. Это удобно, когда структура каталога заранее неизвестна — например, архивы выгрузок разложены по папкам с датами. Один вызов заменяет самописную рекурсию.
Однако на больших деревьях каталогов (десятки тысяч файлов, глубокая вложенность) рекурсивный поиск занимает заметное время и выполняется синхронно — интерфейс в этот момент «подвисает». Для таких случаев лучше ограничивать область поиска конкретной подпапкой или запускать обработку в фоновом задании на сервере.
Если нужно получить только структуру подкаталогов без файлов, отфильтруйте результат по методу ЭтоКаталог():
ВсеЭлементы = НайтиФайлы(КорневойКаталог, "*", Истина);
Для Каждого Элемент Из ВсеЭлементы Цикл
Если Элемент.ЭтоКаталог() Тогда
Сообщить("Папка: " + Элемент.ПолноеИмя);
КонецЕсли;
КонецЦикла;
Поиск на клиенте и на сервере: в чём разница
НайтиФайлы ищет там, где выполняется код. В клиент-серверном варианте серверный вызов видит файловую систему сервера, а не компьютера пользователя. Если пользователь указывает путь «D:\Документы», а код выполняется на сервере, поиск пойдёт по диску D сервера — и, скорее всего, вернёт пустой массив.
Для серверного поиска путь должен быть доступен учётной записи, под которой работает агент сервера 1С (обычно USR1CV8). Сетевые папки лучше указывать в формате UNC (\\server\share\папка) и заранее убедиться, что у служебной учётной записи есть права на чтение.
В тонком и веб-клиенте для работы с файловой системой применяется расширение работы с файлами, а модальные и синхронные вызовы в современных конфигурациях ограничены. Для интерактивного выбора каталога пользователем используйте ДиалогВыбораФайла в асинхронном режиме с описанием оповещения, а не прямой синхронный вызов.
Как выбрать действие
Вывод списка в таблицу значений и на форму
На практике массив файлов почти всегда преобразуют в таблицу значений — её удобно сортировать, показывать в табличном поле и передавать между процедурами. Типовой приём выглядит так:
ТаблицаФайлов = Новый ТаблицаЗначений;
ТаблицаФайлов.Колонки.Добавить("Имя");
ТаблицаФайлов.Колонки.Добавить("ПолноеИмя");
ТаблицаФайлов.Колонки.Добавить("Размер");
ТаблицаФайлов.Колонки.Добавить("ДатаИзменения");
Для Каждого Файл Из НайденныеФайлы Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
Строка = ТаблицаФайлов.Добавить();
Строка.Имя = Файл.Имя;
Строка.ПолноеИмя = Файл.ПолноеИмя;
Строка.Размер = Файл.Размер();
Строка.ДатаИзменения = Файл.ПолучитьВремяИзменения();
КонецЦикла;
ТаблицаФайлов.Сортировать("ДатаИзменения Убыв");
Сортировка по дате изменения полезна, когда из папки обмена нужно брать только самый свежий файл или обрабатывать выгрузки в хронологическом порядке. Обратите внимание: на форме таблицу значений обычно хранят в реквизите формы соответствующего типа, а заполнение выполняют в серверной процедуре.
- 1Определите, где лежит каталог: на клиенте или на сервере
- 2Сформируйте путь и маску поиска
- 3Вызовите НайтиФайлы с нужным признаком рекурсии
- 4Отфильтруйте каталоги через ЭтоКаталог() при необходимости
- 5Перенесите результат в таблицу значений или обработайте в цикле
- 6Проверьте, что массив не пустой, прежде чем продолжать обработку
Проверка результата и обработка пустого результата
Если каталог не существует, путь указан с ошибкой или по маске ничего не найдено, НайтиФайлы возвращает пустой массив — исключения не возникает. Поэтому перед обработкой всегда проверяйте НайденныеФайлы.Количество(), иначе логика «тихо» отработает вхолостую, и причину отсутствия загруженных данных придётся искать долго.
Полезно различать ситуации «каталога нет» и «каталог есть, но файлов нет». Для первой проверки создайте объект Файл с путём к каталогу и вызовите Существует(). Это упростит диагностику: пользователь получит понятное сообщение «папка недоступна», а не «файлы не найдены».
Как проверить результат
Массив содержит ожидаемое число элементов
Пустой массив при заведомо заполненной папке — проверяйте путь и маску
ПолноеИмя содержит абсолютный путь к файлу
Относительные пути — задайте полный путь к каталогу в вызове
Файл(Путь).Существует() возвращает Истина
Ложь — неверный путь или нет прав у учётной записи
В массиве только нужные типы файлов
Попали каталоги или лишние расширения — уточните маску или фильтр в цикле
Типичные ошибки и ограничения
Самая частая ошибка — поиск на сервере по клиентскому пути. Вторая по популярности — ожидание, что маска *.xml вернёт ещё и подкаталоги для дальнейшего обхода: она их отфильтровывает. Третья — игнорирование прав доступа: служба агента 1С по умолчанию работает под учётной записью без доступа к пользовательским сетевым ресурсам и подключённым дискам.
Ещё одна группа проблем связана с производительностью: рекурсивный поиск по огромным каталогам в интерактивном режиме, повторный вызов НайтиФайлы внутри цикла вместо однократного получения списка, отсутствие фонового выполнения для длительных операций. Все эти ошибки устраняются архитектурно — правильным выбором места выполнения кода.
FAQ
Как получить только файлы, без подкаталогов?
Вызовите НайтиФайлы с нужной маской и в цикле пропускайте элементы, для которых ЭтоКаталог() возвращает Истина. Отдельного параметра «только файлы» у функции нет.
Почему НайтиФайлы возвращает пустой массив, хотя файлы в папке есть?
Чаще всего код выполняется на сервере, а путь указывает на диск клиентского компьютера. Также проверьте маску, регистр расширений (на Linux), права доступа учётной записи агента 1С и сам факт существования каталога через Файл(Путь).Существует().
Можно ли искать файлы по части имени, а не по расширению?
Да, маска поддерживает любые шаблоны: «отчёт*.xlsx» найдёт файлы, начинающиеся со слова «отчёт», а «накладная» — содержащие это слово в любом месте имени.
Как получить список файлов в веб-клиенте?
Напрямую перебрать локальную папку в веб-клиенте нельзя без расширения работы с файлами. Практичные варианты — выполнить поиск на сервере по доступному серверу пути или использовать асинхронные методы с установленным расширением.
Как отсортировать найденные файлы по дате?
НайтиФайлы не гарантирует порядок. Перенесите результат в таблицу значений с колонкой «ДатаИзменения» (значение — Файл.ПолучитьВремяИзменения()) и вызовите метод Сортировать с нужным направлением.
Есть ли альтернатива НайтиФайлы?
Для обхода дерева каталогов можно использовать рекурсивную процедуру с объектом Файл, но встроенная функция делает это быстрее и короче. Для сценариев обмена данными вне платформы иногда применяют скрипты ОС, однако внутри 1С НайтиФайлы — стандартный инструмент.
Что важно запомнить
Список файлов в каталоге получают функцией НайтиФайлы(Путь, Маска, Рекурсивно), которая возвращает массив объектов Файл. Поиск выполняется там, где исполняется код: серверный вызов не видит диски пользователя. Всегда проверяйте количество найденных элементов, фильтруйте каталоги через ЭтоКаталог() и выносите обход больших папок в фоновые задания.