Как правильно определить количество страниц в табличном документе 1С и почему возникают расхождения?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке печатных форм в 1С программисты часто сталкиваются с ситуацией, когда метод КоличествоСтраниц() возвращает одно значение, а при предварительном просмотре или реальной печати количество листов оказывается другим. Это создает сложности, если логика программы зависит от точного разбиения документа на страницы (например, если нужно выводить итоги в конце каждой страницы или ограничивать размер документа). В этой статье мы подробно разберем, от чего зависит этот показатель и как добиться максимальной точности в расчетах.

Разберем принцип работы метода КоличествоСтраниц()

Для начала проанализируем, как платформа 1С производит расчет. Метод КоличествоСтраниц() не просто считает строки, он выполняет виртуальную визуализацию документа на основе текущих настроек печатной формы и системных параметров. Основная причина, по которой возникают расхождения, заключается в том, что этот метод чрезвычайно чувствителен к контексту выполнения и состоянию объекта ТабличныйДокумент.

Рассмотрим основные факторы, влияющие на результат:

  1. Настройки принтера: Платформа берет параметры «непечатных зон» и поддерживаемых форматов из драйвера принтера, установленного по умолчанию. Если на сервере (где часто выполняется код) и на клиенте (где открывается просмотр) установлены разные принтеры, результат будет отличаться.
  2. Порядок установки свойств: Если мы сначала вызываем КоличествоСтраниц(), а только потом устанавливаем ОриентацияСтраницы или Поля, то полученное число будет неактуальным.
  3. Автомасштабирование: Использование свойства АвтоМасштаб = Истина вносит наибольшую неопределенность, так как финальное сжатие происходит в момент отрисовки, и метод может не учесть коэффициент сжатия корректно.

Использование метода ПроверитьВывод() для точного контроля

Как справедливо заметили участники форума, для управления процессом формирования страниц лучше использовать метод ПроверитьВывод(). В отличие от простого подсчета общего количества страниц, этот метод позволяет нам в реальном времени (в цикле формирования отчета) понимать, поместится ли очередная секция на текущий лист.

Рассмотрим пример кода, который позволяет вручную контролировать разбиение на страницы и точно знать их количество:


// Создаем массив для проверки выводимых областей
МассивВыводимыхОбластей = Новый Массив;
СчетчикСтраниц = 1;

Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ОбластьСтрока.Параметры.Заполнить(СтрокаДанных);
    
    // Очищаем массив и добавляем текущую область
    МассивВыводимыхОбластей.Очистить();
    МассивВыводимыхОбластей.Добавить(ОбластьСтрока);
    
    // Проверяем, поместится ли строка на текущую страницу
    Если Не ТабДок.ПроверитьВывод(МассивВыводимыхОбластей) Тогда
        // Если не помещается, вставляем разделитель и увеличиваем счетчик
        ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
        СчетчикСтраниц = СчетчикСтраниц + 1;
    КонецЕсли;
    
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Такой подход гарантирует, что вы будете точно знать количество страниц, так как сами управляете их созданием через ВывестиГоризонтальныйРазделительСтраниц().

Влияние серверного контекста на расчет страниц

Проанализируем ситуацию, когда код выполняется на стороне сервера. Часто службы 1С:Предприятия работают под системной учетной записью (например, USR1CV8), у которой либо вообще нет принтера по умолчанию, либо настройки печати сильно отличаются от настроек пользователя. В этом случае метод КоличествоСтраниц() на сервере может вернуть "2", а пользователь на клиенте увидит "1".

Для минимизации таких ошибок рекомендуется:

  1. Явно задавать имя принтера, если оно известно: ТабДок.ИмяПринтера = "HP_LaserJet_P1102";.
  2. Устанавливать все настройки страницы (поля, ориентацию) в самом начале формирования документа.
  3. Если расчет критичен, выполнять его на стороне клиента, где настройки принтера соответствуют тому, что видит пользователь.

Проблема свойства АвтоМасштаб

Выясним причину, почему АвтоМасштаб часто «обманывает» разработчика. Когда это свойство включено, 1С пытается уместить документ по ширине, пропорционально уменьшая весь макет. Метод КоличествоСтраниц() может рассчитывать данные по «номинальному» размеру шрифтов и ячеек, не зная, какой именно коэффициент масштабирования применит графический движок при выводе в окно предварительного просмотра.

Если вам нужно гарантированно уместить документ на одну страницу по ширине и при этом знать количество страниц по вертикали, лучше использовать ЭкземплярУстановкиПараметровПечати или явно задавать масштаб через МасштабПечати (в процентах), избегая автоматики.

Практические рекомендации по настройке макета

Чтобы метод КоличествоСтраниц() возвращал максимально адекватные данные, выполните следующие действия перед его вызовом:


ТабДок = Новый ТабличныйДокумент;
// Сначала устанавливаем все параметры страницы
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
ТабДок.ПолеСлева = 10;
ТабДок.ПолеСправа = 10;
ТабДок.ПолеСверху = 10;
ТабДок.ПолеСнизу = 10;
ТабДок.АвтоМасштаб = Ложь; // Для точности лучше выключить

// Затем заполняем данными
// ... (код заполнения)

// И только в самом конце, когда документ полностью сформирован
ВсегоСтраниц = ТабДок.КоличествоСтраниц();

Также стоит учитывать наличие скрытых колонок и строк. Хотя свойство Видимость = Ложь должно исключать ячейки из расчета, иногда наличие в этих областях графических объектов (картинок, прямых линий), границы которых выходят за пределы видимых ячеек, заставляет систему «считать» пустые листы. Убедитесь, что все рисунки внутри табличного документа строго привязаны к ячейкам и не выступают за их границы.

Подводя итог, можно сказать, что для получения 100% достоверного результата лучше комбинировать использование ПроверитьВывод() в процессе формирования и установку жестких параметров страницы, минимизируя зависимость от системных настроек конкретного принтера.

← На главную