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

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

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

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

Архитектура элементов интерфейса и команд в управляемых формах

Проанализируем базовый принцип: в управляемых формах 1С визуальный элемент КнопкаФормы сам по себе не содержит логики выполнения. Кнопка лишь связывается с объектом КомандаФормы через свойство ИмяКоманды. Логика исполнения задается именно в команде через свойство Действие, в котором строкой указывается имя клиентской процедуры-обработчика.

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

Решение: Использование единого обработчика с параметром Команда

Разберем по шагам, как решить задачу динамического создания кнопок. Вместо попыток создать отдельную процедуру для каждой кнопки мы связываем все создаваемые команды с одной универсальной процедурой-обработчиком. Процедура действия команды на клиенте всегда принимает входящий параметр — саму исполняемую команду.

Посмотрим на пример серверного кода, где в цикле создаются команды и привязанные к ним кнопки на форме:


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

Теперь рассмотрим клиентскую процедуру. Обратите внимание на то, что у процедуры объявлен параметр Команда:


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

Способы передачи данных и параметров в единый обработчик

Так как объект КомандаФормы не имеет встроенного свойства для хранения произвольных структур данных, рассмотрим основные способы передачи контекста в обработчик:

  1. Кодирование идентификатора в имени команды:

    Параметры действия (например, тип операции и числовой идентификатор) можно включить в само имя команды при её создании, разделяя их специальным символом: Команда_Выгрузить_105. В клиентском обработчике имя разбирается с помощью функции СтрРазделить().

  2. Хранение параметров в реквизите формы:

    На сервере создается реквизит формы с типом Соответствие. Ключом выступает имя команды, а значением — структура с любым набором параметров. В обработчике на клиенте параметры считываются по ключу Команда.Имя.

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

Рассмотрим моменты, о которых важно помнить при динамической генерации элементов:

  1. Удаление старых элементов: Если генерация кнопок происходит повторно (например, при смене режима работы формы или при выборе других параметров), перед добавлением новых кнопок необходимо программно удалить ранее созданные с помощью Элементы.Удалить(...) и Команды.Удалить(...) во избежание ошибки дублирования имен.
  2. Производительность: Генерация большого количества визуальных элементов (сотен кнопок) увеличивает объем данных формы, передаваемых между клиентом и сервером. Если вариантов выбора слишком много, рекомендуется использовать альтернативные решения: таблицу формы с оформлением строк в виде гиперссылок, выпадающие подменю (ВидГруппыФормы.Подменю) или меню кнопки (ВидКнопкиФормы.КнопкаМеню).
← На главную