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