Рассмотрим достаточно частую задачу при доработке конфигураций на базе 1С:Предприятие (например, 1С:УНФ). Возникает необходимость вывести новую кнопку в командную панель всех или определенных документов так, чтобы она выполняла как клиентский, так и серверный код. При этом мы хотим избежать добавления самих форм документов в расширение конфигурации, чтобы не тянуть за собой «гору реквизитов» и не усложнять дальнейшую поддержку при обновлениях.
Посмотрим на пример кода, который часто пытаются использовать разработчики, перехватывая событие создания формы в общем модуле через расширение:
&После("ПриСозданииНаСервере")
Процедура пм_ПриСозданииНаСервере(Форма, Знач ПараметрыРазмещения)
Если Форма.ИмяФормы = "Документ.ЗаказПокупателя.Форма.ФормаДокумента" Тогда
ДокументЗаказКлиентаФормаДокумента(Форма);
КонецЕсли;
КонецПроцедуры
Процедура ДокументЗаказКлиентаФормаДокумента(Форма)
НовКоманда = Форма.Команды.Добавить("Команда1");
НовКоманда.Действие = "Подключаемый_ВыполнитьНазначаемуюКоманду";
НовКоманда.Подсказка = "Команда11";
НоваяКнопка = Форма.Элементы.Добавить("Команда1", Тип("КнопкаФормы"), Форма.КоманднаяПанель);
НоваяКнопка.Заголовок = "Сделать действие";
КонецПроцедуры
Выясним причину, почему такой код не работает должным образом. Основная проблема кроется в жестких архитектурных ограничениях управляемых форм 1С. Свойство Действие у динамически создаваемого объекта типа КомандаФормы принимает строго строку с именем процедуры. Эта процедура-обработчик физически должна находиться в модуле текущей формы.
Платформа не поддерживает прямое назначение обработчиков из общих модулей, модулей менеджера или объекта в обход формы. То есть, нельзя написать путь вида "ОбщийМодуль.Процедура". Следовательно, без добавления модуля формы в расширение, реализовать свой программный обработчик для динамической кнопки напрямую через Элементы.Добавить не получится.
Если мы категорически не хотим расширять формы документов, воспользуемся альтернативными, более корректными с точки зрения архитектуры платформы и БСП (Библиотеки стандартных подсистем) механизмами.
В конфигурациях, построенных на БСП, в модулях многих форм уже встроены универсальные обработчики. Посмотрим на пример типовой процедуры:
&НаКлиенте
Процедура Подключаемый_ВыполнитьКоманду(Команда)
ПодключаемыеКомандыКлиент.НачатьВыполнениеКоманды(ЭтотОбъект, Команда, Объект);
КонецПроцедуры
Если в форме нужного документа разработчики конфигурации изначально прописали такую процедуру, мы можем при программном создании команды указать её имя в свойстве Действие: НовКоманда.Действие = "Подключаемый_ВыполнитьКоманду";. Однако этот способ сработает исключительно в том случае, если процедура там действительно есть. В противном случае платформа выдаст ошибку о том, что обработчик не найден.
Рассмотрим самый простой платформенный способ вывести кнопку, вообще не затрагивая формы кодом.
Тип параметра команды, где галочками отмечаем типы тех документов и списков, где наша кнопка должна появиться (например, ДокументСсылка.ЗаказПокупателя).ОбработкаКоманды.Этот метод идеален, если команда должна быть доступна глобально для конкретных типов ссылок.
Поскольку речь идет об УНФ, которая использует функционал БСП, мы можем добавить кнопку через стандартный пользовательский механизм.
Ни одна форма документа для этого не модифицируется.
Проанализируем более глубокую интеграцию для разработчиков. Если необходимо встроить команду именно программно и глобально, минуя справочник внешних обработок, новые команды регистрируются в общих переопределяемых модулях БСП.
Для этого нужно использовать модуль ПодключаемыеКомандыПереопределяемый и его процедуру ПриОпределенииКомандПодключенныхКОбъекту (или аналогичные процедуры в модулях менеджеров конкретных документов).
В этом реестре мы описываем нашу команду. При открытии любой формы документа типовой код БСП сам прочитает этот реестр, выведет кнопки на форму и свяжет их со своими универсальными обработчиками. Вся логика выполнения команды будет маршрутизироваться через общие серверные и клиентские модули БСП к нашему коду. Захватывать модули самих форм документов в расширение для этого также не требуется.