К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно добавить кнопку на форму в 1С

Как программно добавить кнопку на форму в 1С: работа с коллекцией Элементы, команды формы, примеры кода для управляемых форм, типичные ошибки и FAQ.

Программное добавление кнопки на форму в 1С требуется, когда состав интерфейса заранее неизвестен: кнопки зависят от прав пользователя, настроек, данных объекта или расширений. В управляемых формах это делается через коллекцию Элементы формы и механизм команд формы, без изменения конфигурации в конфигураторе.

Задача решается в три этапа: создать команду формы, привязать к ней действие (обработчик) и добавить элемент типа «КнопкаФормы» в нужную группу. Все действия выполняются в модуле формы, обычно в обработчике ПриСозданииНаСервере() или в серверной процедуре, вызываемой при изменении условий отображения.

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

Как устроена работа с элементами формы

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

Ключевое ограничение: обработчик нажатия программной кнопки должен существовать в модуле формы заранее. Нельзя «на лету» создать процедуру — можно только указать имя уже существующей процедуры в свойстве Действие команды. Поэтому типовой подход — один универсальный обработчик, который по имени команды определяет нужную логику.

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

Сначала добавьте команду в коллекцию команд формы. Укажите уникальное имя, заголовок (он станет текстом кнопки) и имя обработчика:

НоваяКоманда = ЭтаФорма.Команды.Добавить("КомандаПечатьСчета");

НоваяКоманда.Заголовок = "Печать счета";

НоваяКоманда.Действие = "Подключаемый_ВыполнитьКоманду";

НоваяКоманда.Подсказка = "Сформировать печатную форму счета";

НоваяКоманда.Картинка = БиблиотекаКартинок.Печать;

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

Свойство Действие принимает строку — имя процедуры модуля формы. Процедура должна быть объявлена с директивой &НаКлиенте и принимать один параметр — команду:

&НаКлиенте

Процедура Подключаемый_ВыполнитьКоманду(Команда)

Если Команда.Имя = "КомандаПечатьСчета" Тогда

ПечатьСчетаНаСервере();

КонецЕсли;

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

Шаг 2. Добавление кнопки в элементы формы

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

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

НоваяКнопка.ИмяКоманды = "КомандаПечатьСчета";

НоваяКнопка.Заголовок = "Печать счета";

Родитель обязателен и должен быть группой формы (например, командная панель, группа кнопок или обычная группа). Если передать Неопределено или элемент, не являющийся группой, платформа выдаст ошибку. Чтобы попасть в стандартную командную панель формы, используйте ЭтаФорма.Элементы.КоманднаяПанель или ЭтаФорма.КоманднаяПанель.

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

Порядок действий
  1. 1
    Создайте команду: ЭтаФорма.Команды.Добавить(Имя) и задайте Заголовок и Действие
  2. 2
    Объявите в модуле формы клиентскую процедуру-обработчик с параметром Команда
  3. 3
    Добавьте кнопку: ЭтаФорма.Элементы.Добавить(Имя, Тип("КнопкаФормы"), Родитель)
  4. 4
    Присвойте кнопке свойство ИмяКоманды, равное имени созданной команды
  5. 5
    Откройте форму и проверьте, что кнопка видна и обработчик срабатывает

Шаг 3. Полный пример в ПриСозданииНаСервере

Соберём фрагменты в рабочий код. Типовое место вызова — обработчик ПриСозданииНаСервере, когда реквизиты и элементы формы уже доступны:

&НаСервере

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

Если ЭтаФорма.Команды.Найти("КомандаОбновитьОстатки") = Неопределено Тогда

Команда = ЭтаФорма.Команды.Добавить("КомандаОбновитьОстатки");

Команда.Заголовок = "Обновить остатки";

Команда.Действие = "Подключаемый_ВыполнитьКоманду";

КонецЕсли;

Если ЭтаФорма.Элементы.Найти("КнопкаОбновитьОстатки") = Неопределено Тогда

Кнопка = ЭтаФорма.Элементы.Добавить("КнопкаОбновитьОстатки",

Тип("КнопкаФормы"), ЭтаФорма.КоманднаяПанель);

Кнопка.ИмяКоманды = "КомандаОбновитьОстатки";

КонецЕсли;

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

Обратите внимание на двойную проверку через Найти(): форма может пересоздаваться (например, при изменении ключевых реквизитов), и повторное добавление команды или элемента без проверки приведёт к ошибке исполнения.

Кнопка в табличной части

Если кнопка нужна в командной панели динамического списка или табличной части, родителем указывают командную панель соответствующей таблицы: ЭтаФорма.Элементы.Товары.КоманднаяПанель. Логика создания команды не меняется — меняется только родительский элемент.

Настройка внешнего вида кнопки

После добавления элементу доступны стандартные свойства кнопки формы. Наиболее используемые:

  • Заголовок — текст на кнопке;
  • Картинка — значок (задаётся в команде через НоваяКоманда.Картинка);
  • Отображение — режим показа: автоматически, только текст, только картинка;
  • Важность — выделяет кнопку как основное действие;
  • Доступность и Видимость — управление состоянием без удаления элемента;
  • КнопкаПоУмолчанию — срабатывание по Enter (только для кнопок в отдельных группах).

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

Динамические кнопки по данным

