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