Как подключить встроенную обработку в 1С через БСП аналогично внешней?

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

При разработке на платформе 1С Предприятие часто возникает дилемма. С одной стороны, внешние обработки заполнения объектов удобны: их можно подключать и обновлять «на лету» через справочник Дополнительные отчеты и обработки без внесения изменений в конфигурацию. С другой стороны, встроенные обработки гораздо удобнее для разработчика: по ним работает глобальный поиск, их код легко отслеживать в системах контроля версий (Git, EDT), и они всегда находятся в одном месте вместе с остальной конфигурацией.

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

Штатный механизм БСП: Подключаемые команды

Начиная с ранних версий БСП 3.x, в системе присутствует мощный механизм подключаемых команд. Он позволяет связывать встроенные объекты метаданных (отчеты и обработки) с документами-потребителями без написания кода в формах этих документов. Чтобы наша встроенная обработка автоматически появилась в меню Заполнение нужного документа, нам потребуется выполнить несколько последовательных шагов.

Шаг 1. Включение обработки в системную подсистему

Первое и обязательное условие для того, чтобы БСП вообще «увидела» нашу встроенную обработку — это правильное ее позиционирование в дереве метаданных. Нам необходимо включить обработку в состав подсистемы ПодключаемыеОтчетыИОбработки. Если этого не сделать, менеджер подключаемых команд проигнорирует объект при инициализации системы.

Выполним это в конфигураторе:

  1. Найдем нашу обработку в дереве метаданных.
  2. Откроем ее свойства и перейдем в раздел Подсистемы.
  3. Установим флажок напротив подсистемы СтандартныеПодсистемы -> ПодключаемыеОтчетыИОбработки.

Шаг 2. Программирование модуля менеджера встроенной обработки

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


#Область ПрограммныйИнтерфейс

// Определяет настройки интеграции обработки с механизмами БСП.
//
// Параметры:
//   Настройки - Структура - Настройки интеграции подключаемых отчетов и обработок.
//
Процедура ПриОпределенииНастроек(Настройки) Экспорт
    
    // Указываем, к каким объектам метаданных мы хотим подключить нашу обработку.
    // Например, подключим ее к документу "Реализация товаров и услуг".
    Настройки.Размещение.Добавить(Метаданные.Документы.РеализацияТоваровУслуг);
    
    // Указываем, что наша обработка предоставляет команды заполнения.
    Настройки.ДобавитьКомандыЗаполнения = Истина;
    
КонецПроцедуры

// Формирует список команд заполнения, которые будут добавлены в форму объекта-потребителя.
//
// Параметры:
//   КомандыЗаполнения - ТаблицаЗначений - Команды, выводимые на форму.
//   Параметры         - Структура       - Вспомогательные параметры.
//
Процедура ДобавитьКомандыЗаполнения(КомандыЗаполнения, Параметры) Экспорт
    
    Команда = КомандыЗаполнения.Добавить();
    Команда.Идентификатор = "ЗаполнитьПоШаблонуВстроенная";
    Команда.Представление = НСтр("ru = 'Заполнить по шаблону (встроенная)'");
    Команда.РежимЗаписи    = "Записывать"; // Варианты: Записывать, НеЗаписывать, ЗаписыватьТолькоПроведенные
    Команда.Очередь        = 1;
    
КонецПроцедуры

#КонецОбласти

Рассмотрим подробнее параметры команды заполнения:

Шаг 3. Реализация обработчика выполнения команды

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


#Область ПрограммныйИнтерфейс

// Выполняет команду заполнения, вызванную из формы объекта.
//
// Параметры:
//   ИдентификаторКоманды - Строка - Идентификатор запущенной команды.
//   ОбъектыНазначения    - Массив - Ссылки на объекты, для которых вызвана команда.
//   ПараметрыВыполнения  - Структура - Контекст выполнения команды.
//
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
    
    Если ИдентификаторКоманды = "ЗаполнитьПоШаблонуВстроенная" Тогда
        ВыполнитьЗаполнениеДокументов(ОбъектыНазначения, ПараметрыВыполнения);
    КонецЕсли;
    
КонецПроцедуры

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

Процедура ВыполнитьЗаполнениеДокументов(ОбъектыНазначения, ПараметрыВыполнения)
    
    Для Каждого СсылкаНаДокумент Из ОбъектыНазначения Цикл
        
        // Получаем объект документа для изменения данных
        ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
        
        // Пример заполнения реквизита "Комментарий"
        ДокументОбъект.Комментарий = ДокументОбъект.Комментарий + " [Заполнено встроенной обработкой " + Строка(ТекущаяДата()) + "]";
        
        Попытка
            ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
        Исключение
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                НСтр("ru = 'Не удалось записать документ при заполнении: '") + ОписаниеОшибки()
            );
        КонецПопытки;
        
    КонецЦикла;
    
    // Оповещаем форму о необходимости перечитать данные
    ПараметрыВыполнения.СистемныеПараметры.Вставить("ВыполнитьОповещениеОИзменении", Истина);
    
