Разработка и Конфигурация · 10 мин
Как программно добавить общую команду на форму в 1С
Разбираем, как программно добавить общую команду на форму в 1С: работа с командной панелью, объект КомандыФормы, примеры кода и типичные ошибки разработчиков.
Общие команды в 1С позволяют вынести обработчик действия в отдельный модуль и переиспользовать его на множестве форм. Но иногда команду нужно вывести на форму не через конфигуратор, а программно — например, в зависимости от роли пользователя, режима работы или данных объекта. В этом случае используется объект КомандыФормы и коллекция элементов формы.
Программное добавление выполняется в два этапа: сначала создаётся команда формы со ссылкой на действие, затем на форму добавляется кнопка, которой назначается имя этой команды. Важно понимать: общая команда сама по себе не появляется на форме автоматически — её нужно либо перетащить в дерево элементов в конфигураторе, либо добавить кодом.
Ниже разобран рабочий способ через создание команды формы с вызовом обработчика общей команды, а также вариант с прямым использованием объекта метаданных общей команды, ограничения платформы и типичные ошибки.
Что такое общая команда и когда её добавляют программно
Общая команда — объект метаданных с собственным модулем, в котором описан обработчик ОбработкаКоманды. Она не привязана к конкретному объекту и может вызываться из любых форм, отчётов и обработок. В конфигураторе её добавляют на форму перетаскиванием из панели команд в дерево элементов.
Программное добавление оправдано, когда состав кнопок должен быть динамическим: команда видна только администраторам, кнопка появляется при определённом статусе документа, форма собирается универсальным механизмом без изменения каждой формы в конфигураторе. Также это удобно в расширениях, где форма заимствована и менять её визуально нежелательно.
Если состав команд статичен, программное добавление избыточно: проще и надёжнее вывести кнопку штатно в конфигураторе. Код усложняет сопровождение и требует аккуратной работы в обработчике ПриСозданииНаСервере.
Как выбрать способ
Базовый механизм: команда формы плюс кнопка
Платформа не позволяет напрямую «вставить» объект метаданных общей команды в форму кодом. Вместо этого создаётся команда формы — элемент коллекции ЭтаФорма.Команды, — которой назначается обработчик. Из этого обработчика уже вызывается логика общей команды.
Последовательность такая: в ПриСозданииНаСервере добавляется команда с уникальным именем, задаются заголовок, картинка и действие. Затем в нужную группу (командную панель, подменю, контекстное меню) добавляется элемент типа КнопкаФормы, и его свойству ИмяКоманды присваивается имя созданной команды.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Команда = ЭтаФорма.Команды.Добавить("ОтправитьПоПочтеДинам");
Команда.Действие = "Подключаемый_ОтправитьПоПочте";
Команда.Заголовок = НСтр("ru = 'Отправить по почте'");
Команда.Подсказка = НСтр("ru = 'Отправить документ контрагенту'");
Кнопка = ЭтаФорма.Элементы.Добавить("КнопкаОтправитьПоПочте",
Тип("КнопкаФормы"), ЭтаФорма.КоманднаяПанель);
Кнопка.ИмяКоманды = "ОтправитьПоПочтеДинам";
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ОтправитьПоПочте(Команда)
ПараметрыКоманды = Новый Массив;
ПараметрыКоманды.Добавить(Объект.Ссылка);
// Вызов логики общей команды
ОткрытьФорму("ОбщаяФорма.ОтправкаПисьма",
Новый Структура("Документы", ПараметрыКоманды), ЭтаФорма);
КонецПроцедуры
Обратите внимание: имя действия указывается строкой, а процедура-обработчик должна существовать в модуле формы с директивой &НаКлиенте, иначе при нажатии возникнет ошибка «Процедура не обнаружена».
Команда = Команды.Добавить("МояКоманда");
Команда.Действие = "Подключаемый_МояКоманда";
Кнопка = Элементы.Добавить("КнопкаМоя", Тип("КнопкаФормы"), Элементы.ГруппаКнопок);
Кнопка.ИмяКоманды = "МояКоманда";Вызов модуля общей команды из обработчика
Модуль общей команды недоступен для прямого вызова как обычный общий модуль — его обработчик ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) вызывается только платформой. Поэтому из своего обработчика кнопки логику общей команды воспроизводят либо выносят общий код в общий модуль, который вызывается и из общей команды, и из формы.
Правильная архитектура выглядит так: общая команда содержит минимальный код и делегирует работу общему серверному модулю. Программно добавленная кнопка вызывает тот же общий модуль. Тогда поведение идентично независимо от способа запуска, а дублирования кода нет.
Если общая команда открывает форму обработки с параметрами, проще всего из клиентского обработчика вызвать ОткрытьФорму с теми же параметрами, как показано в примере выше. Это покрывает большинство сценариев: печать, отправка, запуск обработки.
Размещение кнопки: командная панель, подменю, контекстное меню
Третьим параметром метода Элементы.Добавить передаётся родительский элемент. Им может быть командная панель формы (ЭтаФорма.КоманднаяПанель), любая группа кнопок, подменю или контекстное меню таблицы. Куда поместить кнопку — решает задача: глобальные действия обычно идут в командную панель, действия над строкой таблицы — в её контекстное меню.
Для контекстного меню динамического списка или табличной части родителем указывают соответствующий элемент, например Элементы.Список.КонтекстноеМеню. При этом в обработчике имеет смысл проверять, есть ли текущая строка, иначе действие выполнится «в пустоту».
Если нужного родителя на форме нет, его тоже можно создать программно: добавить группу типа ГруппаФормы с видом ВидГруппыФормы.Подменю, а затем добавлять кнопки в неё. Так строят выпадающие меню «Ещё»-подобного типа целиком из кода.
- 1Определите, в какую группу формы должна попасть кнопка
- 2В ПриСозданииНаСервере добавьте команду в коллекцию ЭтаФорма.Команды
- 3Задайте команде Действие, Заголовок и при необходимости Картинку
- 4Добавьте элемент КнопкаФормы с родителем — нужной группой
- 5Присвойте кнопке ИмяКоманды созданной команды
- 6Создайте клиентский обработчик с указанным именем и проверьте нажатие
Проверка результата и отладка
После добавления откройте форму в режиме предприятия под целевым пользователем и проверьте: кнопка видна, заголовок корректен, нажатие отрабатывает без ошибок. Если кнопки нет — чаще всего не указан или неверно указан родитель, либо группа скрыта настройками видимости.
Если кнопка есть, но нажатие ничего не делает или выдаёт ошибку, проверьте совпадение строки Действие с именем процедуры в модуле формы и наличие директивы компиляции. Процедура без &НаКлиенте не будет найдена при вызове из интерфейса.
Как проверить результат
Кнопка видна в нужной группе с заданным заголовком
Кнопки нет — проверьте родителя и видимость группы
Выполняется обработчик без сообщений об ошибке
Ошибка «процедура не обнаружена» — имя действия не совпадает с процедурой
Кнопка создаётся один раз, дублей нет
Дубли кнопок — код выполняется повторно без проверки существования
Типичные ошибки и ограничения
Самая частая ошибка — добавление кнопки без создания команды или с опечаткой в ИмяКоманды: кнопка появляется, но неактивна. Вторая по частоте — попытка добавить элементы не в ПриСозданииНаСервере, а в клиентском обработчике, где коллекции команд и элементов недоступны для изменения состава.
Также учитывайте: при повторном создании формы (например, после изменения настроек) код может выполниться повторно. Перед добавлением проверяйте существование команды через ЭтаФорма.Команды.Найти("ИмяКоманды"), иначе получите исключение о дублировании.
Ещё одно ограничение: программно созданные элементы не попадают в командный интерфейс «из коробки» — пользователь не сможет вывести их через настройку формы, а при изменении формы в конфигураторе код нужно держать согласованным с реальными именами групп.
FAQ
Можно ли программно добавить саму общую команду, а не команду формы?
Нет. Платформа не позволяет кодом поместить объект метаданных общей команды на форму. Создаётся команда формы, а её обработчик воспроизводит или делегирует логику общей команды, обычно через общий модуль.
Где именно писать код добавления кнопки?
В обработчике ПриСозданииНаСервере с директивой &НаСервере. Изменение состава команд и элементов формы доступно только на сервере при создании формы.
Как скрыть программно добавленную кнопку по условию?
Установите свойство Видимость элемента кнопки в Ложь по нужному условию. Сделать это можно и на клиенте, в отличие от добавления или удаления элементов.
Почему кнопка появилась, но серая и не нажимается?
Чаще всего не заполнено свойство ИмяКоманды или команда с таким именем не найдена в коллекции команд формы. Проверьте точное совпадение имён, включая регистр и опечатки.
Можно ли назначить кнопке картинку из библиотеки?
Да, через свойство Картинка команды формы, например БиблиотекаКартинок.Печать. Картинка задаётся команде, а не кнопке — кнопка унаследует её автоматически.
Работает ли способ в расширении конфигурации?
Да. В расширении заимствуется форма, и в её модуле через &После("ПриСозданииНаСервере") добавляются команды и кнопки. Это предпочтительный способ доработки типовых форм без изменения конфигурации поставщика.
Что важно запомнить
Общая команда добавляется на форму программно через связку «команда формы + кнопка»: команда создаётся в ПриСозданииНаСервере с действием-обработчиком, кнопка связывается с ней через ИмяКоманды. Логику общей команды выносите в общий модуль, проверяйте дубли при повторном создании формы и используйте расширение для типовых конфигураций.