Как работают Дополнительные свойства в 1С и в каких случаях их целесообразно использовать?

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

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

Суть и отличие от БСП

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

Мы же рассматриваем программное свойство ДополнительныеСвойства — это свойство самого объекта метаданных (справочника, документа и т.д.), имеющее тип Структура. Оно предназначено исключительно для разработчика и служит «контейнером» для временного хранения любой информации в теле объекта на время его существования в оперативной памяти.

Жизненный цикл и область видимости

Проанализируем ключевой вопрос: когда «умирают» дополнительные свойства? Ответ прост: они живут ровно столько, сколько живет конкретный экземпляр объекта в оперативной памяти сервера.

Рассмотрим по шагам типичную ситуацию:

  1. Вы создали объект программно: НовыйОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();.
  2. Заполнили НовыйОбъект.ДополнительныеСвойства.Вставить("МойПараметр", Истина);.
  3. Вызвали НовыйОбъект.Записать();.

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

Почему данные пропадают в формах?

Разберем типичную ошибку, с которой сталкиваются программисты при работе с управляемыми формами. Вы пытаетесь установить свойство в обработке заполнения, а затем прочитать его в событии ПриСозданииНаСервере, но там пусто. Выясним причину.

Дело в том, что на форме 1С работает не сам Объект (как ссылочный тип), а специальный тип данных — ДанныеФормыСтруктура. У этого типа нет свойства ДополнительныеСвойства. Когда платформа выполняет преобразование:


// В коде формы
ОбъектЗначение = РеквизитФормыВЗначение("Объект");

Платформа создает новый экземпляр объекта и копирует в него только те данные, которые есть в реквизитах на форме. Поскольку дополнительных свойств на форме нет, они не переносятся. Чтобы передать данные из формы в модуль объекта при записи, используйте обработчик ПередЗаписьюНаСервере:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    ТекущийОбъект.ДополнительныеСвойства.Вставить("ЭтоЗаписьИзФормы", Истина);
КонецПроцедуры

В этом случае в модуле объекта в процедуре ПередЗаписью вы сможете извлечь это значение, так как ТекущийОбъект — это именно тот экземпляр, который отправится на запись.

Практическое применение: Подписки на события

Рассмотрим ситуацию, когда ДополнительныеСвойства незаменимы. Представим, что у вас есть общая подписка на событие ПередЗаписью для всех документов, которая выполняет сложную проверку. Но при загрузке данных из внешней системы эту проверку нужно пропустить.

В коде загрузки мы пишем:


НовыйДокумент = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();
// ... заполнение реквизитов ...
НовыйДокумент.ДополнительныеСвойства.Вставить("ОтключитьПроверкиПриЗагрузке", Истина);
НовыйДокумент.Записать();

А в общем модуле, где находится обработчик подписки на событие, выполняем анализ:


Процедура ПроверкаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    Если Источник.ДополнительныеСвойства.Свойство("ОтключитьПроверкиПриЗагрузке") Тогда
        Возврат; // Пропускаем логику
    КонецЕсли;
    
    // ... основная логика проверки ...
КонецПроцедуры

Оптимизация проведения документов

Посмотрим на пример использования свойств для повышения производительности. Часто в ПередЗаписью нам нужно получить какие-то данные из базы (например, остатки или настройки), которые также понадобятся в ОбработкаПроведения.

Чтобы не делать два запроса к базе данных, мы можем выполнить запрос один раз в ПередЗаписью, сохранить таблицу результатов в ДополнительныеСвойства, а в ОбработкаПроведения просто прочитать её. Это значительно сокращает нагрузку на сервер БД.


// В модуле документа
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если РежимПроведения = РежимПроведенияДокумента.Проведение Тогда
        ТаблицаЦен = ПолучитьЦеныНоменклатуры(Товары.ВыгрузитьКолонку("Номенклатура"));
        ДополнительныеСвойства.Вставить("КэшЦен", ТаблицаЦен);
    КонецЕсли;
КонецПроцедуры

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    ТаблицаЦен = Неопределено;
    Если ДополнительныеСвойства.Свойство("КэшЦен", ТаблицаЦен) Тогда
        // Используем готовую таблицу из памяти
    Иначе
        // Если по какой-то причине кэша нет - получаем заново
        ТаблицаЦен = ПолучитьЦеныНоменклатуры(Товары.ВыгрузитьКолонку("Номенклатура"));
    КонецЕсли;
КонецПроцедуры

Важные ограничения

Проанализируем ситуации, когда использовать этот механизм нельзя или опасно:

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

← На главную