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