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