Почему при программном открытии формы группы справочника в 1С создается обычный элемент?

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

При разработке прикладных решений на платформе 1С:Предприятие часто возникает задача интерактивного создания новой группы справочника с предварительно заполненными реквизитами (например, указанным родителем или владельцем). Разработчики нередко сталкиваются с ситуацией, когда код открывает форму группы, однако при интерактивной записи создается обычный элемент, а реквизит ЭтоГруппа принимает значение Ложь.

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

Анализ проблемы: почему открывается форма группы, а создается элемент

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


Форма = ПолучитьФорму("Справочник.НовыйСправочник.Форма.ФормаГруппы", ПараметрыФормы);
Форма.Объект.Владелец = Свод;
Форма.Объект.Родитель = Глава;
Форма.ОткрытьМодально();

При выполнении этого кода форма действительно открывается, и визуально она может соответствовать форме группы. Однако после нажатия кнопки «Записать и закрыть» в информационной базе появляется элемент, а не группа. Попытка установить значение напрямую на клиенте:

Форма.Объект.ЭтоГруппа = Истина;

приводит к ошибке выполнения: «Поле объекта недоступно для записи (ЭтоГруппа)».

Выясним причину такого поведения системы. В управляемом интерфейсе форма является лишь представлением данных. Если форма создается без указания конкретного объекта (параметр Ключ не передан), платформа по умолчанию инициализирует основной реквизит формы Объект как экземпляр типа СправочникОбъект.<ИмяСправочника> с признаком ЭтоГруппа = Ложь. Имя открываемой формы при этом не определяет тип создаваемого объекта в памяти: для платформы форма группы может отображать и данные обычного элемента. Поскольку свойство ЭтоГруппа доступно только для чтения, изменить его после создания объекта на форме невозможно.

Основное решение: использование стандартного параметра «ЭтоГруппа»

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

Посмотрим на минимальный рабочий пример:


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЭтоГруппа", Истина);

ОткрытьФорму("Справочник.НовыйСправочник.ФормаГруппы", ПараметрыФормы);

Когда платформа получает параметр ЭтоГруппа = Истина, она создает в основном реквизите формы объект с установленным признаком группы. При сохранении такой формы в базу данных будет записана именно группа справочника.

Правильная передача исходных реквизитов: «ЗначенияЗаполнения»

Проанализируем вторую часть исходной задачи — установку реквизитов Родитель и Владелец. В исходном примере значения присваивались напрямую свойствам формы на клиенте (Форма.Объект.Владелец = ...). Такой подход не рекомендуется стандартами разработки 1С по нескольким причинам:

  1. При прямой модификации полей на клиенте не отрабатывает серверное событие объекта ОбработкаЗаполнения, в котором может содержаться прикладная логика инициализации связанных данных и проверка прав.
  2. Порождаются лишние вызовы и рассинхронизация состояния данных между клиентом и сервером.

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

Разберем по шагам правильное формирование параметров и открытие формы:


// 1. Формируем структуру начальных значений реквизитов
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Родитель", Глава);
ПараметрыЗаполнения.Вставить("Владелец", Свод);

// 2. Формируем параметры открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЭтоГруппа", Истина);
ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

// 3. Открываем форму группы
ОткрытьФорму("Справочник.НовыйСправочник.ФормаГруппы", ПараметрыФормы);

При таком подходе платформа создает новую группу, передает структуру в обработчик ОбработкаЗаполнения объекта на сервере, заполняет реквизиты и корректно отображает форму пользователю.

Отказ от устаревших методов «ПолучитьФорму» и «ОткрытьМодально»

В управляемом приложении следует обращать внимание на используемые методы работы с окнами:

  1. Метод ПолучитьФорму() считается устаревшим. Он выполняет синхронный вызов сервера для конструирования формы и нарушает асинхронную модель веб-клиента. Вместо связки ПолучитьФорму() и Открыть() следует всегда использовать метод ОткрытьФорму().
  2. Метод ОткрытьМодально() не поддерживается в конфигурациях с выключенным режимом модальности (параметр конфигурации Режим использования модальности = Не использовать) и вызывает исключение в веб-клиенте.

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


ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Родитель", Глава);
ПараметрыЗаполнения.Вставить("Владелец", Свод);

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЭтоГруппа", Истина);
ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

ОткрытьФорму(
    "Справочник.НовыйСправочник.ФормаГруппы", 
    ПараметрыФормы, 
    ЭтотОбъект, 
    Истина, 
    , 
    , 
    , 
    РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
);

Альтернативный вариант: инициализация группы на сервере

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

  1. Создаем объект группы в серверном контексте вызовом Справочники.<Имя>.СоздатьГруппу().
  2. Заполняем необходимые реквизиты объекта.
  3. Получаем форму через метод ПолучитьФорму() на сервере, преобразуем объект в данные формы методом ЗначениеВДанныеФормы() и возвращаем форму на клиент для открытия.

Однако для большинства стандартных сценариев интерактивного создания группы наиболее простым, чистым и надежным решением остается вызов метода ОткрытьФорму() с параметрами ЭтоГруппа = Истина и структурой ЗначенияЗаполнения.

← На главную