Частый сценарий — набор кнопок, зависящий от данных: например, по кнопке на каждый вид операции из справочника. В этом случае имена команд и элементов формируются в цикле, а обработчик остаётся общим:

Для Каждого Строка Из СписокОпераций Цикл

ИмяКнопки = "Кнопка_" + Строка.Код;

Команда = ЭтаФорма.Команды.Добавить("Команда_" + Строка.Код);

Команда.Заголовок = Строка.Наименование;

Команда.Действие = "Подключаемый_ВыполнитьКоманду";

Кнопка = ЭтаФорма.Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), ЭтаФорма.Элементы.ГруппаОперации);

Кнопка.ИмяКоманды = "Команда_" + Строка.Код;

КонецЦикла;

В обработчике имя команды разбирается, и из него извлекается идентификатор операции. Следите, чтобы коды из данных не содержали символов, недопустимых в именах (пробелы, дефисы, кириллица технически допустима, но усложняет поддержку). Безопаснее использовать GUID или числовой код.

Если кнопок по данным больше 5–7, интерфейс становится перегруженным. В этом случае лучше добавить одну кнопку, открывающую форму выбора, или использовать подменю — группу с видом «Подменю», в которую складываются динамические кнопки.
ПЗ
Практическое замечание

Ограничения и типичные ошибки

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

Вторая частая проблема — обработчик не вызывается, хотя кнопка видна. Причины: имя в свойстве Действие не совпадает с именем процедуры, процедура объявлена без директивы &НаКлиенте, либо у процедуры нет параметра Команда. Платформа в этом случае выдаёт сообщение о невозможности применить действие.

Третья группа ошибок — попытка добавить кнопку в форму, созданную не вами (например, в типовую форму через расширение). В расширениях программное добавление работает так же, но родительские группы должны существовать в расширяемой форме; если типовой код удалит группу при обновлении, ваш код упадёт. Добавляйте проверку Элементы.Найти(ИмяРодителя).

Типичные ошибки
01
Добавление команды без проверки Найти() — при пересоздании формы возникает исключение «Элемент с таким именем уже существует»
02
Указание в Действие несуществующей процедуры — кнопка отображается, но нажатие вызывает ошибку выполнения
03
Добавление кнопки без родителя-группы — ошибка «Недопустимый родитель»
04
Формирование имени кнопки из произвольных данных с пробелами и спецсимволами — ошибка именования элемента
05
Попытка добавить элемент из клиентского контекста без серверного вызова — ошибка доступности метода

Проверка результата

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

Для отладки временно выведите в обработчик Сообщить(Команда.Имя) — так вы убедитесь, что событие доходит до нужной процедуры, и увидите фактическое имя команды.

Контрольные точки

Как проверить результат

Видимость кнопки
Норма

Кнопка есть в нужной группе при каждом открытии формы

Тревожный признак

Кнопка пропадает после перезаписи или появляется дважды

Срабатывание обработчика
Норма

Нажатие вызывает нужную процедуру, имя команды передаётся верно

Тревожный признак

Ошибка «Не найден метод» или тишина при нажатии

Повторное открытие
Норма

Форма открывается без исключений много раз подряд

Тревожный признак

Ошибка «элемент уже существует» при втором открытии

Итог

Что важно запомнить

Программная кнопка = команда формы + элемент «КнопкаФормы» + заранее объявленный обработчик. Добавляйте на сервере, проверяйте уникальность имён через Найти() и используйте один общий обработчик для динамических наборов кнопок.

Частые вопросы

Можно ли добавить кнопку в обычную (неуправляемую) форму?

Да, но механизм другой: в обычных формах используется коллекция ЭлементыФормы с методом Добавить(Тип("Кнопка")), а обработчик назначается через УстановитьДействие("Нажатие", Процедура). Код из этой статьи предназначен для управляемых форм.

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

Вызовите ЭтаФорма.Элементы.Удалить(ЭтаФорма.Элементы.ИмяКнопки) на сервере. Команду при необходимости удаляют через ЭтаФорма.Команды.Удалить(). Чаще вместо удаления меняют свойство Видимость — это безопаснее, если на элемент есть ссылки в другом коде.

Почему кнопка есть, а нажатие ничего не делает?

Проверьте три вещи: имя процедуры в свойстве Действие команды совпадает с реальным именем, процедура объявлена с директивой &НаКлиенте и принимает параметр Команда. Также убедитесь, что у кнопки заполнено свойство ИмяКоманды.

Можно ли добавить кнопку в типовую форму без изменения конфигурации?

Да, через расширение конфигурации: заимствуйте форму, добавьте в её модуль код создания команды и кнопки. При обновлении типовой конфигурации проверяйте, что родительская группа, в которую вы добавляете кнопку, не была переименована или удалена поставщиком.

Как сделать кнопку в командной панели динамического списка?

Команда создаётся так же, а родителем кнопки указывают командную панель таблицы: ЭтаФорма.Элементы.Список.КоманднаяПанель. Если нужно поведение «кнопка в каждой строке», для динамических списков это невозможно напрямую — используют оформление строк или отдельную форму обработки.

Можно ли задать обработчик из общего модуля, а не из модуля формы?

Напрямую нет: свойство Действие команды формы ссылается только на процедуру модуля этой формы. Решение — в обработчике формы вызвать экспортную процедуру общего модуля, передав нужные параметры. Это стандартная практика для вынесения бизнес-логики из формы.