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