При формировании сложных печатных форм в системе 1С:Предприятие программисты часто сталкиваются с необходимостью дублирования определенных областей макета (например, шапки таблицы или специальных технических срезов) на каждом новом листе. Несмотря на наличие встроенных механизмов платформы, в ряде случаев требуется ручной контроль вывода строк. Разберем, как правильно реализовать этот механизм, проанализируем типичные ошибки и выясним, почему стандартные методы иногда требуют дополнения программным кодом. В качестве базы для разработки подобного функционала можно использовать пример внешней печатной формы для БСП.
Рассмотрим ситуацию, когда при выводе длинного списка товаров область «среза» корректно отображается на первой и второй страницах, но исчезает на третьей. Часто это происходит из-за конфликта двух подходов: ручного подсчета строк (например, по переменной Ном) и использования метода ПроверитьВывод. Когда мы пытаемся жестко ограничить количество строк на странице (например, не более 30), мы не учитываем, что высота строк может меняться в зависимости от объема текста внутри ячеек. Это приводит к тому, что логический разделитель страниц срабатывает не вовремя, и область повторения «пролетает» мимо расчетного места.
Наиболее надежным способом управления разрывами страниц является использование метода ПроверитьВывод() объекта ТабличныйДокумент. Этот метод позволяет заранее узнать, поместится ли массив областей на текущую страницу с учетом текущих настроек принтера, полей и масштаба. Рассмотрим правильный алгоритм действий внутри цикла обхода данных.
Проанализируем шаги, которые необходимо выполнить:
Посмотрим на пример программного кода, который решает эту задачу:
// Подготовим массив для проверки вывода
ПоследниеСтроки = Новый Массив;
ПоследниеСтроки.Добавить(ОбластьДанных);
// Начинаем цикл по товарам
Пока ВыборкаСтрокТовары.Следующий() Цикл
// Заполняем параметры области данных
ОбластьДанных.Параметры.Заполнить(ВыборкаСтрокТовары);
// Проверяем, поместится ли следующая строка на текущую страницу
Если НЕ ТабДокумент.ПроверитьВывод(ПоследниеСтроки) Тогда
// Если не помещается, вставляем разрыв страницы
ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
// Получаем и выводим область, которая должна повториться в начале новой страницы
ОбластьМакетаСрез = Макет.ПолучитьОбласть("ПовторениеСреза");
ТабДокумент.Вывести(ОбластьМакетаСрез);
КонецЕсли;
// После проверки (и возможного вывода шапки) выводим саму строку данных
ТабДокумент.Вывести(ОбластьДанных);
КонецЦикла;
Важный момент: обратите внимание, что проверка ПроверитьВывод выполняется до того, как вызвана команда ТабДокумент.Вывести(ОбластьДанных). Это позволяет системе вовремя принять решение о переносе строки на следующий лист.
Как показывает практика, метод ВывестиГоризонтальныйРазделительСтраниц() является ключевым инструментом при ручном формировании структуры документа. Он не просто визуально разрывает таблицу, но и обнуляет внутренние счетчики высоты страницы для объекта ТабличныйДокумент. Это гарантирует, что следующая выведенная область (в нашем случае — повторяющийся срез) окажется в самом верху нового листа.
Выясним, когда можно избежать написания сложного кода. В свойствах табличного документа и макета есть штатные средства:
ПовторятьПриПечатиСтроки: если ваша задача — просто дублировать шапку таблицы, вы можете выделить нужные строки в макете и назначить им это свойство. В коде это выглядит так: ТабДокумент.ПовторятьПриПечатиСтроки = ТабДокумент.Область(1,,1,); (где 1 — номер строки шапки).ВместеССледующим: если установить это свойство для области, платформа постарается не оставлять эту область одну в конце страницы, если следующая за ней область не помещается.Однако ручной метод с ПроверитьВывод остается единственно возможным, если на каждой странице нужно выводить не просто статичную шапку, а, например, промежуточные итоги (перенос суммы с предыдущей страницы).
Разберем ситуации, в которых даже правильный код может работать некорректно:
Автомасштаб = Истина, метод ПроверитьВывод может возвращать неточные данные. Система пытается «втиснуть» данные, уменьшая шрифт, что сбивает расчеты высоты. Рекомендуется сначала сформировать документ, а масштаб применять в самом конце.ПроверитьВывод лучше передавать не одну текущую строку, а связку «Строка + Подвал». Это исключит ситуацию, когда последняя строка данных выводится на одной странице, а итоговая сумма «отрывается» от нее и уходит на пустой следующий лист.ПолеСверху и ПолеСнизу. Если они слишком велики, область печати сужается, что заставляет ПроверитьВывод срабатывать гораздо чаще, чем ожидается визуально.Для создания профессиональных отчетов и печатных форм мы рекомендуем придерживаться следующих правил:
Во-первых, старайтесь минимизировать количество ручных разделителей, если задача решается стандартными свойствами макета. Во-вторых, если вы используете ПроверитьВывод, делайте это в одном месте кода, чтобы избежать логических петель. Объединение условий (как в примере выше) позволяет добиться чистоты кода и предсказуемости результата.
Проанализировав вышеописанные методы, можно сделать вывод: стабильное повторение областей на всех страницах (включая третью и последующие) достигается только при строгом контроле момента разрыва страницы. Используйте комбинацию ПроверитьВывод, ВывестиГоризонтальныйРазделительСтраниц и повторный вывод нужной области макета непосредственно после разрыва.