При разработке внешних обработок на платформе 1С:Предприятие 8.3 с использованием Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с жестким разделением функционала. Одной из типичных задач является создание универсального инструмента, который должен быть доступен пользователю в двух местах: непосредственно в форме документа через меню «Заполнить» и в общем списке сервисных функций раздела (подсистемы) через «Дополнительные обработки».
Проблема заключается в том, что в функции СведенияОВнешнейОбработке разработчик обязан указать конкретный Вид обработки, который и определяет логику её поведения в системе. Рассмотрим подробнее, почему возникает эта сложность и как её эффективно решить.
Разберем ситуацию: если мы указываем вид ВидОбработкиЗаполнениеОбъекта, система ожидает привязки к конкретным объектам (документам или справочникам). Команды такой обработки будут видны в кнопке «Заполнение» внутри этих объектов, но механизм БСП скроет возможность размещения этой же обработки в разделах интерфейса (подсистемах).
Если же мы выберем ВидОбработкиДополнительнаяОбработка, то сможем легко назначить обработке любую подсистему (например, «Продажи» или «Склад»), и она появится в пункте «Дополнительные обработки» этого раздела. Однако в этом случае она исчезнет из меню «Заполнить» в документах. Проанализируем, как обойти это ограничение, сохранив при этом единый код обработки.
Посмотрим на пример реализации функции СведенияОВнешнейОбработке, где мы попытаемся совместить разные типы команд. Важно понимать, что тип команды ТипКомандыЗаполнениеФормы требует контекста объекта, а ТипКомандыОткрытиеФормы — нет.
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
// Устанавливаем вид как ЗаполнениеОбъекта для возможности работы с документами
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта;
ПараметрыРегистрации.Версия = "1.0";
// Добавляем команду для заполнения документа
Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = НСтр("ru = 'Заполнить из внешнего источника'");
Команда.Идентификатор = "ЗаполнитьОбъект";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы;
Команда.ПоказыватьОповещение = Истина;
// Добавляем команду для обычного открытия (для подсистемы)
Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = НСтр("ru = 'Открыть рабочее место'");
Команда.Идентификатор = "ОткрытьИнтерфейс";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы;
Команда.ПоказыватьОповещение = Ложь;
Возврат ПараметрыРегистрации;
КонецФункции
Как показывает практика и обсуждение на форумах, одного лишь добавления команд недостаточно. Если Вид указан как ЗаполнениеОбъекта, вкладка «Размещение» в карточке дополнительной обработки в пользовательском режиме может быть заблокирована или игнорироваться системой при выводе в подсистемы.
Выясним наиболее стабильный способ решения задачи без внесения правок в код БСП. Поскольку один элемент справочника ДополнительныеОтчетыИОбработки может иметь только один вид, мы можем зарегистрировать один и тот же файл .epf дважды.
Этот способ позволяет избежать дублирования исходного кода. Система будет хранить две разные записи, ссылающиеся на одну и ту же логику внутри обработки.
Проанализируем ситуацию: когда пользователь работает с обработкой в режиме «Заполнить», он может сохранять определенные настройки (отборы, пути к файлам). Если он откроет ту же обработку через «Сервис», он ожидает увидеть те же настройки. При двойной регистрации ссылки на элементы справочника будут разными, что может привести к разделению сохраненных данных.
Чтобы избежать этого, в коде обработки при использовании ХранилищеОбщихНастроек или СохранитьЗначенияВНастройках следует использовать фиксированный строковый ключ, а не ссылку на саму обработку. Рассмотрим пример:
&НаСервере
Процедура СохранитьНастройкиНаСервере()
// Используем уникальную строку вместо СсылкаНаВнешнююОбработку
КлючНастроек = "МояУниверсальнаяОбработка_Настройки_V1";
ХранилищеОбщихНастроек.Сохранить(КлючНастроек, "", СтруктураНастроек);
КонецПроцедуры
Для того чтобы одна и та же форма корректно работала в обоих режимах, нам нужно научить её определять, откуда она была запущена. Разберем, как это сделать в модуле формы в процедуре ПриСозданииНаСервере.
Когда обработка запускается как «Заполнение объекта», БСП передает в параметры формы массив ОбъектыНазначения. Если же запуск произошел из подсистемы, этого параметра не будет.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, передан ли контекст объектов для заполнения
Если Параметры.Свойство("ОбъектыНазначения") Тогда
// Режим заполнения объекта
МассивОбъектов = Параметры.ОбъектыНазначения;
Если МассивОбъектов.Количество() > 0 Тогда
// Логика подготовки формы для заполнения конкретного документа
ОбъектОснование = МассивОбъектов[0];
КонецЕсли;
Элементы.ГруппаКонтекстнаяИнформации.Видимость = Истина;
Иначе
// Режим работы как обычной обработки из подсистемы
Элементы.ГруппаКонтекстнаяИнформации.Видимость = Ложь;
// Возможно, нужно предложить пользователю выбрать документ вручную
КонецЕсли;
КонецПроцедуры
Таким образом, мы получаем универсальный инструмент: при открытии из документа обработка подхватывает его данные, а при открытии из меню «Сервис» предоставляет пользователю пустой интерфейс для общей работы или выбора данных вручную.
Разберем основные выводы. Несмотря на жесткую структуру БСП, совместить два вида деятельности в одной обработке можно. Главное — помнить:
ЗаполнениеОбъекта первичен для интеграции в формы документов.ДополнительнаяОбработка.Параметры.ОбъектыНазначения, чтобы корректно инициализировать интерфейс.Следуя этим шагам, мы создадим гибкое и удобное решение, которое гармонично впишется в типовой интерфейс конфигураций на базе БСП, таких как 1С:ERP, 1С:УТ 11 или 1С:Бухгалтерия 3.0.