Как программно добавить файл к объекту в 1С с использованием БСП?

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

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

Анализ проблемы и выбор подхода

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

Существует два основных подхода к решению этой задачи:

  1. Низкоуровневый: Ручное создание элементов справочников присоединенных файлов и версий файлов.
  2. Высокоуровневый: Использование стандартных функций модуля РаботаСФайлами.

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


НовСправочник = Справочники.Файлы.СоздатьЭлемент();
НовСправочник.ТекстХранилище = Строка.Данные;
НовСправочник.ДатаСоздания = Строка.Период;
НовСправочник.Наименование = "ПервыйФайл";
НовСправочник.ВладелецФайла = Строка.СсылкаНаОбъект;
НовСправочник.Расширение = Строка.Расширение;
НовСправочник.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе;
НовСправочник.Записать();

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

Использование универсальных функций БСП

Для программного добавления файла наиболее эффективным является использование общего модуля РаботаСФайлами. Основная функция, которую мы будем использовать — ДобавитьФайл. Она берет на себя всю "черную работу": создание карточки файла, создание первой версии, расчет размера и контрольной суммы MD5, а также физическое размещение данных в зависимости от настроек системы. Для быстрой навигации по экспортным методам подсистем БСП можно использовать инструмент для исследования процедур и функций конфигурации.

Рассмотрим подробнее механизм работы через временный файл, если у вас на входе есть объект ДвоичныеДанные. Нам потребуется сначала сохранить эти данные во временное хранилище на сервере или в файл на диске.

Посмотрим на пример кода, реализующий этот алгоритм:


// 1. Получаем путь для временного файла на сервере
ПутьКФайлу = ПолучитьИмяВременногоФайла(Расширение);
ДвоичныеДанные.Записать(ПутьКФайлу);

// 2. Определяем параметры добавления
ПараметрыФайла = РаботаСФайлами.ПараметрыДобавленияФайла();
ПараметрыФайла.Автор = Пользователи.ТекущийПользователь();
ПараметрыФайла.ВладелецФайла = СсылкаНаОбъект;
ПараметрыФайла.ИмяБезРасширения = "Скан_Договора";
ПараметрыФайла.Расширение = "pdf";

// 3. Вызываем добавление
Результат = РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, ПутьКФайлу);

// 4. Удаляем временный файл
УдалитьФайлы(ПутьКФайлу);

Важный момент: в современных редакциях БСП (начиная с 2.4/3.0) функция ДобавитьФайл может принимать в качестве второго параметра не только путь к диску, но и АдресВоВременномХранилище. Это позволяет избежать лишних операций записи на диск сервера.

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

В типовых конфигурациях (ERP, КА, УТ 11) файлы редко хранятся в общем справочнике Файлы. Вместо этого для каждого типа документа создается отдельный справочник, например, ДоговорыКонтрагентовПрисоединенныеФайлы. Чтобы ваш код был универсальным и работал для любого объекта, рекомендуется использовать функцию РаботаСФайлами.ИмяСправочникаПрисоединенныхФайлов.

Проанализируем ситуацию, когда нам нужно добавить файл к произвольному объекту:


ТипВладельца = ТипЗнч(СсылкаНаОбъект);
ИмяСправочника = РаботаСФайлами.ИмяСправочникаПрисоединенныхФайлов(ТипВладельца);

Если ЗначениеЗаполнено(ИмяСправочника) Тогда
    // Теперь мы знаем, какой справочник использовать для владельца
    // Функция ДобавитьФайл сама определит нужный тип по владельцу
КонецЕсли;

Механизм хранения: База данных или Тома на диске?

Часто возникает вопрос: где физически сохранится файл после выполнения программного кода? Ответ зависит от настроек константы СпособХраненияФайлов и справочника ТомаХраненияФайлов.

Если вы используете высокоуровневые функции РаботаСФайлами, вам не нужно об этом беспокоиться. Система сама проверит:

  1. Если настроены тома и на них есть свободное место, файл будет перемещен в соответствующую папку на сервере; при этом важно обеспечить регулярное автоматическое архивирование баз 1С для защиты данных.
  2. Если тома не настроены, данные будут помещены в информационную базу (в регистр сведений ДвоичныеДанныеФайлов).

Важно: При использовании томов в регистре ДвоичныеДанныеФайлов запись создана не будет, вместо этого в карточке версии файла будет прописана ссылка на том и путь внутри тома. Именно поэтому ручное создание записей (как в первом примере) часто ломает логику работы с внешними хранилищами.

Особенности для Веб-клиента

Если ваша задача подразумевает выбор файла пользователем в веб-интерфейсе, вы не сможете передать прямой путь к файлу на диске (C:\MyFiles\File.pdf) в серверную процедуру из-за ограничений безопасности браузера. В этом случае алгоритм действий будет следующим:

  1. На клиенте вызываем ПоместитьФайлНаСервер.
  2. Передаем полученный АдресВоВременномХранилище на сервер.
  3. На сервере вызываем метод ДобавитьФайл, передавая этот адрес.

Рассмотрим пример кода для серверной части при работе с временным хранилищем:


Функция ПрикрепитьФайлИзХранилища(Владелец, АдресХранилища, ИмяФайла) Экспорт
    
    // Подготавливаем описание файла
    ПараметрыФайла = РаботаСФайлами.ПараметрыДобавленияФайла();
    ПараметрыФайла.ВладелецФайла = Владелец;
    ПараметрыФайла.Наименование = ИмяФайла;
    
    // БСП сама извлечет данные из хранилища и создаст все необходимые записи
    НовыйФайлСсылка = РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, АдресХранилища);
    
    Возврат НовыйФайлСсылка;
    
КонецФункции

Регистрация версий файла

Помните, что в БСП файл — это сложный объект. Он состоит из "Карточки" (элемент справочника присоединенных файлов) и "Версии" (элемент справочника ВерсииФайлов). Пользователь всегда видит карточку, но когда он нажимает "Открыть", система обращается к активной версии. При использовании метода ДобавитьФайл система автоматически создает первую версию и устанавливает её как текущую. Если же вы добавляете новую версию к уже существующему файлу, следует использовать метод РаботаСФайлами.ОбновитьФайл.

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

← На главную