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