Как программно создать кнопки на управляемой форме 1С?

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

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

Архитектурные особенности: Команда и Элемент

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

Процесс программного создания всегда состоит из двух этапов:

  1. Создание объекта КомандаФормы в коллекции ЭтаФорма.Команды (также в типовых решениях часто применяются подключаемые команды БСП).
  2. Создание объекта КнопкаФормы в коллекции ЭтаФорма.Элементы и привязка её к созданной команде.

Шаг 1: Подготовка данных и создание команд на сервере

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

Рассмотрим пример кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Получаем данные из справочника (например, категории товаров)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Категории.Ссылка КАК Ссылка,
        |   Категории.Наименование КАК Наименование,
        |   Категории.Код КАК Код
        |ИЗ
        |   Справочник.Категории КАК Категории";
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();

    Пока Выборка.Следующий() Цикл
        
        // 1. Создаем уникальное имя для команды и кнопки
        ИмяОбъекта = "ДинамическаяКнопка_" + СтрЗаменить(Выборка.Код, " ", "");
        
        // 2. Добавляем команду формы
        НоваяКоманда = ЭтаФорма.Команды.Добавить(ИмяОбъекта);
        НоваяКоманда.Заголовок = Выборка.Наименование;
        НоваяКоманда.Действие  = "ОбработчикНажатияДинамическойКнопки"; // Имя клиентской процедуры
        
        // 3. Добавляем кнопку на форму
        НовыйЭлемент = ЭтаФорма.Элементы.Добавить(ИмяОбъекта, Тип("КнопкаФормы"), ЭтаФорма);
        НовыйЭлемент.ИмяКоманды = ИмяОбъекта;
        
        // Чтобы потом найти ссылку, можно сохранить её в свойстве кнопки (если нужно)
        // Но лучше использовать имя кнопки для идентификации
    КонецЦикла;

КонецПроцедуры

Шаг 2: Группировка кнопок для красивого интерфейса

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


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

Шаг 3: Реализация единого обработчика нажатия

Создавать отдельную процедуру для каждой кнопки нецелесообразно, особенно если их 50. Проанализируем ситуацию: как в одной процедуре понять, какая именно кнопка была нажата? Для этого мы используем свойство ЭтаФорма.ТекущийЭлемент.

Напишем клиентский обработчик, который будет открывать ссылку на элемент справочника, соответствующий нажатой кнопке:


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

&НаСервереБезКонтекста
Функция ПолучитьСсылкуНаСервере(Код)
    Возврат Справочники.Категории.НайтиПоКоду(Код);
КонецФункции

Важные рекомендации и ограничения

При динамическом создании элементов интерфейса следует учитывать несколько критически важных моментов, чтобы форма не стала "неповоротливой" и не вызывала ошибок у пользователей:

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

← На главную