Как убрать повторяющуюся шапку таблицы на последней странице печатной формы 1С, если там остался только подвал?

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

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

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

Почему возникает проблема "оторванного" подвала?

Проанализируем логику работы платформы 1С:Предприятие. Механизм ПовторятьПриПечатиСтроки работает линейно. Когда табличный документ формируется и отправляется на печать, платформа разбивает его на страницы на основе физических размеров листа и настроек принтера. Если очередная выводимая область (в нашем случае подвал) не помещается на текущем листе, система принудительно осуществляет разрыв страницы.

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

Решение 1. Использование свойства «ВместеСоСледующим» (Декларативный метод)

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

Рассмотрим по шагам, как применить этот метод:

  1. Откройте макет вашей печатной формы в конфигураторе.
  2. Выделите строку (или строки) области данных таблицы (обычно это область Строка). Если вы хотите применить это программно, то свойство задается для конкретной выводимой области.
  3. В свойствах выделенной строки (или программно для области) установите флаг Вместе со следующим (в коде это свойство ВместеСоСледующим = Истина).

Посмотрим на пример программной установки этого свойства при выводе строки таблицы:


// Получаем область строки из макета
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// Устанавливаем свойство, чтобы связать ее со следующей выводимой областью
ОбластьСтрока.Область().ВместеСоСледующим = Истина;

Как это работает на практике: Когда платформа пытается вывести последнюю строку таблицы, она проверяет, поместится ли эта строка вместе с идущим следом подвалом на текущей странице. Если подвал большой и не влезает на текущий лист, платформа автоматически перенесет последнюю строку таблицы вместе с подвалом на новую страницу. На последней странице у вас распечатается шапка таблицы, под ней будет находиться ровно одна строка данных, а далее — подвал. Это полностью решает проблему "пустой" шапки.

Минусы метода: Если подвал документа чрезвычайно огромный (например, занимает более половины страницы), перенос даже одной строки вместе с ним может не спасти ситуацию — они все равно могут не поместиться вдвоем на новый лист. Кроме того, на предпоследней странице может образоваться избыточное пустое пространство.

Решение 2. Программное управление разрывом страниц перед выводом последней строки

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

Суть метода заключается в том, чтобы на последней итерации цикла вывода строк проверить, поместится ли подвал документа на текущую страницу. Если подвал не помещается, мы принудительно переносим последнюю строку таблицы на следующий лист с помощью явного добавления разделителя страниц.

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


// Количество строк в исходной табличной части
ВсегоСтрок = Товары.Количество();

Для i = 1 По ВсегоСтрок Цикл
    
    // Получаем и заполняем область строки
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Товары[i - 1]);
    
    // Особое условие для последней строки таблицы
    Если i = ВсегоСтрок Тогда
        // Проверяем, поместится ли область подвала на текущую страницу
        Если Не ТабДок.ПроверитьВывод(ОбластьПодвал) Тогда
            // Если подвал не влезает, принудительно переносим последнюю строку на новую страницу
            ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
    КонецЕсли;
    
    // Выводим строку в табличный документ
    ТабДок.Вывести(ОбластьСтрока);
    
КонецЦикла;

// В конце спокойно выводим подвал
ТабДок.Вывести(ОбластьПодвал);

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

Решение 3. Полный отказ от "ПовторятьПриПечатиСтроки" в пользу ручного контроля

В сложных коммерческих тиражируемых решениях (например, в типовых конфигурациях на базе БСП при формировании ТОРГ-12 или УПД) разработчики часто полностью отказываются от стандартного механизма ПовторятьПриПечатиСтроки. Вместо этого они реализуют полный программный контроль вывода шапки и подвала.

Давайте разберем по шагам, как построить такой алгоритм:

  1. Мы выводим шапку документа и первый раз шапку таблицы.
  2. При выводе каждой последующей строки мы проверяем, поместится ли она на текущую страницу. Но проверяем не просто одну строку, а массив областей: Строка таблицы + Шапка таблицы. Зачем? Чтобы в случае перехода на новую страницу гарантировать место под шапку.
  3. Если это последняя строка, мы проверяем в массиве: Строка таблицы + Шапка таблицы + Подвал.
  4. Если массив областей не помещается, мы выводим горизонтальный разделитель страниц, затем вручную выводим область шапки таблицы, и только потом выводим строку данных.
  5. При выводе самого подвала мы делаем обычную проверку. Если подвал не влезает — переносим страницу, но при этом шапку таблицы больше НЕ выводим, так как данные таблицы уже закончились.

Посмотрим на практическую реализацию этого надежного подхода:


ТабДок = Новый ТабличныйДокумент;
ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_НАША_ФОРМА";

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

// Начальный вывод
ТабДок.Вывести(ОбластьШапкаДокумента);
ТабДок.Вывести(ОбластьШапкаТаблицы);

ВсегоСтрок = СписокТоваров.Количество();
Для Индекс = 0 По ВсегоСтрок - 1 Цикл
    
    СтрокаДанных = СписокТоваров[Индекс];
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаДанных);
    
    // Создаем массив для проверки вывода
    МассивПроверки = Новый Массив;
    МассивПроверки.Добавить(ОбластьСтрока);
    
    // Если это последняя строка, обязательно добавляем в проверку подвал
    Если Индекс = ВсегоСтрок - 1 Тогда
        МассивПроверки.Добавить(ОбластьПодвал);
    КонецЕсли;
    
    // Проверяем вывод накопленного пакета областей
    Если Не ТабДок.ПроверитьВывод(МассивПроверки) Тогда
        // Если не влезает, переносим страницу и вручную дублируем шапку таблицы
        ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
        ТабДок.Вывести(ОбластьШапкаТаблицы);
    КонецЕсли;
    
    ТабДок.Вывести(ОбластьСтрока);
    
КонецЦикла;

// Финальный вывод подвала
Если Не ТабДок.ПроверитьВывод(ОбластьПодвал) Тогда
    ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
EndЕсли;
ТабДок.Вывести(ОбластьПодвал);

Этот метод является наиболее отказоустойчивым и гибким. Он на 100% гарантирует, что шапка таблицы никогда не появится на листе, где присутствуют только подписи или итоговая информация.

Важные нюансы работы метода «ПроверитьВывод()»

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

Применяя данные подходы, вы сможете создавать профессиональные печатные формы, которые будут корректно выводиться на печать у любых пользователей вне зависимости от объема выводимых данных!

← На главную