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

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

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

Постановка задачи и анализ исходных данных

Представим ситуацию: у нас есть документ ПриходМатериалов, у которого заполнен реквизит ТТН (тип Строка). На диске в определенной папке (например, C:\files\) лежат файлы, названные по шаблону [Номер_ТТН].pdf. Нам необходимо просканировать каталог, найти нужный файл и добавить его в список присоединенных файлов конкретного документа.

Для решения этой задачи нам потребуется выполнить три основных шага:

  1. Организовать поиск файлов по маске в файловой системе.
  2. Передать найденный файл в информационную базу (через временное хранилище или напрямую).
  3. Зарегистрировать файл в справочнике присоединенных файлов, используя типовые методы БСП.

Шаг 1. Программный поиск файлов на диске

Для поиска файлов в языке 1С используется глобальный метод НайтиФайлы. Проанализируем его работу. Метод принимает два основных аргумента: путь к каталогу и маску поиска.

Рассмотрим пример кода для поиска файлов, где имя файла совпадает с реквизитом ТТН документа:


// ТекДок - это ссылка на документ ПриходМатериалов
КаталогПоиска = "C:\files";
МаскаПоиска = ТекДок.ТТН + ".*"; // Ищем файл с любым расширением, имя которого совпадает с ТТН

НайденныеФайлы = НайтиФайлы(КаталогПоиска, МаскаПоиска);

Для Каждого НайденныйФайл Из НайденныеФайлы Цикл
    // Здесь будет логика добавления файла
    Сообщить("Найден файл: " + НайденныйФайл.ПолноеИмя);
КонецЦикла;

Важный нюанс: если поиск выполняется на стороне сервера, путь C:\files должен быть доступен пользователю, под которым запущена служба 1C:Enterprise. Если это локальный путь на компьютере пользователя, код должен исполняться в контексте клиента (&НаКлиенте).

Шаг 2. Использование механизмов БСП для добавления файлов

В современных конфигурациях (БП 3.0, УТ 11, ERP 2) работа с файлами реализована через подсистему РаботаСФайлами. Использовать прямую запись в справочники не рекомендуется, так как БСП берет на себя управление томами хранения, создание карточек файлов и связей.

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

Проанализируем исправленный код из обсуждения, который учитывает особенности работы со ссылками и объектами:


// ТекДок - это Ссылка на документ. 
// Использование Ссылки критично, так как Объект нельзя передавать между клиентом и сервером в параметрах БСП
НайденныеФайлы = НайтиФайлы("C:\files", ТекДок.ТТН + ".*");

Для Каждого НайденныйФайл Из НайденныеФайлы Цикл
    // Используем типовой метод БСП
    // Первый параметр: Ссылка на документ-владелец
    // Второй параметр: Полный путь к файлу на диске
    РаботаСФайлами.ДобавитьФайлСДиска(ТекДок, НайденныйФайл.ПолноеИмя);
КонецЦикла;

Важно: При использовании метода ДобавитьФайлСДиска записывать сам документ (вызывать ТекДок.Записать()) не нужно. Файл создается как отдельный объект в подчиненном справочнике, а ссылка на владельца устанавливается внутри метода.

Шаг 3. Обработка ошибок "Мутабельных значений"

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

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

Расширенные возможности и современные методы

Посмотрим на ситуацию шире. Начиная с версии платформы 8.3.15, компания 1С активно внедряет асинхронную модель работы. В веб-клиенте или при работе в облаке прямое обращение к файлам через НайтиФайлы может быть заблокировано. В таких случаях рекомендуется использовать асинхронный метод НайтиФайлыАсинх.

Пример использования асинхронного поиска:


&НаКлиенте
Асинх Процедура НайтиИДобавитьФайлы()
    Каталог = "C:\Temp";
    Маска = "ИН-2010*";
    
    НайденныеФайлы = Ждать НайтиФайлыАсинх(Каталог, Маска);
    
    Для Каждого Файл Из НайденныеФайлы Цикл
        // Дальнейшая логика обработки
    КонецЦикла;
КонецПроцедуры

Также стоит учитывать особенности различных операционных систем. Если ваш сервер 1С работает на Linux, помните:

Оптимизация при больших объемах данных

Если в папке C:\files хранятся тысячи документов, метод НайтиФайлы может работать долго, замедляя работу пользователя. Рассмотрим способы оптимизации:

  1. Распределение по подпапкам: Группируйте сканы по годам или месяцам (например, C:\files\2024\10\). Это значительно ускорит работу файловой системы ОС.
  2. Регламентные задания: Вместо поиска файла в момент открытия документа, можно настроить фоновое задание, которое раз в час сканирует папку "входящих" файлов, сопоставляет их по номеру с документами в базе и прикрепляет автоматически.
  3. Проверка на дубли: Перед вызовом ДобавитьФайл желательно проверить, не прикреплен ли уже файл с таким именем к документу, чтобы не забивать базу одинаковыми сканами при повторном запуске обработки.

В заключение отметим, что для конфигураций, где включен сервис "1С:Распознавание первичных документов", процесс можно автоматизировать еще сильнее. Система не просто "подцепит" файл по имени, но и распознает его содержимое (суммы, номенклатуру, контрагента) и предложит сопоставить с существующим документом ПриходМатериалов по совокупности признаков, даже если имя файла не соответствует номеру ТТН.

← На главную