Как программно добавить кнопку на форму для вызова глобальной или общей команды?

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

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

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

В чем заключается главное ограничение платформы?

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

Однако при попытке повторить это действие программно в коде модуля формы мы сталкиваемся с тем, что свойство ИмяКоманды (CommandName) объекта КнопкаФормы жестко ограничено. Оно может содержать только имя локальной команды формы, определенной в контексте данного конкретного окна.

Если мы попытаемся напрямую присвоить свойству имя общей команды, например:


// Попытка прямого назначения вызовет ошибку выполнения!
НоваяКнопка.ИмяКоманды = "ОбщаяКоманда.ИмяВашейОбщейКоманды";

Информационная база вернет ошибку: «Недопустимое значение атрибута контекста (ИмяКоманды)». Платформа не умеет напрямую связывать физическую кнопку формы с глобальным контекстом метаданных в обход механизма локальных команд.

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

Способ 1. Создание локальной «команды-обертки» (Универсальный вариант)

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

Давайте по шагам разберем реализацию этого способа.

Шаг 1. Программное создание элементов на сервере

В процедуре ПриСозданииНаСервере мы динамически добавляем команду в коллекцию команд формы, настраиваем ее свойства и создаем саму кнопку на командной панели:


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

Шаг 2. Вызов глобальной команды в обработчике на клиенте

Теперь опишем клиентскую процедуру, имя которой мы указали в свойстве Действие. Для вызова глобальной команды мы применим метод ПерейтиПоНавигационнойСсылке. Каждая глобальная команда в системе имеет свой уникальный внутренний адрес URL.


&НаКлиенте
Процедура Подключаемый_ВыполнитьСравнениеБУНУ(Команда)
    
    // Шаблон навигационной ссылки для вызова глобальной команды отчета:
    // e1cib/command/Отчет.<ИмяОтчета>.Команда.<ИмяКоманды>
    
    НавСсылка = "e1cib/command/Отчет.ОтчетСравненияБУНУ.Команда.СравнениеБУНУ";
    
    // Переходим по ссылке, что инициирует выполнение глобальной команды
    ПерейтиПоНавигационнойСсылке(НавСсылка);
    
КонецПроцедуры

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


НавСсылка = "e1cib/command/ОбщаяКоманда.ИмяВашейОбщейКоманды";
ПерейтиПоНавигационнойСсылке(НавСсылка);

Важное примечание о передаче параметров:

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


&НаКлиенте
Процедура Подключаемый_ВыполнитьПараметризованнуюКоманду(Команда)
    
    Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
        // Получаем строковое представление уникального идентификатора объекта
        УИД_Объекта = Строка(Объект.Ссылка.УникальныйИдентификатор());
        
        // Формируем ссылку с параметром "?ref="
        НавСсылка = "e1cib/command/Справочник.Номенклатура.Команда.ОткрытьЦены?ref=" + УИД_Объекта;
        
        ПерейтиПоНавигационнойСсылке(НавСсылка);
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Использование механизмов БСП (Рекомендуемый для типовых конфигураций)

Если вы разрабатываете функционал в современной типовой конфигурации 1С (такой как ERP, Управление торговлей, Комплексная автоматизация или Бухгалтерия предприятия), в которую интегрирована Библиотека Стандартных Подсистем (БСП), ручное программирование кнопок-оберток является не лучшей практикой.

В составе БСП есть мощная подсистема «Подключаемые команды». Она создана специально для того, чтобы автоматически собирать все доступные для конкретного объекта глобальные, общие и параметрические команды (печать, заполнение, отчеты, отправка) и динамически выводить их на форму в виде структурированных подменю.

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

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

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

Резюме

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

← На главную