Как обновить значение дополнительного реквизита в уже открытой управляемой форме?

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

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

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

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

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

  1. При создании формы на сервере подсистема БСП динамически генерирует на форме отдельные реквизиты с составными служебными именами вида ДополнительныйРеквизитЗначение_... и связывает с ними создаваемые элементы интерфейса (поля ввода).
  2. Значения из табличной части объекта считываются и помещаются в эти динамические реквизиты формы.
  3. Если разработчик программно изменяет строки в табличной части Объект.ДополнительныеРеквизиты, динамические реквизиты формы об этом «не знают» и сохраняют старые значения. При последующей интерактивной записи документа значения из динамических реквизитов формы перезаписывают табличную часть, затирая программные изменения.
  4. Вызовы стандартных методов платформы, таких как ЭтаФорма.Прочитать(), ЭтаФорма.ОбновитьОтображениеДанных() или ОповеститьОбИзменении(), обновляют только типовые реквизиты объекта и не затрагивают программно созданную структуру дополнительных свойств БСП.

Основное решение: переинициализация дополнительных реквизитов через БСП

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

Посмотрим на пример вызова в контексте серверной процедуры формы:


&НаСервере
Процедура ЗаполнитьРеквизитыИзОснованияНаСервере(СсылкаНаОснование)
    
    // Заполняем данные документа и табличную часть дополнительных реквизитов
    // ... логика заполнения табличной части Объект.ДополнительныеРеквизиты ...
    
    // Обновляем динамические реквизиты и элементы формы
    УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(ЭтаФорма, Объект);
    
КонецПроцедуры

Разберем параметры процедуры УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме:

  1. Форма — управляемая форма (ЭтаФорма), на которой размещены элементы дополнительных реквизитов.
  2. Объект — контекст данных формы. Процедура принимает тип ДанныеФормыСтруктура (реквизит формы Объект). Выполнять ресурсоемкое преобразование через РеквизитФормыВЗначение("Объект") необязательно: если передать Объект или Неопределено, процедура сама считает данные напрямую из реквизита формы.

Обработка зависимостей и условий видимости на клиенте

Если в наборе свойств настроены зависимые условия (например, видимость, доступность или обязательность заполнения одного реквизита зависят от значения другого), после серверного обновления необходимо актуализировать состояние интерфейса на клиенте.

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


&НаКлиенте
Процедура ЗаполнитьПоОснованию(Команда)
    
    ЗаполнитьПоОснованиюНаСервере();
    
    // Обновляем видимость и доступность зависимых реквизитов
    УправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтаФорма);
    
    // При необходимости вызываем постобработку интерфейса БСП
    УправлениеСвойствамиКлиент.ПослеЗагрузкиДополнительныхРеквизитов(ЭтаФорма);
    
КонецПроцедуры

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

Альтернативный вариант: точечное изменение реквизита формы

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

Разберем по шагам, как выполнить точечную установку:

  1. Найти имя динамического реквизита в служебной таблице Свойства_ОписаниеДополнительныхРеквизитов на форме по ссылке на свойство (ПланВидовХарактеристик ДополнительныеРеквизитыИСведения).
  2. Установить значение напрямую в реквизит формы: ЭтаФорма[ИмяРеквизита] = НовоеЗначение;.
  3. На клиенте вызвать метод УправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтаФорма); для пересчета связанных полей.

Этот способ работает быстрее при точечных корректировках, так как не требует полного перебора всех свойств объекта на сервере.

Ограничение: отложенная инициализация дополнительных реквизитов

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

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

← На главную