При динамическом формировании интерфейса управляемой формы разработчики иногда сталкиваются с критической ошибкой: серверный код успешно отрабатывает, но в момент выхода из процедуры или передачи управления на клиент платформа 1С:Предприятие аварийно завершает работу с сообщением «Запись дампа» (crash dump). Разберем причины такого сбоя, выясним особенности построения дерева элементов и рассмотрим правильный способ создания страниц.
Проанализируем структуру элементов управляемой формы. В платформе 1С действует строгое правило иерархии для панелей вкладок:
ГруппаФормы с видом ВидГруппыФормы.Страница не может существовать самостоятельно в корне формы или внутри группы вида ВидГруппыФормы.ОбычнаяГруппа.ВидГруппыФормы.Страница обязательно должен выступать контейнер ГруппаФормы с видом ВидГруппыФормы.Страницы (панель страниц).Когда в коде методом Элементы.Добавить() создается страница, а в качестве родителя передается обычная группа, синтаксической ошибки на сервере не возникает. Однако при завершении серверного вызова и попытке сериализовать некорректно сформированное дерево элементов в разметку для клиентского интерфейса графический движок сталкивается с нарушением топологии контролов. Это приводит к необработанному системному исключению в нативном коде платформы и падению процесса с записью дампа памяти.
Примечательно, что если страница остается абсолютно пустой, платформа может проигнорировать её рендеринг, но как только внутрь ошибочно размещенной страницы добавляется любой визуальный контрол (декорация, поле ввода, кнопка), аварийное завершение становится неизбежным.
Посмотрим на пример кода, вызывающий падение платформы:
// ОШИБКА: Элементы.Группа1 имеет вид "ОбычнаяГруппа"
Страница = Элементы.Добавить("СтраницаГруппыАвтомобили" + Имя, Тип("ГруппаФормы"), Элементы.Группа1);
Страница.Вид = ВидГруппыФормы.Страница;
Страница.Заголовок = Строка.Наименование;
ДекорацияИмя = "ДекорацияГруппыАвтомобили" + Имя;
Надпись = Элементы.Добавить(ДекорацияИмя, Тип("ДекорацияФормы"), Страница);
Надпись.Заголовок = "Тест";
Разберем по шагам, как исправить эту логику и правильно выстроить дерево элементов управления:
Вид у него было установлено в значение Страницы.ВидГруппыФормы.Страницы.Элементы.Добавить() именно созданную панель страниц.Посмотрим на корректный шаблон создания панели со страницами и элементами:
// 1. Создание родительской панели страниц
ПанельСтраниц = Элементы.Добавить("ПанельАвтомобили", Тип("ГруппаФормы"), ЭтаФорма);
ПанельСтраниц.Вид = ВидГруппыФормы.Страницы;
// 2. Добавление страниц в цикле
ИмяИндекс = 1;
Для Каждого Строка Из РезультатЗапросаТаблица Цикл
// Создаем отдельную страницу внутри панели
ИмяСтраницы = "СтраницаАвтомобили" + Формат(ИмяИндекс, "ЧГ=0");
НоваяСтраница = Элементы.Добавить(ИмяСтраницы, Тип("ГруппаФормы"), ПанельСтраниц);
НоваяСтраница.Вид = ВидГруппыФормы.Страница;
НоваяСтраница.Заголовок = Строка.Наименование;
// Создаем декорацию внутри страницы
ИмяДекорации = "ДекорацияАвтомобили" + Формат(ИмяИндекс, "ЧГ=0");
Надпись = Элементы.Добавить(ИмяДекорации, Тип("ДекорацияФормы"), НоваяСтраница);
Надпись.Вид = ВидДекорацииФормы.Надпись;
Надпись.Заголовок = "Информация об автомобиле: " + Строка.Наименование;
Надпись.РастягиватьПоГоризонтали = Истина;
Надпись.РастягиватьПоВертикали = Истина;
ИмяИндекс = ИмяИндекс + 1;
КонецЦикла;
Рассмотрим важные ограничения платформы 1С при работе с динамическими элементами:
Элементы.Добавить(), Элементы.Удалить(), а также реквизитов через ИзменитьРеквизиты() необходимо выполнять строго в процедуре ПриСозданииНаСервере. Вызов этих методов в других серверных обработчиках после передачи формы клиенту вызовет ошибку времени выполнения."ЧГ=0" функции Формат()), чтобы избежать случайного появления неразрывных пробелов в идентификаторах элементов.НовыйРеквизитФормы и ИзменитьРеквизиты(), и только затем создаются сами элементы формы с заполнением свойства ПутьКДанным.