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

Программист Сфера услуг, туризм и социальный сектор
← На главную

В разработке на платформе 1С:Предприятие 8.3 часто возникает задача динамического изменения интерфейса. Например, когда заранее неизвестно количество элементов, которые должны отобразиться на форме (список групп ученика, перечень активных договоров или доступные подразделения). В этой статье мы подробно разберем, как программно создавать элементы типа Поле надписи, делать их гиперссылками и организовывать переход к формам соответствующих объектов.

Анализ исходной задачи и типичных ошибок

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

Разберем по шагам, как реализовать эту задачу правильно, учитывая производительность, модель объекта и стандарты разработки 1С.

Этап 1. Подготовка данных и оптимизация запроса

Прежде чем создавать визуальные элементы, нам нужно получить данные. Важно помнить о производительности: обращение через точку к полям ссылочных типов внутри цикла (например, Выборка.Группа.Наименование) порождает дополнительные неявные запросы к базе данных. Проанализируем, как составить запрос оптимально.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	УченикиВГруппах.Группа КАК Группа,
        |	УченикиВГруппах.Группа.Наименование КАК ГруппаНаименование
        |ИЗ
        |	РегистрСведений.УченикиВГруппах КАК УченикиВГруппах
        |ГДЕ
        |	УченикиВГруппах.СтатусУченика = &СтатусУченика
        |	И УченикиВГруппах.Ученик = &Ученик";
    
    Запрос.УстановитьПараметр("СтатусУченика", Перечисления.СтатусУченикаВГруппе.Учится);
    Запрос.УстановитьПараметр("Ученик", Объект.Ссылка);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Номер = 1;
    Пока Выборка.Следующий() Цикл
        СоздатьДинамическийЭлемент(Выборка.Группа, Выборка.ГруппаНаименование, Номер);
        Номер = Номер + 1;
    КонецЦикла;
    
КонецПроцедуры

Обратите внимание, что мы сразу получаем ГруппаНаименование в запросе. Это исключает лишнюю нагрузку на сервер при итерации выборки.

Этап 2. Программное создание элементов формы

Для создания элемента используется метод ЭтаФорма.Элементы.Добавить(). Однако просто добавить элемент мало — нужно определить, как он будет реагировать на действия пользователя. Рассмотрим процесс создания поля надписи, которое ведет себя как гиперссылка.

При программном создании элементов мы столкнемся с тем, что нам нужно где-то хранить ссылку на саму группу, чтобы открыть её позже. Одним из решений является создание динамических реквизитов формы, но для простых задач можно использовать именование элементов или сохранение связей в структуру.


&НаСервере
Процедура СоздатьДинамическийЭлемент(СсылкаНаГруппу, ИмяГруппы, ПорядковыйНомер)
    
    ИмяЭлемента = "Надпись_Группа_" + СтрЗаменить(Строка(СсылкаНаГруппу.УникальныйИдентификатор()), "-", "_");
    
    // Добавляем элемент на форму в определенную группу (контейнер)
    НоваяНадпись = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), Элементы.ГруппаКонтейнер);
    НоваяНадпись.Вид = ВидПоляФормы.ПолеНадписи;
    НоваяНадпись.Заголовок = ИмяГруппы;
    НоваяНадпись.Гиперссылка = Истина;
    
    // Устанавливаем действие при нажатии
    НоваяНадпись.УстановитьДействие("Нажатие", "Подключаемый_ПриНажатииНаГруппу");
    
    // Чтобы на клиенте понять, какую ссылку открывать, можно использовать 
    // скрытые реквизиты или соответствие, но самый простой способ — 
    // связать элемент с данными, если вы заранее создали реквизиты.
КонецПроцедуры

Этап 3. Обработка нажатия и открытие формы

Теперь разберем, как реализовать обработчик нажатия на клиенте. Основная сложность здесь — передать ссылку на объект из сервера на клиент. Если мы создавали динамические реквизиты через ИзменитьРеквизиты(), мы можем просто обратиться к ним. Если же нет, мы можем использовать параметры самого элемента или вспомогательную коллекцию.

Рассмотрим универсальный способ открытия формы объекта по ссылке:


&НаКлиенте
Процедура Подключаемый_ПриНажатииНаГруппу(Элемент)
    
    // В реальной задаче ссылку можно получить из соответствия имен элементов и ссылок,
    // подготовленного на сервере при создании элементов.
    // Допустим, мы получили СсылкаНаОбъект.
    
    ПараметрыФормы = Новый Структура("Ключ", СсылкаНаОбъект);
    ОткрытьФорму("Справочник.Группы.ФормаОбъекта", ПараметрыФормы);
    
КонецПроцедуры

Использование параметра Ключ в структуре параметров формы — это стандартный механизм платформы 1С для открытия существующего элемента объекта. Если передать Ключ, система поймет, что нужно открыть не новую форму, а форму конкретной записи базы данных.

Альтернативный и современный метод: Форматированная строка

Создание множества отдельных элементов ПолеФормы может замедлить работу интерфейса, если групп слишком много. Проанализируем более эффективный подход — использование одного реквизита типа ФорматированнаяСтрока. Этот объект позволяет внедрять гиперссылки прямо в текст, причем в качестве значения гиперссылки можно передать саму ссылку на объект.

Выясним преимущества этого метода:

  1. Производительность: создается всего один элемент управления на форме.
  2. Автоматизация: платформа сама обрабатывает нажатие на ссылку типа "СправочникСсылка". Вам даже не придется писать процедуру ОткрытьФорму.
  3. Внешний вид: вы можете гибко настраивать разделители (запятые, точки с запятой) и стили текста, используя условное оформление.

Пример реализации через форматированную строку:


&НаСервере
Процедура ЗаполнитьСписокГруппФорматированнойСтрокой()
    
    МассивЭлементов = Новый Массив;
    
    // Допустим, мы получили данные запросом
    Пока Выборка.Следующий() Цикл
        Если МассивЭлементов.Количество() > 0 Тогда
            МассивЭлементов.Добавить(", "); // Разделитель
        КонецЕсли;
        
        // Создаем гиперссылку, где значением является сама ссылка на группу
        МассивЭлементов.Добавить(Новый ФорматированнаяСтрока(Выборка.ГруппаНаименование, , , , Выборка.Группа));
    КонецЦикла;
    
    // ГруппыТекст - это реквизит формы с типом ФорматированнаяСтрока
    ГруппыТекст = Новый ФорматированнаяСтрока(МассивЭлементов);
    
КонецПроцедуры

Важные рекомендации по очистке формы

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

Обязательно перед циклом создания элементов нужно реализовать процедуру очистки:


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

Посмотрим на этот процесс внимательно: мы сначала собираем элементы в массив, а потом удаляем их. Это необходимо, так как удаление элемента напрямую из коллекции во время обхода этой же коллекции через Для Каждого может привести к ошибкам и пропуску элементов.

Итоги

Мы рассмотрели два основных способа решения задачи. Первый — через программное добавление элементов ПолеФормы — дает максимальную гибкость, позволяя настраивать обработчики событий и передавать сложные параметры. Второй — через ФорматированнаяСтрока — является более легким и предпочтительным для простого отображения списков ссылок. Выбор метода зависит от требований к интерфейсу и сложности логики, которую необходимо выполнить при нажатии на элемент.

← На главную