Как в 1С реализовать вывод нескольких страниц в один документ Word (DOCX) через БСП

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке печатных форм (Отладка внешних печатных форм и обработок) часто возникает задача сформировать единый документ Word, в котором данные по разным объектам (например, по разным организациям или договорам) располагаются на отдельных страницах. В Библиотеке стандартных подсистем (БСП) (Справочник по методам БСП (с примерами использования)) предусмотрены штатные механизмы для работы с макетами .docx, однако их использование имеет свои нюансы, отличные от привычных табличных документов .mxl. В этой статье мы подробно разберем, как правильно спроектировать макет и написать код для пакетного вывода данных в один файл.

Понимание принципа работы областей в Word-макетах

Первое, что нам необходимо усвоить: принцип работы с макетом Word в БСП строится на использовании именованных областей. В отличие от MXL, где области задаются координатами строк и колонок, в Word области определяются специальными тегами. Разберем структуру типичного макета для вывода списка товаров по организации.

В тексте документа или внутри ячеек таблиц макета используются следующие конструкции:

  1. Начало области: {v8 Область.ИмяОбласти}
  2. Конец области: {/v8 Область.ИмяОбласти}
  3. Параметры для заполнения: {ИмяПараметра}

Важно понимать, что области могут быть вложенными. Например, вы можете создать общую область ДанныеОрганизации, внутри которой будет находиться шапка и таблица со своей собственной областью для строк СтрокаТаблицы. Главная ошибка начинающих разработчиков — создание множества одинаковых областей в макете для каждой страницы. На самом деле, нам достаточно одной группы областей, которую мы будем выводить в цикле столько раз, сколько потребуется.

Подготовка макета Word

Проанализируем структуру макета. Для корректного вывода нам понадобятся следующие логические блоки:

Создайте в Word документ и разместите теги примерно так:

{v8 Область.Шапка}
Отчет по организации {НазваниеОрганизации}
{/v8 Область.Шапка}

Затем вставьте таблицу, где строка с данными будет помечена как область:
{v8 Область.СтрокаТаблицы} {Номенклатура} | {Количество} | {Цена} {/v8 Область.СтрокаТаблицы}

Программная реализация вывода в цикле

Рассмотрим основной алгоритм работы в модуле менеджера объекта или в специализированной процедуре печати. Нам потребуется использовать функции общего модуля УправлениеПечатью. Основная идея заключается в том, чтобы инициализировать один печатный документ и в цикле "нанизывать" на него области макета.

Проанализируем пример кода, реализующий эту логику:


// 1. Инициализируем структуру печатной формы
ДанныеДляПечати = УправлениеПечатью.ИнициализироватьПечатнуюФормуMSWord(Макет, ИмяМакета);
Документ = ДанныеДляПечати.Документ;

// 2. Описываем области, которые будем использовать
// Для повышения производительности лучше описать структуры областей заранее
ОписаниеШапки = Новый Структура("ИмяОбласти, ТипОбласти", "Шапка", "СтрокаТаблицы");
ОбластьШапка = УправлениеПечатью.ОбластьМакета(ДанныеДляПечати.Макет, ОписаниеШапки);

ОписаниеСтроки = Новый Структура("ИмяОбласти, ТипОбласти", "СтрокаТаблицы", "СтрокаТаблицы");
ОбластьСтрока = УправлениеПечатью.ОбластьМакета(ДанныеДляПечати.Макет, ОписаниеСтроки);

ОписаниеПодвала = Новый Структура("ИмяОбласти, ТипОбласти", "Подвал", "СтрокаТаблицы");
ОбластьПодвал = УправлениеПечатью.ОбластьМакета(ДанныеДляПечати.Макет, ОписаниеПодвала);

// 3. Запускаем цикл по массиву объектов (например, организаций)
Для Каждого ОрганизацияСсылка Из МассивОбъектов Цикл
    
    // Получаем данные для текущей итерации
    ДанныеШапки = ПолучитьДанныеДляШапки(ОрганизацияСсылка);
    ДанныеТаблицы = ПолучитьДанныеТаблицы(ОрганизацияСсылка); // Массив структур или ТЗ
    
    // Присоединяем шапку и заполняем её параметры
    УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(Документ, ОбластьШапка, ДанныеШапки);
    
    // Заполняем табличную часть. БСП сама размножит строку таблицы по коллекции данных
    УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(Документ, ОбластьСтрока, ДанныеТаблицы);
    
    // Определяем, нужен ли разрыв страницы. 
    // Обычно разрыв вставляется перед каждой новой страницей, кроме первой, 
    // либо после каждой, кроме последней.
    ВставитьРазрыв = (ОрганизацияСсылка <> МассивОбъектов[МассивОбъектов.Количество() - 1]);
    
    // Присоединяем подвал. Четвертый параметр отвечает за вставку разрыва страницы
    УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(Документ, ОбластьПодвал, ДанныеПодвала, ВставитьРазрыв);
    
КонецЦикла;

// 4. Завершаем формирование и получаем двоичные данные
ПечатнаяФорма = УправлениеПечатью.СформироватьПечатнуюФорму(ДанныеДляПечати);

Методы управления разрывом страницы

Выясним причину, почему иногда разрыв страницы работает не так, как ожидается. В БСП есть два основных способа управления переносом на новый лист в Word:

  1. Программный способ: Использование четвертого параметра в методе УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(..., Истина). Если передать Истина, БСП добавит символ разрыва раздела или страницы. Однако стоит помнить, что это может добавить пустой лист в конце документа, если не проверять, является ли текущая итерация последней.
  2. Создание отдельной области в макете: Вы можете создать в макете крошечную область (например, пустую строку), внутри которой в самом Word нажат Ctrl + Enter. Назовите её ОбластьРазрыва. В коде выводите её просто методом УправлениеПечатью.ПрисоединитьОбласть(Документ, ОбластьРазрыва) в конце каждой итерации цикла. Это дает визуально более предсказуемый результат при редактировании макета.

Особенности работы с коллекциями данных

Рассмотрим подробнее метод УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию. Это крайне полезная функция, которая избавляет нас от написания вложенных циклов по строкам товаров или услуг.

Чтобы метод отработал корректно, убедитесь, что:

Типичные ошибки и советы по оптимизации

Проанализируем ситуацию, когда формирование документа занимает слишком много времени. Работа с COM-объектами Word (если сервер 1С использует их) довольно ресурсозатратна.

Совет 1: Если ваша версия БСП поддерживает работу с форматом .docx через XML (без использования установленного Word на сервере), обязательно используйте этот режим. Это ускоряет процесс в разы.

Совет 2: Не перегружайте макет сложной графикой внутри повторяющихся областей. Логотипы большого размера могут значительно увеличить итоговый файл, если они будут дублироваться на каждой из 100 страниц.

Совет 3: Обращайте внимание на колонтитулы. В рамках одного документа Word через стандартные методы БСП сложно менять содержимое колонтитулов для каждой страницы индивидуально (например, выводить там название текущей фирмы). Если это критично, данные организации лучше выводить в теле документа (в шапке области), а не в системных колонтитулах Word.

Следуя этим рекомендациям и используя приведенный выше программный код, вы сможете эффективно реализовать вывод сложных многостраничных отчетов в формате Word, полностью используя потенциал Библиотеки стандартных подсистем.

← На главную