КонецПроцедуры

#КонецОбласти

Шаг 4. Обновление вспомогательных данных в пользовательском режиме

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

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

  1. Запустить сеанс «1С:Предприятие» с параметром командной строки /ЗапускОбновленияИнформационнойБазы.
  2. Либо зайти в режиме администратора и открыть стандартную обработку Обновление вспомогательных данных (в разных конфигурациях она может находиться в разделе «Администрирование -> Обслуживание -> Обновление программы»).
  3. Также кэш автоматически обновится, если временно изменить номер версии конфигурации на сотую долю при обновлении.

После этого откроем документ «Реализация товаров и услуг» и убедимся, что на форме в меню Заполнение появилась наша новая кнопка «Заполнить по шаблону (встроенная)».

---

Гибридный подход: Внешняя обработка-заглушка

Рассмотрим альтернативную ситуацию. Что делать, если вам крайне важно сохранить возможность администрирования прав доступа к этой обработке штатными средствами БСП (через интерфейс справочника Дополнительные отчеты и обработки, с привязкой к конкретным пользователям или разделам интерфейса), но при этом вы не хотите постоянно перезаливать файл .epf при каждом изменении кода?

Для решения этой задачи мы можем применить крайне удобный гибридный метод:

  1. Вся основная логика заполнения, формы и алгоритмы разрабатываются и хранятся внутри встроенной обработки (например, Обработка.МоеВстроенноеЗаполнение).
  2. Создается внешняя обработка-заглушка минимального размера. В ней прописывается стандартная функция БСП СведенияОВнешнейОбработке() для интеграции.
  3. В модуле объекта внешней обработки в процедуре выполнения команды мы просто перенаправляем вызов во встроенную обработку.

Посмотрим на пример кода модуля объекта такой внешней обработки-заглушки:


Функция СведенияОВнешнейОбработке() Экспорт
    
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.3");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Наименование = "Заполнение объектов (Гибридный метод)";
    ПараметрыРегистрации.Информация = "Внешняя заглушка для вызова встроенного кода";
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Заполнить встроенным механизмом";
    НоваяКоманда.Идентификатор = "ВыполнитьИнтеграцию";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовСерверногоМетода();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
    
    Если ИдентификаторКоманды = "ВыполнитьИнтеграцию" Тогда
        
        // Вызываем код напрямую из встроенной обработки конфигурации!
        ВстроенныйОбъект = Обработки.МоеВстроенноеЗаполнение.Создать();
        ВстроенныйОбъект.ВыполнитьЗаполнение(ОбъектыНазначения, ПараметрыВыполнения);
        
    КонецЕсли;
    
КонецПроцедуры

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

---

Как вывести кнопку заполнения в командную панель табличной части?

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

Выясним, как элегантно решить эту проблему, используя программное добавление элементов в форме документа или через расширение конфигурации.

Рассмотрим по шагам программное добавление кнопки в форму документа через расширение:

  1. Создадим расширение конфигурации (или используем существующее).
  2. Добавим в расширение форму нужного нам документа (например, форму документа «Реализация товаров и услуг»).
  3. В модуле формы расширения перехватим процедуру ПриСозданииНаСервере.

Пропишем следующий код, который создаст команду и поместит кнопку непосредственно на командную панель табличной части:


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

&НаКлиенте
Процедура Подключаемый_ВыполнитьПрограммноеЗаполнениеТЧ(Команда)
    
    // Передаем управление на сервер для выполнения заполнения табличной части
    ВыполнитьЗаполнениеТЧНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура ВыполнитьЗаполнениеТЧНаСервере()
    
    // Получаем объект встроенной обработки
    ОбработкаЗаполнения = Обработки.МоеВстроенноеЗаполнение.Создать();
    
    // Передаем объект текущего документа для заполнения табличной части "Товары"
    ДокументОбъект = РеквизитФормыВЗначение("Объект");
    
    ОбработкаЗаполнения.ЗаполнитьТабличнуюЧастьТовары(ДокументОбъект);
    
    // Возвращаем измененные данные обратно на форму
    ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
    
КонецПроцедуры

Используя этот подход, мы получаем идеальный UX: пользователь видит красивую кнопку с иконкой непосредственно над табличной частью «Товары», а вся бизнес-логика заполнения по-прежнему аккуратно инкапсулирована внутри встроенной обработки конфигурации, обеспечивая чистоту кода и простоту поддержки.

← На главную