Разработка собственных справочников или документов в расширении конфигурации часто ставит перед разработчиком задачу обеспечения полноценной работы с присоединенными файлами (сканами, договорами, изображениями). Типовой механизм БСП предполагает использование ОпределяемыхТипов, и мы разберем, как эффективно интегрировать ваш объект в эту систему, не нарушая целостность основной конфигурации.
Если ваша инфраструктура позволяет использовать платформу версии 8.3.20 и выше, процесс максимально упрощается. Вам больше не нужно «затаскивать» все объекты из основной конфигурации в расширение или снимать её с поддержки.
ОпределяемыеТипы, а именно ВладелецПрисоединенныхФайлов.ОпределяемогоТипа прямо в расширении.Это «золотой стандарт» разработки, так как он позволяет сразу задействовать типовой функционал подсистемы РаботаСФайлами, включая формы, списки и логику хранения, без написания дополнительного кода.
Если обновление платформы невозможно, нам придется создать собственный механизм, имитирующий работу БСП. Это потребует создания ряда объектов в расширении и перехвата логики типовых процедур.
Для начала создадим Регистр сведений, который будет хранить двоичные данные, например, СОГ_ДвоичныеДанныеФайлов. В нем должен быть ресурс типа ХранилищеЗначения. Также нам потребуются подписки на события для обеспечения целостности данных.
Разберем реализацию подписки на события. Нам нужно перехватить методы, отвечающие за запись данных, чтобы корректно сохранять файлы в наш регистр:
Процедура ВыполнитьДействияПриЗаписиПрисоединенногоФайла(Источник, Отказ) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
ЗаписатьДанныеФайлаВРегистрПриОбмене(Источник);
Возврат;
КонецЕсли;
ТипЗначенияРасширения = СОГ_ДопФункцииПовторИсп.ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл();
Если ТипЗначенияРасширения.СодержитТип(ТипЗнч(Источник.Ссылка)) <> Истина Тогда
Возврат;
КонецЕсли;
РаботаСФайламиСлужебный.ПриЗаписиПрисоединенногоФайлаСервер(Источник.ВладелецФайла, Источник);
КонецПроцедуры
Для корректной работы механизмов необходимо учитывать следующие рекомендации:
1. Определение типов в расширении
Создайте общий модуль, например СОГ_ДопФункцииПовторИсп, который будет возвращать ОписаниеТипов для ваших объектов. Это необходимо для того, чтобы типовые модули могли отличить «свои» объекты от «чужих».
Функция ПолучитьОписаниеТипов_ОпределяемыеТипы_ПрисоединенныйФайл() Экспорт
МассивТипов = Новый Массив;
ИмяРасширения = "АдаптацияКонфигурации";
Для Каждого Мета Из Метаданные.Справочники Цикл
ИспользРасш = Мета.РасширениеКонфигурации();
Если ИспользРасш <> Неопределено И ИспользРасш.Имя = ИмяРасширения Тогда
Если Прав(Мета.Имя, 19) = "ПрисоединенныеФайлы" Тогда
МассивТипов.Добавить(Тип("СправочникСсылка." + Мета.Имя));
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Новый ОписаниеТипов(МассивТипов);
КонецФункции
2. Перехват процедур (Аннотация &Вместо)
Используйте аннотацию &Вместо для перехвата типовых функций работы с файлами, таких как ХранилищеФайлаИзИнформационнойБазы. Внутри перехватчика проверяйте тип ссылки: если это ваш объект — выполняйте свою логику запроса к регистру, если нет — используйте ПродолжитьВызов().
3. Использование привилегированного режима
Всегда оборачивайте операции записи и чтения в УстановитьПривилегированныйРежим(Истина). Файловые механизмы часто работают с системными таблицами или регистрами, к которым у обычного пользователя, работающего в интерфейсе, может не быть прав доступа.
4. Очистка и удаление
Не забывайте про подписки на события ПередУдалением. Если вы не удалите запись из вашего регистра сведений при удалении карточки файла, база данных будет накапливать «мусорные» данные, что приведет к её необоснованному росту.
5. Оптимизация
При использовании ХранилищеЗначения для записи файла в регистр обязательно применяйте сжатие: Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9)). Это позволит сэкономить значительный объем дискового пространства в информационной базе.
Реализация собственного механизма хранения — задача кропотливая, требующая внимательной настройки подписок на события. Однако, придерживаясь описанной структуры модулей и проверок типов, вы сможете добиться полной функциональности стандартной подсистемы в рамках вашего расширения.