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