При разработке и доработке конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как 1С:Управление нашей фирмой, 1С:ERP, 1С:Комплексная автоматизация или 1С:Управление торговлей, часто возникает задача программного заполнения данных объекта из других документов. Однако при попытке программно изменить дополнительный реквизит в уже открытой форме документа разработчики сталкиваются с тем, что стандартные методы обновления формы не отображают новые данные.
Разберем подробно, почему возникает эта проблема, как устроена подсистема дополнительных реквизитов и сведений и какими методами можно корректно обновить интерфейс открытой формы.
Рассмотрим, как подсистема «Свойства» БСП выводит дополнительные реквизиты на форму. Они не привязаны напрямую к строкам табличной части Объект.ДополнительныеРеквизиты. Вместо этого механизм работает следующим образом:
ДополнительныйРеквизитЗначение_... и связывает с ними создаваемые элементы интерфейса (поля ввода).Объект.ДополнительныеРеквизиты, динамические реквизиты формы об этом «не знают» и сохраняют старые значения. При последующей интерактивной записи документа значения из динамических реквизитов формы перезаписывают табличную часть, затирая программные изменения.ЭтаФорма.Прочитать(), ЭтаФорма.ОбновитьОтображениеДанных() или ОповеститьОбИзменении(), обновляют только типовые реквизиты объекта и не затрагивают программно созданную структуру дополнительных свойств БСП.Для синхронизации данных формы с измененной табличной частью объекта необходимо вызвать специальную экспортную процедуру общего модуля подсистемы управления свойствами на сервере.
Посмотрим на пример вызова в контексте серверной процедуры формы:
&НаСервере
Процедура ЗаполнитьРеквизитыИзОснованияНаСервере(СсылкаНаОснование)
// Заполняем данные документа и табличную часть дополнительных реквизитов
// ... логика заполнения табличной части Объект.ДополнительныеРеквизиты ...
// Обновляем динамические реквизиты и элементы формы
УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(ЭтаФорма, Объект);
КонецПроцедуры
Разберем параметры процедуры УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме:
ЭтаФорма), на которой размещены элементы дополнительных реквизитов.ДанныеФормыСтруктура (реквизит формы Объект). Выполнять ресурсоемкое преобразование через РеквизитФормыВЗначение("Объект") необязательно: если передать Объект или Неопределено, процедура сама считает данные напрямую из реквизита формы.Если в наборе свойств настроены зависимые условия (например, видимость, доступность или обязательность заполнения одного реквизита зависят от значения другого), после серверного обновления необходимо актуализировать состояние интерфейса на клиенте.
Посмотрим на полный цикл обработки на клиенте и сервере:
&НаКлиенте
Процедура ЗаполнитьПоОснованию(Команда)
ЗаполнитьПоОснованиюНаСервере();
// Обновляем видимость и доступность зависимых реквизитов
УправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтаФорма);
// При необходимости вызываем постобработку интерфейса БСП
УправлениеСвойствамиКлиент.ПослеЗагрузкиДополнительныхРеквизитов(ЭтаФорма);
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоОснованиюНаСервере()
// Выполняем установку нужного значения в табличной части
СтрокаРеквизита = Объект.ДополнительныеРеквизиты.Найти(НужноеСвойство, "Свойство");
Если СтрокаРеквизита = Неопределено Тогда
СтрокаРеквизита = Объект.ДополнительныеРеквизиты.Добавить();
СтрокаРеквизита.Свойство = НужноеСвойство;
КонецЕсли;
СтрокаРеквизита.Значение = НовоеЗначениеСвойства;
// Синхронизируем форму с табличной частью
УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(ЭтаФорма, Объект);
КонецПроцедуры
Если требуется изменить всего один дополнительный реквизит без полного серверного перезаполнения всей структуры свойств, можно обратиться напрямую к динамическому реквизиту формы. Имя этого реквизита хранится в служебной коллекции формы.
Разберем по шагам, как выполнить точечную установку:
Свойства_ОписаниеДополнительныхРеквизитов на форме по ссылке на свойство (ПланВидовХарактеристик ДополнительныеРеквизитыИСведения).ЭтаФорма[ИмяРеквизита] = НовоеЗначение;.УправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтаФорма); для пересчета связанных полей.Этот способ работает быстрее при точечных корректировках, так как не требует полного перебора всех свойств объекта на сервере.
Обратим внимание на важную особенность БСП: в некоторых формах включена отложенная инициализация дополнительных реквизитов. В этом случае элементы интерфейса создаются не при открытии документа, а только в момент первого перехода пользователя на соответствующую закладку (например, «Дополнительно» или «Реквизиты»).
Если программно заполнить реквизиты до того, как пользователь открыл страницу со свойствами, динамические элементы на форме могут отсутствовать. В такой ситуации достаточно стандартного заполнения табличной части Объект.ДополнительныеРеквизиты на сервере — при первом переходе на страницу подсистема БСП сама считает актуальные данные из объекта и корректно отобразит их в созданных полях.