Как быстро заполнить реквизиты управляемой формы из переданных параметров

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

При открытии подчиненных или общих форм часто возникает задача передать в них большое количество исходных значений. Если форма не привязана к конкретному прикладному объекту базы данных, а содержит лишь набор собственных реквизитов, разработчик сталкивается с рутинным написанием кода вида Реквизит1 = Параметры.Реквизит1. Попытка использовать привычный метод ЗаполнитьЗначенияСвойств() в контексте управляемой формы часто приводит к ошибке или не дает результата. Рассмотрим причины такого поведения платформы и разберем эффективные способы быстрого заполнения данных формы.

Почему не работает ЗаполнитьЗначенияСвойств для управляемой формы

Выясним причину, по которой стандартная процедура ЗаполнитьЗначенияСвойств() не может заполнить форму напрямую:

  1. Метод ЗаполнитьЗначенияСвойств(Приемник, Источник) рассчитан на работу с объектами, обладающими динамически определяемыми свойствами (структуры, строки таблиц и деревьев значений) либо с прикладными объектами данных (ДанныеФормыСтруктура, справочники, документы).
  2. Объект УправляемаяФорма не предоставляет свои пользовательские реквизиты в виде открытых свойств COM/CLR-объекта формы. Для метода доступны только системные свойства самой формы (например, Заголовок или ТолькоПросмотр). Попытка передать форму как приемник вызывает ошибку несоответствия типов.
  3. В обычном приложении (толстый клиент) обращение к свойствам формы могло отрабатывать иначе, однако в тонком клиенте и на сервере управляемых форм такой подход не применим.

Способ 1. Обход реквизитов формы через ПолучитьРеквизиты

Рассмотрим наиболее безопасный и системный способ. На сервере в контексте управляемой формы доступен метод ПолучитьРеквизиты(), который возвращает массив описаний всех реквизитов текущей формы (объекты РеквизитФормы). Мы можем перебрать эти описания и проверить, передан ли одноименный параметр в структуру Параметры.

Разберем пример реализации в обработчике ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    МассивРеквизитов = ПолучитьРеквизиты();
    Для Каждого ОписаниеРеквизита Из МассивРеквизитов Цикл
        Если Параметры.Свойство(ОписаниеРеквизита.Имя) Тогда
            ЭтаФорма[ОписаниеРеквизита.Имя] = Параметры[ОписаниеРеквизита.Имя];
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Этот способ удобен тем, что мы избегаем ошибок при наличии в коллекции Параметры системных параметров платформы (таких как Ключ, АвтоТест, РежимОткрытияОкна), для которых нет соответствующих реквизитов на форме.

Способ 2. Обход коллекции параметров с обработкой исключений

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

Посмотрим на пример кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Для Каждого КлючИЗначение Из Параметры Цикл
        Попытка
            ЭтаФорма[КлючИЗначение.Ключ] = КлючИЗначение.Значение;
        Исключение
            // Пропускаем служебные параметры платформы, для которых нет реквизитов
        КонецПопытки;
    КонецЦикла;
    
КонецПроцедуры

Способ 3. Передача единой структуры данных

Проанализируем еще один архитектурно правильный подход. Вместо передачи десятков разрозненных параметров при вызове формы можно упаковать все данные в единую структуру, например с ключом ДанныеЗаполнения.

Если на самой форме создать реквизит типа Структура (или реквизит составного типа, отображаемый как ДанныеФормыСтруктура), к нему уже можно без ограничений применять метод ЗаполнитьЗначенияСвойств():


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

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

При реализации группового заполнения реквизитов формы необходимо учитывать следующие правила платформы 1С:

  1. Типы данных реквизитов: прямое присваивание через ЭтаФорма[Имя] = Значение отлично работает для примитивных (числа, строки, даты, булево) и ссылочных типов.
  2. Коллекции и таблицы: если среди реквизитов формы есть таблицы (типы ДанныеФормыКоллекция или ДанныеФормыДерево), прямое присваивание таблицы значений вызовет ошибку. Для таких данных следует применять метод ЗначениеВРеквизитФормы(ТаблицаИсточник, "ИмяРеквизита").
  3. Свойство реквизита «Заполнять из данных заполнения»: для стандартных реквизитов объектов платформы можно включать данный флаг в свойствах метаданных, что позволяет платформе автоматически считывать значения из переданных параметров типа ЗначениеЗаполнения.
← На главную