Как осуществить поиск файлов в каталоге по списку имен в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Чтение списка из текстового файла и запуск поиска

Сначала выясним алгоритм действий. Чтобы произвести поиск по списку, мы должны прочитать исходный txt-файл, извлечь оттуда имена или шаблоны файлов в цикле, а затем для каждой строки выполнить поиск в целевом каталоге. Для чтения текстовых документов в 1С используется объект ТекстовыйДокумент, а для поиска — метод НайтиФайлы().

Посмотрим на пример базовой реализации такого алгоритма:


// Создаем объект для чтения файла
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать("C:\Temp\СписокИмен.txt");

КаталогПоиска = "C:\TargetFolder\";

// Перебираем все строки документа
Для Индекс = 1 По ТекстДок.КоличествоСтрок() Цикл
    МаскаПоиска = ТекстДок.ПолучитьСтроку(Индекс);
    
    Если ЗначениеЗаполнено(МаскаПоиска) Тогда
        // Осуществляем поиск
        МассивНайденныхФайлов = НайтиФайлы(КаталогПоиска, МаскаПоиска);
        
        // Обработка результатов
        Для Каждого НайденныйФайл Из МассивНайденныхФайлов Цикл
            Сообщить("Найден файл: " + НайденныйФайл.ПолноеИмя);
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

Как правильно задавать формат и маску файла?

В процессе работы часто возникает вопрос: что вводить в качестве формата или маски при поиске через НайтиФайлы()? Обязательно ли указывать расширение файла? Нет, не обязательно. Разберем подробнее, как работают символы подстановки в 1С.

Для создания гибких условий поиска мы можем использовать специальные символы в маске:

  1. Символ "*" (Звездочка) — заменяет любое количество любых символов (включая их полное отсутствие).
  2. Символ "?" (Вопросительный знак) — строго заменяет один любой символ.

Рассмотрим примеры применения масок:

  1. *.txt — найдет абсолютно все файлы в каталоге с расширением txt.
  2. *Name* — найдет все файлы, в названии (или расширении) которых содержится слово "Name".
  3. Name* — найдет все файлы, имя которых начинается с "Name", независимо от расширения.
  4. file?.txt — найдет файлы file1.txt, fileA.txt, но пропустит file12.txt, так как вопросительный знак заменяет только один символ.

Кроме того, платформа 1С поддерживает использование сложных масок. Если нам нужно искать сразу несколько типов файлов или применять классы символов, мы можем перечислять их через точку с запятой. Например, маска *.docx;*.[Rr][Ff];doc[0-9].txt позволит найти документы Word, файлы с расширением rf или RF, а также файлы формата doc1.txt, doc2.txt и так далее.

Поиск во вложенных папках (подкаталогах)

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

Посмотрим на пример вызова с поиском по вложенным папкам:

МассивФайлов = НайтиФайлы("C:\TargetFolder\", "*.txt", Истина);

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

Работа с возвращаемым результатом

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

Объект Файл обладает множеством полезных свойств и методов, к которым мы можем обращаться в цикле перебора:

  1. Файл.Имя — выдаст имя файла вместе с его расширением.
  2. Файл.ПолноеИмя — выдаст абсолютный (полный) путь к файлу на жестком диске (например: C:\Temp\document.txt).
  3. Файл.Расширение — вернет только расширение файла (включая точку).
  4. Методы Файл.ЭтоКаталог() и Файл.ЭтоФайл() — критически важные функции для проверки типа найденного объекта.

Обратите внимание на последнюю особенность. Под заданную маску (например, *Name*) могут попасть не только обычные файлы, но и названия директорий (папок). Если мы планируем открывать или читать файлы, нам нужно отсечь папки. Разберем на примере:


Для Каждого НайденныйОбъект Из МассивНайденныхФайлов Цикл
    Если НайденныйОбъект.ЭтоФайл() Тогда
        Сообщить("Найден именно файл: " + НайденныйОбъект.Имя);
    ИначеЕсли НайденныйОбъект.ЭтоКаталог() Тогда
        Сообщить("Найдена папка: " + НайденныйОбъект.Имя);
    КонецЕсли;
КонецЦикла;

Современный асинхронный поиск файлов

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

Рассмотрим, как выполнить ту же задачу с помощью современного метода НайтиФайлыАсинх(). Для этого мы будем использовать операторы Асинх и Ждать:


&НаКлиенте
Асинх Процедура ВыполнитьПоискФайлов(Команда)
    
    Каталог = "Z:\АрхивДокументов\";
    Маска = "*.pdf";
    
    // Интерфейс не зависнет во время выполнения этой строки
    МассивНайденных = Ждать НайтиФайлыАсинх(Каталог, Маска, Истина);
    
    Для Каждого НайденныйФайл Из МассивНайденных Цикл
        Если НайденныйФайл.ЭтоФайл() Тогда
            Сообщить(НайденныйФайл.ПолноеИмя);
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Особенности выполнения поиска на сервере 1С

Выясним еще один важный нюанс. Метод поиска можно вызывать как в контексте &НаКлиенте, так и &НаСервере. Однако поведение программы будет кардинально отличаться.

Если мы вызываем код на сервере, поиск будет происходить исключительно в файловой системе того компьютера (или виртуальной машины), где установлен кластер серверов 1С:Предприятие. Локальные диски пользователя (например, диск D:\ на его ноутбуке) серверу напрямую недоступны.

Кроме того, видимость файлов и папок при серверном вызове строго ограничена правами той учетной записи операционной системы (ОС), под которой запущена служба сервера 1С (обычно это пользователь USR1CV8). Критически важно понимать: то, что доступно и видно вам как администратору Windows, может быть совершенно недоступно серверу 1С. Если метод возвращает пустой массив на сервере, хотя файлы там точно есть — первым делом проверьте права доступа пользователя службы 1С к этому каталогу.

← На главную