При разработке печатных форм в 1С часто возникает задача, когда стандартных возможностей табличного документа недостаточно. Классический пример — необходимость создать многостраничный документ, где каждая страница имеет уникальное оформление, в частности, разный фоновый рисунок. Стандартное свойство ФоноваяКартинка объекта ТабличныйДокумент применяется ко всему документу целиком, что не позволяет решить эту задачу "в лоб".
Рассмотрим два эффективных способа, как обойти это ограничение и реализовать печатную форму со сложным постраничным оформлением.
Этот метод является наиболее мощным и гибким, так как позволяет использовать все богатые возможности форматирования Microsoft Word. Идея заключается в том, чтобы отделить дизайн макета от программной логики его заполнения.
Принцип работы: вы создаете шаблон документа в формате .docx, настраиваете в нем весь дизайн, включая разные фоновые изображения для разных страниц, а затем из 1С программно заполняете этот шаблон данными.
Разберем процесс по шагам:
Подготовка шаблона в Word.
Создайте новый документ в MS Word. Чтобы задать разные фоны для разных страниц, необходимо использовать механизм разделов. Например, для двухстраничного документа:
Далее разметьте в шаблоне области для вывода данных из 1С. Для этого используются специальные параметры-закладки:
[ИмяПараметра], например, [НомерДокумента] или [ДатаДокумента].СтрокаТовары. В ячейках этой строки укажите параметры для колонок: [Номенклатура], [Количество], [Цена].Загрузка шаблона в 1С.
Сохраненный .docx файл нужно добавить в конфигурацию 1С как двоичный макет. Например, в обработке или общем макете.
Программное заполнение из 1С.
Для заполнения шаблона используется функционал БСП из общего модуля УправлениеПечатью. Этот подход полностью сохраняет исходное форматирование документа, включая разные фоновые картинки.
Посмотрим на пример кода, который загружает макет, заполняет параметры и табличную часть:
&НаСервере
Функция СформироватьПечатнуюФормуWord()
// Получаем двоичные данные макета из конфигурации
ДвоичныеДанныеМакета = ПолучитьМакет("МойШаблонWord");
// Инициализируем макет офисного документа
Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета);
Если Макет = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
// Готовим структуру с данными для заполнения
ДанныеДляПечати = Новый Структура;
ДанныеДляПечати.Вставить("НомерДокумента", "ДК-00123");
ДанныеДляПечати.Вставить("ДатаДокумента", Формат(ТекущаяДата(), "ДЛФ=Д"));
// Готовим таблицу значений для табличной части
ТаблицаТоваров = Новый ТаблицаЗначений;
ТаблицаТоваров.Колонки.Добавить("Номенклатура");
ТаблицаТоваров.Колонки.Добавить("Количество");
ТаблицаТоваров.Колонки.Добавить("Цена");
НоваяСтрока = ТаблицаТоваров.Добавить();
НоваяСтрока.Номенклатура = "Товар 1";
НоваяСтрока.Количество = 10;
НоваяСтрока.Цена = 1500;
НоваяСтрока = ТаблицаТоваров.Добавить();
НоваяСтрока.Номенклатура = "Товар 2";
НоваяСтрока.Количество = 5;
НоваяСтрока.Цена = 3200;
ДанныеДляПечати.Вставить("Товары", ТаблицаТоваров);
// Инициализируем итоговый документ
ПечатнаяФорма = УправлениеПечатью.ИнициализироватьПечатнуюФорму(Неопределено, Неопределено, Макет);
// Получаем область всего документа для заполнения простых параметров
ОбластьШапка = УправлениеПечатью.ОбластьМакета(Макет, "ОбластьШапка"); // Предполагается, что вы назвали так область в Word
УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, ОбластьШапка, ДанныеДляПечати);
// Получаем область табличной части и заполняем ее из коллекции
ОбластьТаблицы = УправлениеПечатью.ОбластьМакета(Макет, "СтрокаТовары");
УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФорма, ОбластьТаблицы, ДанныеДляПечати.Товары);
// Формируем итоговый документ и получаем его адрес во временном хранилище
АдресХранилища = УправлениеПечатью.СформироватьДокумент(ПечатнаяФорма);
// Очищаем временные объекты
УправлениеПечатью.ОчиститьСсылки(ПечатнаяФорма);
УправлениеПечатью.ОчиститьСсылки(Макет);
Возврат АдресХранилища;
КонецФункции
Важные моменты:
ПрисоединитьИЗаполнитьПараметры находит в указанной области закладки вида [ИмяПараметра] и заменяет их значениями из переданной структуры или объекта.ПрисоединитьИЗаполнитьКоллекцию находит именованную область (в нашем примере строку таблицы СтрокаТовары) и вставляет ее столько раз, сколько строк в переданной таблице значений, заполняя параметры в каждой строке.Этот способ является предпочтительным для сложных документов, так как вся работа по дизайну выносится во внешний редактор, а код 1С отвечает только за подготовку данных.
Если по каким-либо причинам использование MS Word нежелательно (например, на сервере не установлен Office или требуется полностью нативное решение 1С), можно воспользоваться другим подходом — созданием пакета документов.
Принцип работы: вместо того чтобы пытаться собрать один ТабличныйДокумент из частей с разным фоном, мы создаем несколько независимых объектов ТабличныйДокумент, для каждого настраиваем свой фон и содержимое, а затем объединяем их в специальную коллекцию (массив) для печати или сохранения.
Разберем этот метод по шагам:
Создание нескольких табличных документов.
В коде создайте столько объектов ТабличныйДокумент, сколько у вас страниц с разным фоном. В нашем случае — два.
ТабДок1 = Новый ТабличныйДокумент;
ТабДок2 = Новый ТабличныйДокумент;
Индивидуальная настройка и заполнение каждого документа.
Для каждого документа установите свою фоновую картинку и выведите в него соответствующее содержимое. Например, первая страница — это только титульный лист, а вторая — таблица с данными.
// Настраиваем первую страницу (титульный лист)
КартинкаФон1 = Новый Картинка("C:\background1.jpg");
ТабДок1.ФоноваяКартинка = КартинкаФон1;
// Можно вывести какой-то текст или оставить пустым, если фон уже содержит все необходимое
ОбластьТитул = Макеты.Получить("Титул");
ТабДок1.Вывести(ОбластьТитул);
// Настраиваем вторую страницу (с данными)
КартинкаФон2 = Новый Картинка("C:\background2.jpg");
ТабДок2.ФоноваяКартинка = КартинкаФон2;
// Выводим шапку, таблицу и подвал во второй документ
ОбластьШапка = Макеты.Получить("Шапка");
ТабДок2.Вывести(ОбластьШапка);
// ... цикл по выводу строк таблицы ...
ОбластьПодвал = Макеты.Получить("Подвал");
ТабДок2.Вывести(ОбластьПодвал);
Объединение документов в коллекцию для печати.
Важно: не используйте метод Присоединить(), так как он сольет документы в один и применит настройки фона от первого документа. Вместо этого создайте массив и добавьте в него ваши табличные документы.
ПакетДляПечати = Новый Массив;
ПакетДляПечати.Добавить(ТабДок1);
ПакетДляПечати.Добавить(ТабДок2);
Вывод на печать или сохранение.
Передайте этот массив в стандартную команду печати или сохранения. Система обработает его как единое задание, но каждая часть массива будет выведена со своими индивидуальными настройками.
// Показать пользователю для предварительного просмотра и печати
УниверсальныеМеханизмы.НапечататьДокумент(ПакетДляПечати);
// Или сохранить в один многостраничный PDF-файл
ТабДок1.Записать("C:\output.pdf", ТипФайлаТабличногоДокумента.PDF);
ТабДок2.Записать("C:\output.pdf", ТипФайлаТабличногоДокумента.PDF); // Запись в тот же файл добавит страницы
Этот метод хорош своей "нативностью" для платформы 1С, но может потребовать более сложной логики для управления переносом данных, если большая таблица не помещается на одну страницу и должна быть разбита.
В итоге, выбор метода зависит от сложности макета и требований к проекту. Для печатных форм с профессиональным дизайном рекомендуется первый способ с Word, а для более простых задач, где важна независимость от стороннего ПО, отлично подойдет второй способ с пакетом документов.