Почему метод ПроверитьВывод() в 1С возвращает Ложь, хотя документ помещается на страницу?

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

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

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

Причина 1. Конфликт с механизмом автомасшабирования (Автомасштаб)

Самая распространенная причина ложного срабатывания метода кроется в использовании свойства АвтоМасштаб табличного документа. Когда для документа установлено значение АвтоМасштаб = Истина, платформа при выводе на печать автоматически сжимает документ по ширине, чтобы он полностью уместился на одном листе формата А4. Однако метод ПроверитьВывод() работает иначе.

Алгоритм работы метода не умеет динамически рассчитывать коэффициент сжатия, который будет применен при выводе. Он выполняет расчет физических размеров областей "как есть" — при исходном масштабе 100%. Если ваш исходный макет (шаблон) хотя бы на пару миллиметров шире печатной области страницы А4 при масштабе 100%, платформа считает, что документ выйдет за границы листа. В итоге метод возвращает Ложь, сигнализируя о нехватке места, хотя при фактической печати механизм автомасшабирования сожмет документ до 95-98%, и он прекрасно поместится на одной странице.

Причина 2. Влияние кэша настроек пользователя (КлючПараметровПечати)

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

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

Причина 3. Окружение выполнения кода (Сервер против Клиента)

Метод ПроверитьВывод() критически зависит от системного графического движка операционной системы и доступных драйверов принтера. Рассмотрим, как это влияет на результат:

  1. Отсутствие принтеров на сервере. В клиент-серверном варианте код формирования печатных форм чаще всего выполняется на стороне сервера. Если у системной учетной записи, под которой запущен сервер 1С, нет доступа к физическим или виртуальным принтерам, платформа использует стандартный абстрактный принтер Windows/Linux. Его метрики (размер непечатной области полей) могут существенно отличаться от реального принтера пользователя.
  2. Сервер под управлением Linux. Если серверная часть работает на ОС Linux, ситуация усложняется отсутствием стандартных шрифтов Windows (таких как Arial, Times New Roman, Calibri), которые используются в макете. При отсутствии пакета шрифтов msttcorefonts операционная система Linux подменяет их на похожие шрифты. Из-за разницы в метриках символов текст может переноситься на новые строки, увеличивая высоту ячеек, что приводит к ложному результату работы ПроверитьВывод().

Причина 4. Динамическое объединение ячеек и автовысота

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

---

Как решить проблему: пошаговое руководство

Для того чтобы обойти ограничения платформы и заставить проверку вывода работать со 100% точностью, рассмотрим несколько эффективных подходов.

Решение А. Отказ от автомасштабирования в пользу ручного подбора масштаба

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

Проанализируем следующий пример реализации этого алгоритма:


// Создаем новый табличный документ для проверки
ТабличныйДокументДляПроверки = Новый ТабличныйДокумент;

// Отключаем автоматический масштаб, так как он мешает проверке
ТабличныйДокументДляПроверки.АвтоМасштаб = Ложь;

// Копируем настройки полей и ориентации из исходного документа
ТабличныйДокументДляПроверки.ПолеСлева   = ИсходныйДокумент.ПолеСлева;
ТабличныйДокументДляПроверки.ПолеСправа  = ИсходныйДокумент.ПолеСправа;
ТабличныйДокументДляПроверки.ПолеСверху  = ИсходныйДокумент.ПолеСверху;
ТабличныйДокументДляПроверки.ПолеСнизу   = ИсходныйДокумент.ПолеСнизу;
ТабличныйДокументДляПроверки.ОриентацияСтраницы = ИсходныйДокумент.ОриентацияСтраницы;

// Начинаем подбор масштаба со 100%
ТекущийМасштаб = 100;
ТабличныйДокументДляПроверки.МасштабПечати = ТекущийМасштаб;

// Выводим данные во временный документ
ТабличныйДокументДляПроверки.Вывести(ИсходныйДокумент);

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

Если УспешныйВывод Тогда
    // Применяем подобранный рабочий масштаб к оригинальному документу
    ИсходныйДокумент.АвтоМасштаб = Ложь;
    ИсходныйДокумент.МасштабПечати = ТекущийМасштаб;
Иначе
    // Если даже при сжатии не влезает, возвращаем исходный автомасштаб
    ИсходныйДокумент.АвтоМасштаб = Истина;
КонецЕсли;

Решение Б. Правильная работа с Ключом параметров печати

Если вам необходимо сохранять настройки печати пользователя, но при этом гарантировать корректность проверки на сервере, никогда не устанавливайте КлючПараметровПечати до выполнения проверок вывода. Присваивайте его в самый последний момент, непосредственно перед выводом готового сформированного документа на экран или печать.

Рассмотрим правильную последовательность действий:

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

Решение В. Безопасная проверка с использованием БСП

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

Вместо прямого вызова метода используем функцию общего назначения БСП:


// Безопасный вызов проверки вывода средствами БСП
ПараметрыПроверки = Новый Массив;
ПараметрыПроверки.Добавить(ОбластьМакета);

Если ОбщегоНазначенияКлиентСервер.ПроверитьВыводТабличногоДокумента(ТабличныйДокумент, ПараметрыПроверки) Тогда
    ТабличныйДокумент.Вывести(ОбластьМакета);
Иначе
    ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
    ТабличныйДокумент.Вывести(ОбластьМакета);
КонецЕсли;

Данная функция выполняет внутреннюю проверку возможности построения печатных страниц на сервере и перехватывает возможные исключения операционной системы, предотвращая падение сеанса пользователя.

Решение Г. Оптимизация макета

Если макет разрабатывается с нуля, старайтесь избегать чрезмерно широких колонок. Всегда тестируйте макет при масштабе 100% с полями по 10 мм. Если макет в ширину превышает границы листа А4 при 100%, пересмотрите структуру таблиц. Помните: правильный макет изначально должен быть спроектирован так, чтобы укладываться в печатную область по ширине без использования автомасшабирования.

← На главную