Как сбросить нумерацию страниц в табличном документе при печати нескольких договоров в 1С?

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

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

Проанализируем суть проблемы

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


ТабДокумент.НижнийКолонтитул.ТекстСправа = "[&НомерСтраницы]";
ТабДокумент.НижнийКолонтитул.Выводить = Истина;

Если мы формируем один общий ТабличныйДокумент и разделяем договоры горизонтальными разделителями страниц, то штатная переменная [&НомерСтраницы] выдаст нам сквозную нумерацию. В итоге первый договор получит страницы 1-4, а второй начнется со страницы 5. Встроенными методами платформы обнулить счетчик внутри одного физического объекта невозможно. Рассмотрим, какие подходы существуют для обхода этого ограничения.

Почему не стоит использовать метод ПроверитьВывод()

На первый взгляд может показаться, что можно отказаться от колонтитулов, добавить в макет отдельную область (например, "ПодвалСНомером") и программно подставлять в нее вычисленный номер. Разберем по шагам, как это выглядит в теории:

  1. Выводим область "Шапка".
  2. С помощью метода ПроверитьВывод проверяем, помещается ли следующая область на страницу.
  3. Если не помещается, принудительно выводим "ПодвалСНомером" в самый низ листа, увеличиваем счетчик и начинаем новую страницу.

Мы настоятельно не рекомендуем использовать этот подход. Выясним причину: метод ПроверитьВывод крайне нестабилен при попытке вручную рассчитать место для подвала. Результат зависит от множества факторов, таких как выбранный принтер (разные драйверы имеют разные "мертвые зоны"), настройки масштабирования ("по ширине страницы") и даже разрешение экрана пользователя. То, что отлично работает на компьютере программиста, почти гарантированно "съедет" на вторую страницу у клиента.

Решение 1: Использование коллекции печатных форм (для конфигураций на базе БСП)

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП) и вы используете внешнюю печатную форму, то оптимальным архитектурным решением будет отказ от "склеивания" договоров.

В процедуру печати передается параметр КоллекцияПечатныхФорм. Вместо того чтобы собирать всё в один табдок, сформируем отдельный ТабличныйДокумент для каждого договора в цикле и добавим их как независимые строки в коллекцию.

Рассмотрим, что это дает: при выводе на экран появится штатное окно предпросмотра БСП. Слева будет список всех сформированных документов (договоров). Так как каждый из них — это отдельный ТабличныйДокумент, системный колонтитул с конструкцией [&НомерСтраницы] будет корректно начинать отсчет с первой страницы для каждого файла.

Решение 2: Объект ПакетОтображаемыхДокументов

Если вывод через БСП по каким-то причинам не подходит, разберем еще один системный подход. Платформа 1С позволяет объединять независимые документы с помощью объекта ПакетОтображаемыхДокументов.

Создадим пакет и добавим в него наши сформированные договоры:


Пакет = Новый ПакетОтображаемыхДокументов;
Для Каждого Договор Из МассивДоговоров Цикл
    ТабДокДоговора = СформироватьДоговор(Договор); // Возвращает ТабличныйДокумент со своим колонтитулом
    
    ЭлементПакета = Пакет.Состав.Добавить();
    ЭлементПакета.Данные = ТабДокДоговора;
КонецЦикла;

Этот подход позволяет задавать общие настройки печати на весь пакет и отправлять документы на принтер единым потоком. Нумерация в колонтитулах при этом останется индивидуальной для каждого документа в пакете.

Решение 3: Прямая печать в цикле (без предпросмотра)

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

Мы просто формируем каждый договор в виде отдельного табличного документа и сразу отправляем его на принтер, используя метод Напечатать.


Для Каждого ВыделеннаяСтрока Из МассивОбъектов Цикл
    ТабДокумент = СформироватьПечатнуюФормуПоОбъекту(ВыделеннаяСтрока);
    
    // Настраиваем колонтитул
    ТабДокумент.НижнийКолонтитул.ТекстСправа = "[&НомерСтраницы]";
    ТабДокумент.НижнийКолонтитул.Выводить = Истина;
    
    // Отправляем на печать без диалога (Истина - показать диалог, Ложь - без диалога)
    ТабДокумент.Напечатать(УстройствоПечати);
КонецЦикла;

В этом случае каждое задание на печать уходит независимо, и принтер самостоятельно нумерует листы, начиная с единицы для каждого нового задания.

Подведем итоги

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

← На главную