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

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

При разработке сложных интерфейсов или создании универсальных обработок часто возникает необходимость изменять состав элементов формы «на лету», в зависимости от прав пользователя, настроек программы или данных самого объекта. Рассмотрим подробно, как программно добавить команду и кнопку на управляемую форму, связать их между собой и назначить обработчик действия.

Постановка задачи и анализ механизмов платформы

Для того чтобы на форме появилась кнопка, которая что-то делает, нам необходимо выполнить три обязательных действия в процедуре ПриСозданииНаСервере:

  1. Создать саму Команду формы (объект, который несет в себе логику).
  2. Создать Элемент формы (визуальную кнопку), который будет отображать эту команду.
  3. Связать визуальный элемент с командой и назначить команде обработчик.

Разберем этот процесс по шагам, опираясь на практику разработки и рекомендации сообщества.

Шаг 1: Создание команды формы

Команды формы хранятся в коллекции Команды. Первым делом мы должны добавить новую команду в эту коллекцию. Метод Добавить возвращает объект типа КомандаФормы, свойства которого нам нужно заполнить.

Проанализируем код создания команды. Нам потребуется задать ей уникальное имя, заголовок и, самое главное, имя процедуры-обработчика.


// Добавляем команду в коллекцию команд формы
НоваяКоманда = ЭтаФорма.Команды.Добавить("ИмяМоейКоманды");
НоваяКоманда.Заголовок = "Выполнить действие";
НоваяКоманда.Действие  = "НажатиеНаКнопку"; // Имя процедуры-обработчика

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

Шаг 2: Создание визуального элемента (Кнопки)

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

Используем метод Элементы.Добавить(). Рассмотрим параметры этого метода:

Посмотрим на пример кода добавления кнопки:


// Добавляем элемент формы типа "Кнопка"
НовыйЭлемент = Элементы.Добавить("ИмяКнопкиНаФорме", Тип("КнопкаФормы"), ЭтаФорма);
НовыйЭлемент.Вид = ВидКнопкиФормы.ОбычнаяКнопка; 
НовыйЭлемент.ИмяКоманды = "ИмяМоейКоманды"; // Связываем с созданной ранее командой

Важный момент: свойство ИмяКоманды у элемента должно в точности совпадать с именем команды, которую мы создали на первом шаге. Именно это свойство связывает визуальное представление (кнопку) и логику (команду).

Шаг 3: Описание обработчика команды

Как мы указывали ранее в свойстве Действие, платформа будет искать процедуру с именем НажатиеНаКнопку. Если этой процедуры не будет в модуле формы, при открытии формы возникнет ошибка.

Давайте напишем код обработчика. Он должен выполняться на клиенте.


&НаКлиенте
Процедура НажатиеНаКнопку(Команда)
    // Здесь описываем логику, которая выполнится при нажатии
    ПоказатьОповещениеПользователя("Успех!", , "Кнопка была нажата программно!");
КонецПроцедуры

Расширенные возможности: Добавление реквизитов

Часто вместе с кнопками требуется программно добавить и поля ввода (реквизиты). Если мы просто добавим элемент типа ПолеФормы, он не будет работать, так как ему нужен "ПутьКДанным". Но данных (реквизита) на форме еще нет.

Для решения этой задачи используется метод ИзменитьРеквизиты. Он позволяет массово добавлять и удалять реквизиты формы.

Разберем алгоритм добавления строкового реквизита и поля для него:


// 1. Описываем массив добавляемых реквизитов
ДобавляемыеРеквизиты = Новый Массив;
ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("НовыйРеквизит", Новый ОписаниеТипов("Строка"), "", "Заголовок реквизита"));

// 2. Вызываем метод изменения структуры данных формы
ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);

// 3. Создаем элемент формы, связанный с этим реквизитом
НовоеПоле = Элементы.Добавить("ПолеНовыйРеквизит", Тип("ПолеФормы"), ЭтаФорма);
НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
НовоеПоле.ПутьКДанным = "НовыйРеквизит";

Метод ИзменитьРеквизиты является ресурсоемким, так как перестраивает контекст формы. Поэтому, если нужно добавить много реквизитов, следует накапливать их в массиве и вызывать метод один раз для всего массива, а не для каждого реквизита отдельно.

Группировка элементов

Если мы хотим, чтобы наши программно созданные кнопки располагались аккуратно (например, в одну линию), нам следует использовать группы форм.

Создадим программно группу и поместим туда кнопку:


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

// Добавляем кнопку ВНУТРЬ этой группы (третий параметр)
КнопкаВГруппе = Элементы.Добавить("Кнопка1", Тип("КнопкаФормы"), НоваяГруппа);
КнопкаВГруппе.ИмяКоманды = "ИмяМоейКоманды";

Полный пример кода для модуля формы

Соберем всё воедино. Рассмотрим готовый блок кода, который можно вставить в процедуру ПриСозданииНаСервере для тестирования.


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

&НаКлиенте
Процедура ВыполнитьПриветствие(Команда)
    Сообщить("Привет! Кнопка создана программно.");
КонецПроцедуры

Типичные ошибки и нюансы

При программной работе с формой следует помнить о нескольких важных моментах:

  1. Уникальность имен. Имена элементов (первый параметр метода Добавить) должны быть уникальны в пределах формы. Если вы попытаетесь создать элемент с именем, которое уже существует, платформа выдаст исключение. Рекомендуется добавлять префиксы или проверять наличие элемента через Элементы.Найти().
  2. Контекст вызова. Все изменения структуры формы (добавление команд, элементов, реквизитов) возможны только на сервере. Вы не сможете добавить кнопку из клиентской процедуры.
  3. Жизненный цикл. Элементы, созданные программно, существуют пока открыта форма. При следующем открытии код ПриСозданииНаСервере выполнится заново, и элементы создадутся снова.
  4. Передача контекста. Если вы добавляете реквизиты через ИзменитьРеквизиты, помните, что это сбрасывает значения переменных модуля формы, не являющихся реквизитами, так как происходит переинициализация формы.

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

← На главную