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