Программное создание элементов интерфейса — это мощный инструмент, который позволяет делать формы динамическими, подстраивающимися под конкретные данные пользователя. Однако при попытке реализовать создание элементов в цикле разработчики часто сталкиваются с рядом трудностей: от ошибок именования до проблем с привязкой данных. В этой статье мы подробно разберем, как правильно организовать этот процесс, рассмотрим типичные ошибки и изучим работающие примеры кода.
Для начала вспомним базовый синтаксис добавления элемента на форму. Для этого используется метод Элементы.Добавить(). Рассмотрим стандартный пример создания одной декорации (надписи):
// Пример создания одной надписи
НовыйЭлемент = ЭтаФорма.Элементы.Добавить("МояДекорация", Тип("ДекорацияФормы"), ЭтаФорма);
НовыйЭлемент.Вид = ВидДекорацииФормы.Надпись;
НовыйЭлемент.Заголовок = "Заголовок декорации";
Метод Добавить принимает три параметра: уникальное имя элемента, тип создаваемого элемента и родительскую группу (если не указана, элемент добавится в корень формы).
Когда нам нужно создать множество однотипных элементов (например, список показателей или динамическую панель управления), мы используем цикл. Главное правило здесь — имена элементов должны быть уникальными. Если попытаться создать два элемента с одинаковым именем, система выдаст критическую ошибку.
Рассмотрим, как можно сформировать уникальные имена в цикле, используя индекс итерации или данные из какого-либо списка:
// Допустим, у нас есть список имен будущих надписей
МассивИмен = Новый Массив;
МассивИмен.Добавить("Клиент");
МассивИмен.Добавить("Договор");
МассивИмен.Добавить("Сумма");
Для Индекс = 0 По МассивИмен.ВГраница() Цикл
// Формируем уникальное имя элемента
ИмяЭлемента = "Декорация_" + Индекс;
// Создаем элемент
Элемент = ЭтаФорма.Элементы.Добавить(ИмяЭлемента, Тип("ДекорацияФормы"), ЭтаФорма);
Элемент.Вид = ВидДекорацииФормы.Надпись;
Элемент.Заголовок = МассивИмен[Индекс];
КонецЦикла;
В данном примере мы используем счетчик Индекс для создания уникальных имен вида Декорация_0, Декорация_1 и так далее. Это самый надежный способ избежать конфликтов имен.
Проанализируем ситуацию, когда нам нужно добавить не просто надписи, а интерактивные элементы, например, поля ввода. Просто вызвать Элементы.Добавить() в этом случае недостаточно. Если вы попытаетесь создать ПолеФормы и не укажете для него ПутьКДанным, или укажете путь к несуществующему реквизиту, возникнет ошибка «тип поля данных».
Программное создание полноценных элементов управления на управляемых формах всегда состоит из двух этапов:
ИзменитьРеквизиты().Разберем этот процесс по шагам на примере создания нескольких полей ввода в цикле:
// 1. Подготовим массив новых реквизитов
МассивДобавляемыхРеквизитов = Новый Массив;
КоличествоПолей = 5;
Для Индекс = 1 По КоличествоПолей Цикл
ИмяРеквизита = "ДинамическийРеквизит_" + Индекс;
// Создаем описание реквизита: Имя, Тип, Путь, Заголовок, Сохранение
НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("Строка"), , "Поле №" + Индекс);
МассивДобавляемыхРеквизитов.Добавить(НовыйРеквизит);
КонецЦикла;
// 2. Добавляем реквизиты на форму (выполняется только на сервере)
ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// 3. Теперь создаем визуальные элементы в цикле
Для Каждого Реквизит Из МассивДобавляемыхРеквизитов Цикл
ИмяЭлемента = "Поле_" + Реквизит.Имя;
Элемент = ЭтаФорма.Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ЭтаФорма);
Элемент.Вид = ВидПоляФормы.ПолеВвода;
// Важнейший момент: привязываем элемент к созданному реквизиту
Элемент.ПутьКДанным = Реквизит.Имя;
КонецЦикла;
Если мы просто добавим 20 элементов на форму, они выстроятся в длинный вертикальный список, что неудобно для пользователя. Выясним, как управлять их расположением. Для этого используются Группы формы.
Рассмотрим пример создания «плитки» или сетки элементов, где в одной строке будет находиться надпись и поле ввода:
// Создаем горизонтальную группу для каждой строки
Для Индекс = 1 По 3 Цикл
ИмяГруппы = "ГруппаСтрока_" + Индекс;
Группа = ЭтаФорма.Элементы.Добавить(ИмяГруппы, Тип("ГруппаФормы"), ЭтаФорма);
Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
Группа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
Группа.ОтображатьЗаголовок = Ложь;
// Добавляем надпись ВНУТРЬ группы
Надпись = ЭтаФорма.Элементы.Добавить("Надпись_" + Индекс, Тип("ДекорацияФормы"), Группа);
Надпись.Вид = ВидДекорацииФормы.Надпись;
Надпись.Заголовок = "Параметр " + Индекс + ":";
// Добавляем поле (предположим, реквизит уже создан)
Поле = ЭтаФорма.Элементы.Добавить("ПолеВвода_" + Индекс, Тип("ПолеФормы"), Группа);
Поле.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
Зачастую программно созданные кнопки или поля должны реагировать на действия пользователя. Для этого используется метод УстановитьДействие(). Посмотрим на пример назначения одного обработчика для всех созданных кнопок:
Для Индекс = 1 По 5 Цикл
ИмяКнопки = "Кнопка_" + Индекс;
Кнопка = ЭтаФорма.Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), ЭтаФорма);
Кнопка.Заголовок = "Нажать " + Индекс;
Кнопка.ИмяКоманды = "ОбщаяКомандаНажатия"; // Команда должна быть определена в форме
// Либо привязываем напрямую к процедуре
Кнопка.УстановитьДействие("Нажатие", "Подключаемый_ОбработчикНажатия");
КонецЦикла;
Важно: Процедура Подключаемый_ОбработчикНажатия должна существовать в модуле формы, быть объявлена на клиенте (&НаКлиенте) и иметь правильный набор параметров (обычно это Команда или Элемент).
Проанализируем влияние таких операций на скорость работы программы. Каждый вызов ИзменитьРеквизиты() и массовое добавление элементов — это «тяжелая» операция для сервера и клиента. Если элементов слишком много (сотни), форма может начать заметно «тормозить» при открытии.
Посмотрим на альтернативные варианты:
ПриСозданииНаСервере.Элементы.Найти("Имя").Используя предложенные подходы, вы сможете создавать гибкие и динамичные интерфейсы, сохраняя при этом чистоту кода и работоспособность системы.