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