В процессе оптовой и розничной торговли часто возникает ситуация, когда для одной отгрузки клиенту требуется распечатать сразу несколько документов. Как правило, это «Реализация товаров и услуг» и «Расходный ордер на товары» (или расходная накладная). Если эти документы содержат всего несколько позиций, каждый из них занимает не более 30–40% площади бумажного листа А4. Печатать их на отдельных листах — неэкологично и неэкономично. Гораздо удобнее расположить оба документа на одной странице.
В этой статье мы подробно разберем, как решить эту задачу изящно, не прибегая к «грязному» изменению типовой конфигурации, а используя штатные механизмы 1С:Библиотеки стандартных подсистем (БСП) на примере конфигурации «1С:Управление торговлей 11».
Многие начинающие разработчики совершают типичную ошибку: они пытаются встроить новый макет и код печати напрямую в модуль менеджера документа конфигурации. Это приводит к тому, что информационная база снимается с полной поддержки («с замка»). В дальнейшем это существенно усложнит и удорожит процесс обновления программы 1С.
Правильный подход — использование Внешней печатной формы (ВПФ). Механизм БСП позволяет зарегистрировать ВПФ в базе данных так, что для пользователя она будет выглядеть как обычный пункт в стандартном выпадающем меню кнопки «Печать».
---
Для начала создадим внешнюю обработку в конфигураторе. Чтобы система БСП распознала её как печатную форму, в модуле объекта обработки необходимо разместить обязательную экспортную функцию СведенияОВнешнейОбработке(). Рассмотрим пример заполнения этой функции:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("3.1.2.0");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.Наименование = "Комплект: Реализация и Расходный ордер на одном листе";
ПараметрыРегистрации.БезопасныйРежим = Истина;
// Указываем, к каким объектам привязываем форму
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
ПараметрыРегистрации.Назначение.Добавить("Документ.ЗаказКлиента");
// Описываем команду печати
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Реализация и Расходный ордер (1 лист)";
НоваяКоманда.Идентификатор = "ПечатьКомплектаНаОдномЛисте";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
Метод ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке() инициализирует структуру параметров. Мы связываем печатную форму с документами реализации и заказа, а также объявляем команду вызова серверного метода.
---
Главная техническая сложность при выводе двух разных документов на один лист заключается в том, что у «Реализации» и «Расходного ордера» абсолютно разная структура табличной части (разное количество колонок, их ширина и назначение). Если мы просто последовательно выведем сначала одну таблицу, а затем другую в общий ТабличныйДокумент, то колонки второго документа безвозвратно деформируются под сетку первого.
Для решения этой проблемы в платформе 1С:Предприятие 8 предусмотрен важнейший метод — СоздатьФорматСтрок(). Проанализируем, как он работает: данный метод позволяет зафиксировать ширину колонок для уже выведенной области, благодаря чему последующие выводимые области могут иметь совершенно другую структуру колонок, не влияя на предыдущие.
---
В модуле объекта внешней обработки создаем процедуру Печать(), которая отвечает за генерацию итогового табличного документа. Разберем по шагам логику объединения двух макетов:
Процедура Печать(МассивОбъектов, КоллекцияКоманд, ОбъектыПечати, ПараметрыВывода) Экспорт
КомандаПечати = УправлениеПечатью.НайтиКомандуПоИдентификатору(КоллекцияКоманд, "ПечатьКомплектаНаОдномЛисте");
Если КомандаПечати <> Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_КОМПЛЕКТ_НА_ЛИСТЕ";
// Настраиваем свойства для размещения на одном листе А4
ТабличныйДокумент.Автомасштаб = Истина;
ТабличныйДокумент.ОриентацияЛиста = ОриентацияЛиста.Портрет;
// Минимизируем поля, чтобы документы гарантированно уместились
ТабличныйДокумент.ПолеСверху = 5;
ТабличныйДокумент.ПолеСнизу = 5;
ТабличныйДокумент.ПолеСлева = 5;
ТабличныйДокумент.ПолеСправа = 5;
ПервыйДокумент = Истина;
Для Каждого СсылкаИзМассива Из МассивОбъектов Цикл
Если Не ПервыйДокумент Тогда
// Если мы печатаем несколько комплектов, отделяем их друг от друга разрывом страницы
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
// 1. Формируем и выводим Реализацию товаров и услуг
ТабДокРеализация = СформироватьПечатнуюФормуРеализации(СсылкаИзМассива);
ТабличныйДокумент.Вывести(ТабДокРеализация);
// Фиксируем колонки реализации перед выводом следующего документа
ТабличныйДокумент.СоздатьФорматСтрок();
// Добавим декоративную разделительную линию отреза (пунктир)
ВывестиЛиниюОтреза(ТабличныйДокумент);
ТабличныйДокумент.СоздатьФорматСтрок();
// 2. Формируем и выводим Расходный ордер на товары
ТабДокОрдер = СформироватьПечатнуюФормуОрдера(СсылкаИзМассива);
ТабличныйДокумент.Вывести(ТабДокОрдер);
// Фиксируем формат строк расходного ордера
ТабличныйДокумент.СоздатьФорматСтрок();
ПервыйДокумент = Ложь;
КонецЦикла;
// Связываем итоговый документ с коллекцией печатных форм БСП
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияКоманд,
"ПечатьКомплектаНаОдномЛисте",
"Реализация и Расходный ордер (1 лист)",
ТабличныйДокумент
);
КонецЕсли;
КонецПроцедуры
Вспомогательные функции СформироватьПечатнуюФормуРеализации() и СформироватьПечатнуюФормуОрдера() могут вызывать стандартные механизмы печати конфигурации, чтобы не переписывать код заполнения параметров макетов вручную. Мы просто перенаправляем результат в наши локальные объекты ТабличныйДокумент и объединяем их.
Обратите внимание на вызов метода ВывестиЛиниюОтреза(). Это простая процедура, которая выводит пустую строку, оформленную снизу пунктирной линией, чтобы пользователю было удобно визуально разделять документы после печати.
Процедура ВывестиЛиниюОтреза(ТабличныйДокумент)
// Создаем небольшую разделительную область
ТекущаяСтрока = ТабличныйДокумент.ВысотаТаблицы + 1;
ТабличныйДокумент.Область(ТекущаяСтрока, 1, ТекущаяСтрока, 10).Текст = "------------------------------------------ линия отреза ------------------------------------------";
ТабличныйДокумент.Область(ТекущаяСтрока, 1, ТекущаяСтрока, 10).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ТабличныйДокумент.Область(ТекущаяСтрока, 1, ТекущаяСтрока, 10).Шрифт = Новый Шрифт("Arial", 8, Ложь, Истина); // Курсив
КонецПроцедуры
---
После того как внешняя обработка сохранена на диске с расширением .epf, выполним ее подключение в пользовательском режиме:
СведенияОВнешнейОбработке().Теперь при нажатии на кнопку «Печать» в документах «Реализация товаров и услуг» или «Заказ клиента» появится новый пункт, при выборе которого оба документа будут выведены на одну страницу А4.
---
В конфигурациях на базе БСП (включая УТ 11.4) присутствует удобный типовой механизм печати комплектов. Если вы хотите, чтобы разработанная внешняя печатная форма автоматически подтягивалась в этот помощник, выполните следующие действия:
Резюмируем: Использование внешних печатных форм в сочетании с методом СоздатьФорматСтрок() позволяет быстро и безопасно решать нестандартные требования бизнеса к оптимизации печатного пространства. При этом конфигурация программы остается на полной поддержке, что гарантирует легкое обновление системы в будущем.