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