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