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

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

При разработке механизмов ввода на основании или программного создания документов в типовых конфигурациях (1С:Управление торговлей 11, 1С:ERP, 1С:КА, 1С:УНФ) разработчики часто сталкиваются с ситуацией: строка в табличную часть ДополнительныеРеквизиты добавляется без ошибок, но на управляемой форме поле реквизита остается пустым, а при интерактивной записи добавленное значение стирается.

Разберем причины такого поведения платформы и подсистемы «Свойства» Библиотеки стандартных подсистем (БСП), а также рассмотрим правильные способы программного заполнения дополнительных реквизитов.

Почему обычное добавление строки в табличную часть не работает на форме?

Проанализируем архитектуру работы дополнительных реквизитов в типовых решениях. Механизм БСП построен следующим образом:

  1. Динамические реквизиты формы: Поля дополнительных реквизитов, отображаемые на форме, не привязаны напрямую к строкам табличной части ДополнительныеРеквизиты. При открытии формы подсистема динамически генерирует реквизиты формы с синтетическими именами вида ДополнительныйРеквизитЗначение_... и связывает их с созданными элементами интерфейса.
  2. Перезапись при сохранении: При нажатии кнопки сохранения формы подсистема считывает значения именно из этих динамических реквизитов формы и переносит их в табличную часть ДополнительныеРеквизиты объекта. Если динамический реквизит на форме остался пустым, значение в табличной части будет перезаписано пустым значением.
  3. Изоляция контекста формы: Если мы открываем форму и пытаемся передать ДанныеФормы на сервер в собственную процедуру, мы модифицируем только структуру данных, но не запускаем методы перерисовки и переинициализации динамических элементов формы.

Способ 1. Заполнение в модуле объекта через «ОбработкаЗаполнения» (Рекомендуемый)

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

Посмотрим на пример переопределения логики в обработке заполнения документа-приемника (например, в модуле объекта или через расширение конфигурации):


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

КонецПроцедуры

На клиенте достаточно просто открыть форму нового документа с передачей основания в параметрах:


&НаКлиенте
Процедура ВвестиАктВР(Команда)
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Основание", Объект.Ссылка);
    
    ОткрытьФорму("Документ.АктВыполненныхРабот.Форма.ФормаДокумента", ПараметрыФормы);
    
КонецПроцедуры

Способ 2. Вызов методов подсистемы «УправлениеСвойствами» из контекста формы

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

Для этого в контексте формы вызывается типовой экспортный метод БСП:


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

КонецПроцедуры

Важно: Метод УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме требует передачи контекста текущей управляемой формы (ЭтаФорма), поэтому вызвать его во внешней неконтекстной процедуре, оперирующей только структурой ДанныеФормы, нельзя.

Способ 3. Создание и запись документа на сервере без интерактивной формы

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


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

КонецФункции

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

← На главную