В этой статье мы подробно разберем, как добавить команду из внешней обработки на форму справочника в системе 1С, с особым вниманием к размещению этой команды в подменю "Заполнить", а не в стандартных "Дополнительные обработки" или "Еще". Мы проанализируем различные подходы, включая использование Библиотеки стандартных подсистем (БСП) и программное добавление, и предоставим примеры кода для каждого случая.
Стандартный механизм подключения внешних отчетов и обработок в 1С основан на использовании справочника "Дополнительные отчеты и обработки" (части Библиотеки стандартных подсистем, БСП). При регистрации внешней обработки через этот справочник мы можем указать объекты метаданных (например, справочники, документы), к которым она будет привязана. Однако, по умолчанию команды таких обработок часто попадают в общие подменю, такие как "Еще" или "Дополнительные обработки", что не всегда удобно для пользователя.
Особый интерес представляет задача размещения команды в подменю "Заполнить". Это подменю предназначено для команд, которые выполняют действия по заполнению реквизитов текущего объекта, и поэтому является логичным местом для многих внешних обработок.
Наиболее предпочтительным и типовым способом решения данной задачи является корректная настройка параметров регистрации внешней обработки с помощью БСП. БСП предоставляет специальные виды обработок, которые позволяют системе автоматически определять место размещения команды.
Ключевым моментом для размещения команды в подменю "Заполнить" является указание вида обработки как "Заполнение объекта". Это сообщается БСП, что данная обработка предназначена для работы с текущим объектом формы и должна быть размещена соответствующим образом. Мы сделаем это в экспортной функции СведенияОВнешнейОбработке(), которая является точкой входа для регистрации обработки в системе.
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Назначение.Добавить("Справочник.Контрагенты"); // Укажите свой справочник или документ
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Моя команда для заполнения";
НоваяКоманда.Идентификатор = "МояКомандаЗаполнения";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода(); // Важно для работы с формами
Возврат ПараметрыРегистрации;
КонецФункции
Давайте подробнее рассмотрим этот код:
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.1");: Мы создаем объект для регистрации, указывая версию API БСП.ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();: Это самый важный шаг. Мы явно указываем, что наша обработка относится к типу "Заполнение объекта". Именно это свойство дает команду БСП разместить кнопку в подменю "Заполнить".ПараметрыРегистрации.Назначение.Добавить("Справочник.Контрагенты");: Здесь мы определяем, к каким объектам метаданных будет привязана наша команда. В данном примере это справочник "Контрагенты". Вы можете добавить несколько назначений.ПараметрыРегистрации.Команды.Добавить().НоваяКоманда.Представление = "Моя команда для заполнения";: Это текст, который будет виден на кнопке.НоваяКоманда.Идентификатор = "МояКомандаЗаполнения";: Уникальный идентификатор команды, который будет использоваться внутри системы.НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();: Здесь важно использовать ТипКомандыВызовКлиентскогоМетода(), если ваша обработка будет взаимодействовать с формой или открывать другие формы на клиенте. Использование ТипКомандыВызовСерверногоМетода() будет корректно только для серверных операций, не требующих взаимодействия с интерфейсом.После регистрации команды нам необходимо реализовать сам обработчик. Это экспортная процедура или функция в модуле объекта внешней обработки, которая будет вызываться при нажатии на кнопку.
Процедура МояКомандаЗаполнения(Команда) Экспорт
// Здесь будет логика вашей обработки
// Например, открытие формы обработки или выполнение каких-либо действий
Сообщить("Команда 'Моя команда для заполнения' выполнена для объекта: " + Команда.ОбъектНазначения);
// Если нужно открыть форму обработки
// ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма", Новый Структура("ОбъектНазначения", Команда.ОбъектНазначения), Команда.Источник);
КонецПроцедуры
Обратите внимание, что в обработчик команды передается параметр Команда, который содержит полезную информацию, включая Команда.ОбъектНазначения — ссылку на тот объект, с формы которого была вызвана команда.
После сохранения файла внешней обработки (.epf), ее необходимо зарегистрировать в системе:
СведенияОВнешнейОбработке().В некоторых сложных случаях, когда стандартный механизм БСП не подходит (например, если назначения динамически меняются или требуется очень специфичное размещение команды, которое не поддерживается стандартными видами БСП), можно прибегнуть к программному добавлению команды непосредственно на форму. Этот метод сложнее и предпочтительно выполнять его через механизм расширений, чтобы не модифицировать типовую конфигурацию.
Важно: Прямая модификация типовой конфигурации не рекомендуется, так как это усложняет ее обновление и поддержку. Вместо этого используйте расширения конфигурации.
Расширение позволяет заимствовать нужную форму справочника и добавлять на нее новые элементы (команды, кнопки, реквизиты) без изменения исходного кода конфигурации. Для стандартизации таких доработок можно использовать модуль с готовыми функциями программного создания элементов и команд.
В модуле заимствованной формы (например, в обработчике события ПриСозданииНаСервере или ПриОткрытии), мы можем программно добавить команду и кнопку:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ... стандартный код формы ...
// Создаем новую команду формы
НоваяКоманда = ЭтаФорма.Команды.Добавить("МояПрограммнаяКоманда");
НоваяКоманда.Действие = "ВыполнитьМоюКоманду"; // Имя клиентской процедуры, которая будет вызвана
// Создаем кнопку для этой команды
ЭлементыФормы = ЭтаФорма.Элементы;
НоваяКнопка = ЭлементыФормы.Добавить("КнопкаМоейКоманды", Тип("КнопкаФормы"));
НоваяКнопка.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
НоваяКнопка.Заголовок = "Программная команда";
НоваяКнопка.ИмяКоманды = НоваяКоманда.Имя;
// Размещаем кнопку в нужной группе
// Для размещения в подменю "Заполнить" нужно знать имя группы
// Обычно группа "Заполнить" имеет имя "ГруппаЗаполнить" или "ПодменюЗаполнить".
// Проверьте это в конфигураторе для конкретной формы.
Если ЭлементыФормы.Найти("ПодменюЗаполнить") <> Неопределено Тогда
НоваяКнопка.Родитель = ЭлементыФормы.ПодменюЗаполнить;
Иначе
// Если подменю "Заполнить" не найдено, размещаем в "Еще" или создаем свою группу
Если ЭлементыФормы.Найти("ПодменюЕще") <> Неопределено Тогда
НоваяКнопка.Родитель = ЭлементыФормы.ПодменюЕще;
Иначе
// Можно создать свою группу, если это необходимо
// НоваяГруппа = ЭлементыФормы.Добавить("МояГруппаКоманд", Тип("ГруппаФормы"));
// НоваяГруппа.Вид = ВидГруппыФормы.Подменю;
// НоваяГруппа.Заголовок = "Мои команды";
// НоваяКнопка.Родитель = НоваяГруппа;
// НовуюГруппу можно поместить, например, в ГруппаКоманднойПанели
// НоваяГруппа.Положение = ПоложениеЭлементаНаФорме.Авто;
КонецЕсли;
КонецЕсли;
// ...
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьМоюКоманду(Команда)
// Здесь вызываем внешнюю обработку или ее экспортные методы
Сообщить("Вызвана программно добавленная команда!");
// Пример вызова экспортного метода внешней обработки
// ОбщегоНазначенияКлиентСервер.ВыполнитьВнешнююОбработку(
// ОбъектНазначения,
// "ПутьКФайлуОбработки",
// "ИмяЭкспортнойПроцедуры",
// "Параметры");
КонецПроцедуры
Давайте разберем ключевые моменты этого кода:
ПриСозданииНаСервере для добавления элементов.НоваяКоманда = ЭтаФорма.Команды.Добавить("МояПрограммнаяКоманда");: Создаем объект команды формы.НоваяКоманда.Действие = "ВыполнитьМоюКоманду";: Указываем имя клиентской процедуры, которая будет вызвана при нажатии на кнопку.НоваяКнопка = ЭлементыФормы.Добавить("КнопкаМоейКоманды", Тип("КнопкаФормы"));: Создаем элемент формы типа "Кнопка".НоваяКнопка.ИмяКоманды = НоваяКоманда.Имя;: Связываем кнопку с созданной командой.Если ЭлементыФормы.Найти("ПодменюЗаполнить") <> Неопределено Тогда НоваяКнопка.Родитель = ЭлементыФормы.ПодменюЗаполнить;: Это ключевой момент для размещения. Мы ищем существующую группу "Заполнить" по ее имени. Важно: Имя группы может отличаться в разных конфигурациях (например, ГруппаКомандыЗаполнить, ПодменюЗаполнить). Вам необходимо посмотреть имя этой группы в конфигураторе для вашей конкретной формы. Если группа не найдена, можно предусмотреть альтернативное размещение.ВыполнитьМоюКоманду мы реализуем логику вызова внешней обработки или ее функционала. Здесь можно программно открыть форму внешней обработки, передав ей текущий объект как параметр.В некоторых сценариях, когда внешняя обработка должна быть зарегистрирована в справочнике "Дополнительные отчеты и обработки" не вручную, а программно, например, при обновлении или первоначальной настройке, мы можем использовать следующий подход. Хотя автор форума столкнулся с проблемой, что команда все равно не появлялась на форме, этот код показывает, как программно создать запись в справочнике "Дополнительные отчеты и обработки". При этом для корректного размещения в подменю "Заполнить" по-прежнему критично указание Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗаполнениеОбъекта;, как мы рассматривали ранее.
ДокументОбъект = РеквизитФормыВЗначение("Объект"); // Получаем текущий объект формы
ПоискЭлементаСправочника = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Заполнить реквизиты");
Если Не ПоискЭлементаСправочника.Пустая Тогда
ЭлементСправочника = ПоискЭлементаСправочника.ПолучитьОбъект();
Иначе
ЭлементСправочника = Справочники.ДополнительныеОтчетыИОбработки.СоздатьЭлемент();
ЭлементСправочника.Наименование = "Заполнить реквизиты";
КонецЕсли;
// Предполагаем, что ИспользуемоеИмяФайла содержит полный путь к файлу обработки
// В реальном сценарии, файл обработки должен быть загружен в базу или храниться где-то
// Для примера, можно использовать ПутьКФайлуОбработки, который известен
// Пример: ИспользуемоеИмяФайла = "C:\МоиОбработки\ЗаполнитьРеквизиты.epf";
// Здесь ДокументОбъект.ИспользуемоеИмяФайла - это, вероятно, путь к текущей обрабатываемой обработке,
// если этот код выполняется из самой внешней обработки при ее регистрации.
// Для универсальности, путь к файлу должен быть передан или определен другим способом.
ИспользуемоеИмяФайла = ДокументОбъект.ИспользуемоеИмяФайла;
Файл = Новый ДвоичныеДанные(ИспользуемоеИмяФайла);
ХранилищеФайла = Новый ХранилищеЗначения(Файл);
ЭлементСправочника.ХранилищеОбработки = ХранилищеФайла;
ЭлементСправочника.ИмяФайла = Прав(ИспользуемоеИмяФайла, СтрДлина(ИспользуемоеИмяФайла) - СтрНайти(ИспользуемоеИмяФайла, "\", НаправлениеПоиска.СКонца));
// Ключевой момент для размещения в "Заполнить"
ЭлементСправочника.Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗаполнениеОбъекта;
ЭлементСправочника.Публикация = Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Используется;
ЭлементСправочника.Ответственный = Пользователи.ТекущийПользователь;
ЭлементСправочника.Версия = "2.1";
ЭлементСправочника.БезопасныйРежим = Ложь;
ЭлементСправочника.ИмяОбъекта = "Заполнить реквизиты"; // Имя объекта метаданных обработки
ЭлементСправочника.Информация = "Заполнить реквизиты";
ЭлементСправочника.ИспользоватьДляФормыОбъекта = Истина; // Для формы элемента
ЭлементСправочника.ИспользоватьДляФормыСписка = Ложь; // Не использовать для формы списка
ЭлементСправочника.РежимСовместимостиРазрешений = Перечисления.РежимыСовместимостиРазрешенийДополнительныхОтчетовИОбработок.Версия_2_1_3;
ЭлементСправочника.Команды.Очистить();
СтрокаКоманды = ЭлементСправочника.Команды.Добавить();
СтрокаКоманды.Идентификатор = "ЗаполнитьРеквизиты";
СтрокаКоманды.ВариантЗапуска = Перечисления.СпособыВызоваДополнительныхОбработок.ОткрытиеФормы; // Открываем форму обработки
СтрокаКоманды.Представление = "Заполнить реквизиты";
СтрокаКоманды.Модификатор = "";
ЭлементНазначение = "Справочник.Контрагенты"; // Или получаем динамически
ЭлементСправочника.Назначение.Очистить();
СтрокаНазначения = ЭлементСправочника.Назначение.Добавить();
СтрокаНазначения.ОбъектНазначения = Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоНаименованию(ЭлементНазначение);
ЭлементСправочника.Записать();
Обратим внимание на следующие строки:
ЭлементСправочника.Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗаполнениеОбъекта;: Повторно подчеркнем, что это свойство критически важно для определения места размещения команды в подменю "Заполнить".СтрокаКоманды.ВариантЗапуска = Перечисления.СпособыВызоваДополнительныхОбработок.ОткрытиеФормы;: Указывает, что при вызове команды будет открываться форма обработки.ЭлементНазначение = "Справочник.Контрагенты";: Здесь мы задаем объект назначения. В случае динамического назначения, как у автора темы, эту строку необходимо будет модифицировать для получения нужного объекта.Даже с таким кодом, как упоминалось в обсуждении, команда может не появиться сразу или появиться не в том месте, если БСП или форма объекта имеют свои особенности обработки команд. Всегда стоит сначала попробовать стандартный путь через СведенияОВнешнейОбработке().
Мы рассмотрели три основных подхода к добавлению команды внешней обработки на форму справочника:
ВидОбработкиЗаполнениеОбъекта: Это самый простой, рекомендуемый и типовой способ для большинства задач, когда объект назначения известен заранее. Он обеспечивает автоматическое размещение команды в подменю "Заполнить".Вид = Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗаполнениеОбъекта).Прежде чем приступать к сложным программным решениям, всегда начинайте с изучения возможностей БСП и ее механизмов регистрации внешних обработок. В большинстве случаев она предоставляет необходимые инструменты для решения задачи без избыточного кодирования и модификаций конфигурации. Для быстрого ознакомления с доступными функциями подсистем пригодится справочник по методам БСП с практическими примерами.