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

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

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

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

---

Способ 1. Использование механизма общих команд и команд объектов

Это самый простой и элегантный способ, заложенный в архитектуру платформы «1С:Предприятие 8». Он позволяет вывести кнопку на форму вообще без написания программного кода в модуле формы или создания программных элементов интерфейса. Всё настраивается на уровне свойств объектов метаданных в расширении.

Выясним по шагам, как настроить такую команду:

  1. В дереве объектов вашего расширения создайте новый объект Общая команда (или добавьте команду к конкретному заимствованному объекту, например, к документу или справочнику, не трогая его формы).
  2. Перейдите в палитру свойств созданной команды. Нам важны три ключевых свойства:
    • Тип параметра команды: укажите тип ссылки на объект, на форме которого должна появиться кнопка (например, ДокументСсылка.РеализацияТоваровУслуг). Это сделает команду параметризуемой.
    • Режим использования параметра: выберите значение Одиночный (или Множественный, если предполагается работа со списком).
    • Группа: это ключевое свойство для позиционирования кнопки. Укажите здесь стандартное место размещения на форме. Например, чтобы кнопка появилась в шапке формы, выберите Командная панель формы.Важное или Командная панель формы.Печать.
  3. В модуле команды опишите логику, которая должна выполняться при нажатии на кнопку. Процедура-обработчик будет выглядеть следующим образом:

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // ПараметрКоманды содержит ссылку на текущий документ или элемент справочника
    Если ЗначениеЗаполнено(ПараметрКоманды) Тогда
        ПоказатьПредупреждение(, "Кнопка нажата для объекта: " + Строка(ПараметрКоманды));
    КонецЕсли;
    
КонецПроцедуры

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

---

Способ 2. Программное добавление кнопки через перехват общих модулей (БСП)

Если конфигурация разработана на базе Библиотеки стандартных подсистем (БСП) (к таким относятся почти все типовые конфигурации: ERP, КА, УТ, УНФ, БП, ЗУП), мы можем использовать программное создание элементов формы при инициализации на сервере.

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

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

Создадим в расширении общий модуль и добавим перехват метода ПриСозданииНаСервере с помощью аннотации &После:


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

Решение проблемы клиентского обработчика нажатия кнопки

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

Как обойти это ограничение?

---

Способ 3. Компромиссный вариант: заимствование «пустышки» формы

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

  1. Заимствуйте форму в свое расширение обычным способом.
  2. Внимание! Откройте заимствованную форму в расширении и полностью удалите из дерева элементов все перенесенные элементы управления и реквизиты. Ваша форма в расширении должна выглядеть абсолютно пустой — без единого поля ввода или декорации. Должна остаться только «чистая» оболочка формы.
  3. В модуле этой пустой формы создайте стандартную экспортную клиентскую процедуру-обработчик для вашей будущей кнопки.
  4. Программное создание команды и кнопки реализуйте в процедуре ПриСозданииНаСервере в модуле формы расширения:

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

&НаКлиенте
Процедура ОбработчикЛокальнойКоманды(Команда) Экспорт
    
    // Здесь мы можем свободно работать с контекстом формы
    ПоказатьПредупреждение(, "Локальный обработчик успешно выполнен в контексте формы!");
    
КонецПроцедуры

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

---

Резюме и рекомендации

Мы проанализировали три отличных подхода к бесконфликтному расширению интерфейса 1С:

← На главную