Как программно создать кнопку для вызова глобальной (общей) команды в 1С?

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

При разработке сложных решений на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей массового внедрения одной и той же кнопки на множество форм различных объектов (справочников, документов, журналов). Естественным желанием разработчика является программное создание кнопки на сервере с привязкой её действия к некоторой Общей команде (глобальной команде), которая определена в конфигурации. Однако попытка сделать это «в лоб» через программное добавление элементов формы неизбежно приводит к ошибкам платформы.

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

Почему напрямую связать кнопку и общую команду программно невозможно?

Давайте выясним причину этого поведения на уровне архитектуры управляемых форм 1С. Ограничение заложено в самой платформе и сохраняется во всех актуальных версиях (включая 8.3.25 / 8.3.26+):

  1. Ограничение свойства ИмяКоманды у кнопки формы: Кнопка, программно создаваемая на управляемой форме (объект типа КнопкаФормы), может быть связана только с той командой, которая объявлена локально в коллекции Команды этой конкретной формы. Попытка присвоить свойству ИмяКоманды значение пути к общей команде, например "ОбщаяКоманда.ИмяМоейКоманды", всегда будет вызывать системное исключение: «Недопустимое значение».
  2. Ограничение свойства Действие у команды формы: Программно созданная локальная команда формы имеет свойство Действие, которое принимает строго текстовое имя экспортной клиентской процедуры (директива &НаКлиенте), расположенной строго внутри модуля этой же формы. Указать здесь путь к процедуре общего модуля (например, "ОбщийМодульКлиент.ИмяПроцедуры") платформа не позволит.

Таким образом, стандартный код программного создания кнопки не сработает:


// Этот код вызовет ошибку на этапе выполнения!
НоваяКоманда = ЭтаФорма.Команды.Добавить("МояКоманда");
НоваяКоманда.Действие = "ОбщийМодульКлиент.ВыполнитьДействие"; // Ошибка!

НоваяКнопка = ЭтаФорма.Элементы.Добавить("КнопкаКоманды", Тип("КнопкаФормы"), ЭтаФорма.Элементы.КоманднаяПанель);
НоваяКнопка.ИмяКоманды = "ОбщаяКоманда.МояОбщаяКоманда"; // Ошибка!

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

---

Способ 1. Автоматическое размещение команды платформой (Без написания кода)

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

Разберем этот процесс по шагам:

  1. В конфигураторе найдите или создайте вашу Общую команду.
  2. Перейдите в свойства этой команды и настройте свойство «Тип параметра команды». Укажите в списке те типы объектов (справочники, документы), на формах которых должна появиться кнопка. Если в вашей конфигурации есть определяемый тип вроде ОпределяемыйТип.ЛюбаяСсылка, можно использовать его для максимального охвата.
  3. Задайте свойство «Группа». Выберите группу команд, в которую должна помещаться кнопка. Например, Панель навигации формы.Важное или Командная панель формы.Важное.
  4. Убедитесь, что у командной панели целевых форм включено свойство «Автозаполнение» (по умолчанию оно всегда включено для стандартных форм объектов).

Результат: Платформа автоматически сформирует и отобразит кнопку на командной панели во всех формах выбранных типов объектов при открытии формы. При нажатии на эту кнопку будет автоматически вызываться модуль вашей общей команды, а в качестве параметра (ПараметрКоманды) будет передана ссылка на текущий объект формы.

---

Способ 2. Использование БСП и механизма «Подключаемые команды» (Лучшая практика)

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

Давайте проанализируем, как это работает:

  1. Регистрация команды: В модуле менеджера объекта (например, документа) или в переопределяемом модуле БСП (ПодключаемыеКомандыПереопределяемый) мы описываем параметры нашей команды через специальный API.
  2. Автоматическая генерация элементов: При создании формы БСП сама анализирует зарегистрированные команды, программно создает команды формы и выводит соответствующие им кнопки в командную панель формы.
  3. Единый обработчик: В качестве обработчика действия для всех таких команд на формах используется стандартная процедура БСП — Подключаемый_ВыполнитьКоманду. Данная процедура уже прописана в модуле стандартных форм БСП и служит своеобразным "мостом", перенаправляющим выполнение в ваш общий модуль.

Посмотрим на пример регистрации такой подключаемой команды в модуле менеджера объекта:


Процедура ПриОпределенииКомандПодключенныхКОбъекту(НастройкиФормы, ИсточникиДанных, Команды, Параметры) Экспорт
	
	НоваяКоманда = Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'Моя глобальная команда'");
	НоваяКоманда.Идентификатор = "МояГлобальнаяКоманда";
	НоваяКоманда.ИмяВыполняемогоМетода = "МойОбщийМодульКлиент.ВыполнитьГлобальноеДействие";
	НоваяКоманда.Порядок = 50;
	
КонецПроцедуры

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

---

Способ 3. Использование расширения конфигурации (Proxy-метод)

Бывают ситуации, когда конфигурация не использует БСП, а вносить изменения в свойства сотен форм в основной конфигурации вручную не хочется. В этом случае на помощь приходит расширение конфигурации, реализующее паттерн "Прокси-процедура".

Рассмотрим этот алгоритм по шагам:

  1. Создаем расширение конфигурации.
  2. Добавляем в расширение общий клиентский модуль (например, Расш_ОбщийМодульКлиент), где описываем логику выполнения нашей глобальной задачи.
  3. Через расширение перехватываем событие ПриСозданииНаСервере для нужных нам типов форм, используя аннотацию &После. Это позволит нам программно внедрять команду и кнопку на форму.

Пример реализации программного добавления команды и кнопки в модуле формы через расширение:


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

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


&НаКлиенте
Процедура Расш_ВыполнитьГлобальноеДействиеФормы(Команда) Экспорт
	
	// Передаем управление в единую точку обработки, передавая саму форму в качестве контекста
	Расш_ОбщийМодульКлиент.ВыполнитьГлобальныйПроцесс(ЭтаФорма);
	
КонецПроцедуры

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

---

Способ 4. Дополнительные обработки заполнения БСП

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

Результат: БСП самостоятельно выведет кнопку вызова вашей логики во все указанные вами объекты в стандартное подменю «Заполнить» (или «Ещё -> Заполнить»). Вам вообще не придется менять код конфигурации или расширять формы.

Резюме

Несмотря на то, что прямое связывание программно созданных элементов интерфейса с глобальными командами ограничено платформой 1С на уровне ядра, разработчику доступен широкий спектр альтернативных вариантов. Для типовых конфигураций на БСП всегда следует отдавать предпочтение встроенному механизму Подключаемых команд или Дополнительным обработкам. Для нетиповых или сильно измененных решений отлично подойдет Proxy-метод через расширения, позволяющий централизованно управлять интерфейсом сотен форм.

← На главную