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