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