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