Как корректно проверить умещается ли табличный документ на страницу и решить проблемы с масштабированием в 1С

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

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

Разбор логики работы метода ПроверитьВывод

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

Если ваш ТабличныйДокумент уже содержит данные, занимающие, например, полторы страницы, то вызов ПроверитьВывод() для новой области будет проверять наличие свободного места в остатке второй страницы. Если область туда помещается, метод вернет Истина. В результате вы получите документ на двух страницах, хотя, возможно, рассчитывали, что метод сигнализирует о переходе на новую (третью) страницу или о выходе за пределы одного листа.

Рассмотрим типичный ошибочный код:


ТабДокумент.Вывести(Шапка);
ТабДокумент.Вывести(Подвал);

// Если подвал уже перенесся на 2-ю страницу, 
// проверка ниже будет искать место в хвосте 2-й страницы
Если ТабДокумент.ПроверитьВывод(РеквизитыСторон) Тогда
    ТабДокумент.Вывести(РеквизитыСторон);
Иначе
    ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
    ТабДокумент.Вывести(РеквизитыСторон);
КонецЕсли;

В этой ситуации, если «Шапка» и «Подвал» вместе заняли 1.1 страницы, проверка реквизитов на остаток второй страницы даст положительный результат, и разделитель не будет выведен. В итоге документ растянется на две страницы без явного управления разрывами.

Конфликт масштабирования и свойства Растягивать по горизонтали

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

Выясним причину, почему ПроверитьВывод() может предлагать масштаб 70%, в то время как при ручном выставлении 80% документ прекрасно помещается на лист. Это происходит из-за технологического «запаса», который закладывает платформа при проверке, и некорректного учета динамического изменения ширины ячеек. Платформа «пессимистично» полагает, что текст не влезет, и занижает масштаб сильнее, чем это требуется на самом деле.

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

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

Рассмотрим алгоритм «мягкого» подбора масштаба, который позволяет уместить документ строго на одну страницу. Мы будем уменьшать масштаб в цикле до тех пор, пока количество страниц не станет равным единице:


// Устанавливаем начальный масштаб
ТабличныйДокумент.МасштабПечати = 100;

// Цикл подбора масштаба (ограничиваем итерации для безопасности)
Для Ш = 1 По 20 Цикл
    Если ТабличныйДокумент.КоличествоСтраниц() > 1 Тогда
        // Уменьшаем масштаб на шаг в 2%
        ТабличныйДокумент.МасштабПечати = ТабличныйДокумент.МасштабПечати - 2;
    Иначе
        // Документ уместился на одну страницу, выходим из цикла
        Прервать;
    КонецЕсли;
КонецЦикла;

Важный момент: использование КоличествоСтраниц() внутри цикла может замедлить формирование документа, если в нем сотни строк. Однако для типовых печатных форм (счета, акты, договоры на 1-3 страницы) этот метод является самым надежным.

Альтернативный подход: манипуляция шириной колонок

Если ваша печатная форма состоит из одной широкой колонки (например, текст договора), можно использовать альтернативный «костыль» — программное изменение ширины колонки вместо изменения масштаба всей страницы. Это позволяет сохранить читаемость шрифта, регулируя только плотность заполнения листа по горизонтали.

Посмотрим на пример реализации:


ТабДокумент.АвтоМасштаб = Истина;
Область = ТабДокумент.Область("C1"); // Выбираем колонку, которая должна растягиваться
Область.ШиринаКолонки = 50; // Начальное значение

Пока ТабДокумент.КоличествоСтраниц() > 1 Цикл
    // Увеличиваем ширину колонки, чтобы текст занимал меньше строк в высоту
    Область.ШиринаКолонки = Область.ШиринаКолонки + 1;
    
    // Прерывание цикла, если ширина стала чрезмерной
    Если Область.ШиринаКолонки > 150 Тогда 
        Прервать; 
    КонецЕсли;
КонецЦикла;

Этот метод особенно эффективен, когда включен АвтоМасштаб = Истина. Увеличивая физическую ширину колонки в макете, мы заставляем систему пересчитывать высоту строк. В сочетании с АвтоМасштабом это позволяет добиться идеального заполнения страницы текстом.

Рекомендации по стабильной печати

Для того чтобы ваши расчеты в коде максимально совпадали с тем, что пользователь увидит на экране предварительного просмотра, придерживайтесь следующих правил:

  1. Всегда устанавливайте ИмяПараметровПечати. Это позволяет системе запоминать настройки пользователя, но при программном расчете масштаба лучше сначала очистить параметры или использовать уникальное имя, чтобы настройки старого принтера не искажали расчет КоличествоСтраниц().
  2. Если необходимо, чтобы «Подвал» и «Реквизиты» гарантированно выводились на одной странице, объединяйте их в Массив и передавайте в ПроверитьВывод(МассивОбластей). Только так система поймет, что их нужно анализировать как единый неразрывный блок.
  3. Учитывайте, что расчет на стороне сервера может отличаться от клиента из-за разных настроек принтера по умолчанию. Старайтесь выполнять финальные проверки вывода на той стороне, где формируется ТабличныйДокумент для показа.
  4. При использовании свойства «Растягивать по горизонтали» старайтесь избегать ручного управления масштабом через ПроверитьВывод(), отдавая предпочтение комбинации АвтоМасштаб и контролю через КоличествоСтраниц().

Проанализировав вышеописанные подходы, мы видим, что стандартный ПроверитьВывод() хорош для простых задач по вставке разделителей, но для точного позиционирования документа «в границы листа» лучше использовать циклическую проверку общего количества страниц документа. При необходимости программно вносить подобные корректировки в типовые документы подойдёт инструмент для постобработки печатных форм средствами БСП.

← На главную