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

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

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

Проанализируем типичный подход и его ограничения

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


&После("ПриСозданииНаСервере")
Процедура пм_ПриСозданииНаСервере(Форма, Знач ПараметрыРазмещения)
	Если Форма.ИмяФормы = "Документ.ЗаказПокупателя.Форма.ФормаДокумента" Тогда
		ДокументЗаказКлиентаФормаДокумента(Форма);
	КонецЕсли;
КонецПроцедуры 

Процедура ДокументЗаказКлиентаФормаДокумента(Форма)
	НовКоманда = Форма.Команды.Добавить("Команда1");
	НовКоманда.Действие = "Подключаемый_ВыполнитьНазначаемуюКоманду";
	НовКоманда.Подсказка = "Команда11";	
	
	НоваяКнопка = Форма.Элементы.Добавить("Команда1", Тип("КнопкаФормы"), Форма.КоманднаяПанель);	
	НоваяКнопка.Заголовок = "Сделать действие";
КонецПроцедуры  

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

Платформа не поддерживает прямое назначение обработчиков из общих модулей, модулей менеджера или объекта в обход формы. То есть, нельзя написать путь вида "ОбщийМодуль.Процедура". Следовательно, без добавления модуля формы в расширение, реализовать свой программный обработчик для динамической кнопки напрямую через Элементы.Добавить не получится.

Разберем возможные пути решения проблемы

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

1. Использование обработчиков БСП (если они есть в форме)

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


&НаКлиенте
Процедура Подключаемый_ВыполнитьКоманду(Команда)
	ПодключаемыеКомандыКлиент.НачатьВыполнениеКоманды(ЭтотОбъект, Команда, Объект);
КонецПроцедуры

Если в форме нужного документа разработчики конфигурации изначально прописали такую процедуру, мы можем при программном создании команды указать её имя в свойстве Действие: НовКоманда.Действие = "Подключаемый_ВыполнитьКоманду";. Однако этот способ сработает исключительно в том случае, если процедура там действительно есть. В противном случае платформа выдаст ошибку о том, что обработчик не найден.

2. Создание Общей команды

Рассмотрим самый простой платформенный способ вывести кнопку, вообще не затрагивая формы кодом.

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

Этот метод идеален, если команда должна быть доступна глобально для конкретных типов ссылок.

3. Механизм дополнительных отчетов и обработок (БСП)

Поскольку речь идет об УНФ, которая использует функционал БСП, мы можем добавить кнопку через стандартный пользовательский механизм.

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

Ни одна форма документа для этого не модифицируется.

4. Регистрация в подсистеме «Подключаемые команды» (БСП)

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

Для этого нужно использовать модуль ПодключаемыеКомандыПереопределяемый и его процедуру ПриОпределенииКомандПодключенныхКОбъекту (или аналогичные процедуры в модулях менеджеров конкретных документов).

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

← На главную