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

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

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

Разбираем, как программно добавить общую команду на форму в 1С: работа с командной панелью, объект КомандыФормы, примеры кода и типичные ошибки разработчиков.

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

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

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

Что такое общая команда и когда её добавляют программно

Общая команда — объект метаданных с собственным модулем, в котором описан обработчик ОбработкаКоманды. Она не привязана к конкретному объекту и может вызываться из любых форм, отчётов и обработок. В конфигураторе её добавляют на форму перетаскиванием из панели команд в дерево элементов.

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

Если состав команд статичен, программное добавление избыточно: проще и надёжнее вывести кнопку штатно в конфигураторе. Код усложняет сопровождение и требует аккуратной работы в обработчике ПриСозданииНаСервере.

Маршрут решения

Как выбрать способ

Кнопка нужна всегда и всем пользователямДобавьте общую команду на форму в конфигураторе перетаскиванием
Состав кнопок зависит от прав, данных или режима работыСоздавайте команду и кнопку программно в ПриСозданииНаСервере
Форма заимствована в расширениеПрограммное добавление без изменения формы предпочтительнее

Базовый механизм: команда формы плюс кнопка

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

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

&НаСервере

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

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

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

Команда.Заголовок = НСтр("ru = 'Отправить по почте'");

Команда.Подсказка = НСтр("ru = 'Отправить документ контрагенту'");

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

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

Кнопка.ИмяКоманды = "ОтправитьПоПочтеДинам";

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

&НаКлиенте

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

ПараметрыКоманды = Новый Массив;

ПараметрыКоманды.Добавить(Объект.Ссылка);

// Вызов логики общей команды

ОткрытьФорму("ОбщаяФорма.ОтправкаПисьма",

Новый Структура("Документы", ПараметрыКоманды), ЭтаФорма);

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

Обратите внимание: имя действия указывается строкой, а процедура-обработчик должна существовать в модуле формы с директивой &НаКлиенте, иначе при нажатии возникнет ошибка «Процедура не обнаружена».

bsl
Команда = Команды.Добавить("МояКоманда");
Команда.Действие = "Подключаемый_МояКоманда";
Кнопка = Элементы.Добавить("КнопкаМоя", Тип("КнопкаФормы"), Элементы.ГруппаКнопок);
Кнопка.ИмяКоманды = "МояКоманда";

Вызов модуля общей команды из обработчика

Модуль общей команды недоступен для прямого вызова как обычный общий модуль — его обработчик ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) вызывается только платформой. Поэтому из своего обработчика кнопки логику общей команды воспроизводят либо выносят общий код в общий модуль, который вызывается и из общей команды, и из формы.

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

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

Размещение кнопки: командная панель, подменю, контекстное меню

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

Для контекстного меню динамического списка или табличной части родителем указывают соответствующий элемент, например Элементы.Список.КонтекстноеМеню. При этом в обработчике имеет смысл проверять, есть ли текущая строка, иначе действие выполнится «в пустоту».

Если нужного родителя на форме нет, его тоже можно создать программно: добавить группу типа ГруппаФормы с видом ВидГруппыФормы.Подменю, а затем добавлять кнопки в неё. Так строят выпадающие меню «Ещё»-подобного типа целиком из кода.

Порядок действий
  1. 1
    Определите, в какую группу формы должна попасть кнопка
  2. 2
    В ПриСозданииНаСервере добавьте команду в коллекцию ЭтаФорма.Команды
  3. 3
    Задайте команде Действие, Заголовок и при необходимости Картинку
  4. 4
    Добавьте элемент КнопкаФормы с родителем — нужной группой
  5. 5
    Присвойте кнопке ИмяКоманды созданной команды
  6. 6
    Создайте клиентский обработчик с указанным именем и проверьте нажатие

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

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

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

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

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

Кнопка отображается на форме
Норма

Кнопка видна в нужной группе с заданным заголовком

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

Кнопки нет — проверьте родителя и видимость группы

Нажатие кнопки
Норма

Выполняется обработчик без сообщений об ошибке

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

Ошибка «процедура не обнаружена» — имя действия не совпадает с процедурой

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

Кнопка создаётся один раз, дублей нет

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

Дубли кнопок — код выполняется повторно без проверки существования

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

Самая частая ошибка — добавление кнопки без создания команды или с опечаткой в ИмяКоманды: кнопка появляется, но неактивна. Вторая по частоте — попытка добавить элементы не в ПриСозданииНаСервере, а в клиентском обработчике, где коллекции команд и элементов недоступны для изменения состава.

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

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

Типичные ошибки
01
Кнопке не назначено ИмяКоманды — кнопка видна, но неактивна
02
Имя в Действие не совпадает с именем процедуры — ошибка при нажатии
03
Добавление выполняется на клиенте — коллекции формы недоступны для изменения
04
Нет проверки на повторное добавление — исключение о дублирующемся имени
05
Обработчик без директивы &НаКлиенте — платформа не находит процедуру

FAQ

Можно ли программно добавить саму общую команду, а не команду формы?

Нет. Платформа не позволяет кодом поместить объект метаданных общей команды на форму. Создаётся команда формы, а её обработчик воспроизводит или делегирует логику общей команды, обычно через общий модуль.

Где именно писать код добавления кнопки?

В обработчике ПриСозданииНаСервере с директивой &НаСервере. Изменение состава команд и элементов формы доступно только на сервере при создании формы.

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

Установите свойство Видимость элемента кнопки в Ложь по нужному условию. Сделать это можно и на клиенте, в отличие от добавления или удаления элементов.

Почему кнопка появилась, но серая и не нажимается?

Чаще всего не заполнено свойство ИмяКоманды или команда с таким именем не найдена в коллекции команд формы. Проверьте точное совпадение имён, включая регистр и опечатки.

Можно ли назначить кнопке картинку из библиотеки?

Да, через свойство Картинка команды формы, например БиблиотекаКартинок.Печать. Картинка задаётся команде, а не кнопке — кнопка унаследует её автоматически.

Работает ли способ в расширении конфигурации?

Да. В расширении заимствуется форма, и в её модуле через &После("ПриСозданииНаСервере") добавляются команды и кнопки. Это предпочтительный способ доработки типовых форм без изменения конфигурации поставщика.

Итог

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

Общая команда добавляется на форму программно через связку «команда формы + кнопка»: команда создаётся в ПриСозданииНаСервере с действием-обработчиком, кнопка связывается с ней через ИмяКоманды. Логику общей команды выносите в общий модуль, проверяйте дубли при повторном создании формы и используйте расширение для типовых конфигураций.