Разработка и Конфигурация · 10 мин
Как получить список файлов в папке в 1С
Как получить список файлов в папке в 1С: метод НайтиФайлы, маски поиска, рекурсия по подкаталогам, проверка атрибутов, примеры кода и типичные ошибки разработчиков.
Получение списка файлов в каталоге — одна из базовых задач при разработке обменов данными, загрузке прайсов, обработке выгрузок из других систем и автоматизации рутинных операций в 1С. Во встроенном языке для этого предусмотрен метод НайтиФайлы(), который возвращает массив объектов типа Файл с полной информацией о каждом найденном элементе.
Метод работает одинаково в тонком, толстом и веб-клиенте, но с важной оговоркой: в клиент-серверном режиме код, выполняемый на сервере, видит файловую систему сервера, а не компьютера пользователя. Это самая частая причина «неработающего» кода, который прекрасно находил файлы в файловой базе на локальной машине.
Ниже разобран синтаксис метода, работа с масками и подкаталогами, проверка результатов, а также сценарии для управляемых форм и асинхронного режима, который стал стандартом в современных конфигурациях.
Синтаксис метода НайтиФайлы
Метод НайтиФайлы() доступен глобально и принимает три параметра, из которых обязательный только первый:
- Путь — строка с путём к каталогу, в котором выполняется поиск. Может быть абсолютным (
C:\Обменили/mnt/exchange). - Маска — шаблон отбора имён файлов, например
.xmlилиprice_.csv. Если параметр не указан, возвращаются все файлы и подкаталоги. - ИскатьВПодкаталогах — булево, определяет, нужен ли рекурсивный обход вложенных папок.
Результат — массив объектов типа Файл. Если ни один файл не подошёл под условия, возвращается пустой массив, а не Неопределено и не исключение. Это важно для корректной проверки результата.
МассивФайлов = НайтиФайлы("C:\Обмен", "*.xml", Ложь);
Для Каждого Файл Из МассивФайлов Цикл
Сообщить(Файл.ПолноеИмя);
КонецЦикла;Обратите внимание: метод возвращает не только файлы, но и подкаталоги, если они подходят под маску. Маска . в некоторых случаях отбирает только имена с точкой, поэтому для получения всего содержимого надёжнее использовать маску * или опускать параметр.
Базовый пример: получить и перебрать файлы
Минимальный рабочий фрагмент выглядит так: сначала проверяем существование каталога, затем ищем файлы и перебираем массив. Проверка каталога нужна, потому что обращение к несуществующему пути вызовет исключение.
Функция ПолучитьСписокФайлов(ПутьКПапке, Маска = "*")
Результат = Новый Массив;
Каталог = Новый Файл(ПутьКПапке);
Если Не Каталог.Существует() Тогда
Возврат Результат;
КонецЕсли;
НайденныеФайлы = НайтиФайлы(ПутьКПапке, Маска, Ложь);
Для Каждого Элемент Из НайденныеФайлы Цикл
Если Не Элемент.ЭтоКаталог() Тогда
Результат.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Обернуть поиск в функцию удобно ещё и потому, что вызов НайтиФайлы без предварительной проверки каталога — типичный источник ошибок при работе с сетевыми путями, которые могут быть временно недоступны.
- 1Создайте объект Файл с путём к каталогу и проверьте методом Существует()
- 2Вызовите НайтиФайлы с путём, маской и признаком поиска в подкаталогах
- 3Проверьте, что массив не пуст: НайденныеФайлы.Количество() > 0
- 4Переберите массив и отфильтруйте каталоги через ЭтоКаталог()
- 5Обработайте каждый файл: прочитайте, переместите в архив или удалите
Как отличить файлы от папок и прочитать атрибуты
Каждый элемент результата — объект Файл с набором методов и свойств. Ключевые из них:
ЭтоКаталог()— возвращает Истина, если элемент является папкой;ЭтоФайл()— возвращает Истина для обычного файла;ПолноеИмя— полный путь включая имя файла;Имя— имя файла с расширением,ИмяБезРасширенияиРасширение— отдельные части имени;Размер()— размер в байтах;ПолучитьВремяИзменения()— дата и время последней модификации.
Атрибуты полезны для отбора: например, обрабатывать только файлы, изменённые за последние сутки, или пропускать нулевого размера, которые часто остаются после незавершённой выгрузки. Проверка Размер() = 0 — простой способ отсечь «битые» файлы до попытки чтения.
Свойство Расширение возвращает строку вида .xml в нижнем регистре, поэтому сравнение лучше выполнять через НРег(Элемент.Расширение) = ".xml" — это защитит от файлов с расширением в верхнем регистре.
Поиск по маске и рекурсивный обход подкаталогов
Маски поддерживают стандартные символы подстановки: заменяет любую последовательность символов, ? — один произвольный символ. Можно перечислить несколько масок через точку с запятой, например .xml;*.csv, чтобы одним вызовом получить файлы разных форматов.
Третий параметр включает рекурсию: при значении Истина метод обойдёт все вложенные папки и вернёт полный список. Это удобно, но на больших деревьях каталогов рекурсивный поиск может занимать заметное время и блокировать сеанс. Если структура папок известна, иногда быстрее обойти подкаталоги вручную с контролем глубины.
Сравнение вариантов
Быстро, предсказуемо. Подходит для плоских папок обмена, где файлы складываются в один каталог.
Один вызов вместо цикла, но нет контроля глубины и порядка обхода. Осторожно на больших сетевых деревьях.
Единственный вариант для управляемых форм с отказом от модальности и для веб-клиента. Требует описания оповещения.
Работа в клиент-серверном режиме и управляемых формах
Главное правило: НайтиФайлы видит файловую систему того узла, где выполняется код. Серверный вызов ищет на дисках сервера 1С, клиентский — на компьютере пользователя. Если обменная папка лежит на сетевом ресурсе, убедитесь, что у учётной записи, под которой работает агент сервера 1С, есть к ней доступ — у системных учётных записей сетевые диски пользователя обычно недоступны.
В управляемых формах при включённом режиме отказа от модальности синхронные файловые вызовы на клиенте запрещены или нежелательны. Используйте асинхронный аналог НачатьПоискФайлов с описанием оповещения:
&НаКлиенте
Процедура НайтиФайлыНачало(Команда)
Оповещение = Новый ОписаниеОповещения("НайтиФайлыЗавершение", ЭтотОбъект);
НачатьПоискФайлов(Оповещение, ПутьККаталогу, "*.xml", Ложь);
КонецПроцедуры
&НаКлиенте
Процедура НайтиФайлыЗавершение(НайденныеФайлы, ДополнительныеПараметры) Экспорт
Для Каждого Файл Из НайденныеФайлы Цикл
Сообщить(Файл.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
Для регламентных заданий на сервере асинхронность не нужна — там работает обычный НайтиФайлы. Но путь к папке обмена храните в настройках (константе или справочнике), а не зашивайте в код: при переносе базы или смене сервера жёстко прописанный путь станет источником сбоев.
Проверка результата и обработка ошибок
Пустой массив — штатная ситуация, а не ошибка. Различайте три случая: каталог не существует (проверяется заранее), каталог пуст (нулевая длина массива) и файлы есть, но не подходят под маску. Для диагностики полезно временно запросить содержимое каталога без маски и сравнить с результатом по маске.
Операции с файлами стоит оборачивать в попытку-исключение, особенно при работе с сетевыми путями: обрыв связи, отсутствие прав, блокировка файла антивирусом или другой программой — всё это вызывает исключения, которые не должны ронять всю обработку.
Как проверить результат
Количество элементов больше нуля, все элементы — объекты Файл
Массив пуст при заведомо существующих файлах — проверьте путь и сторону выполнения
ЭтоФайл() возвращает Истина для обрабатываемых элементов
В списке подкаталоги, обработка падает на чтении
Размер больше нуля, файл открывается на чтение
Размер 0 или исключение при открытии — файл занят или не дописан
Частые вопросы
Как получить только подкаталоги, а не файлы?
Вызовите НайтиФайлы с маской «*» и отфильтруйте массив условием Элемент.ЭтоКаталог(). Отдельного параметра «только папки» у метода нет, отбор выполняется в цикле.
Почему НайтиФайлы возвращает пустой массив, хотя файлы в папке есть?
Чаще всего код выполняется не там: серверный вызов ищет на дисках сервера, а не на компьютере пользователя. Также проверьте маску (регистр расширения, лишние пробелы) и права учётной записи на каталог.
Как отсортировать найденные файлы по дате изменения?
Метод не гарантирует порядок. Перенесите объекты в таблицу значений с колонками «Файл» и «ДатаИзменения», затем вызовите Сортировать("ДатаИзменения") — так получите нужный порядок обработки.
Можно ли искать файлы по нескольким расширениям сразу?
Да, перечислите маски через точку с запятой: «.xml;.csv;*.txt». Один вызов вернёт файлы всех указанных типов в общем массиве.
Работает ли НайтиФайлы в веб-клиенте?
Синхронный вызов в веб-клиенте недоступен. Используйте асинхронный НачатьПоискФайлов с описанием оповещения и предварительным подключением расширения работы с файлами.
Как безопасно удалить обработанные файлы?
Удаляйте только после успешного завершения обработки конкретного файла, а не всего пакета. Надёжная практика — не удалять, а перемещать в подпапку «Архив» с датой в имени: это оставляет возможность восстановления при ошибке.
Что важно запомнить
Список файлов получают методом НайтиФайлы с путём, маской и признаком рекурсии; результат — массив объектов Файл, который нужно фильтровать от каталогов. Проверяйте существование папки заранее, учитывайте сторону выполнения кода в клиент-серверном режиме, а в управляемых формах используйте асинхронный НачатьПоискФайлов.