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