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