Как программно определить, помещается ли печатная форма на один лист в 1С?

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

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

Причина сбоев при математическом расчете строк

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


Функция ОпределитьКолСтраниц(СтрокШапки, СтрокПодвала, КоличествоСтрокТаб, СтрокНаСтранице)
    ЦелыхСтраниц = Цел(КоличествоСтрокТаб / (СтрокНаСтранице - СтрокШапки));
    ОстатокСтрок = КоличествоСтрокТаб - ЦелыхСтраниц * (СтрокНаСтранице - СтрокШапки); 
    
    Если (ОстатокСтрок + СтрокШапки + СтрокПодвала) > СтрокНаСтранице Тогда 
        ЦелыхСтраниц = ЦелыхСтраниц + 2;
    Иначе     
        ЦелыхСтраниц = ЦелыхСтраниц + 1;
    КонецЕсли;
    
    Возврат ЦелыхСтраниц; 
КонецФункции

Такой алгоритм дает верный результат только в идеальном случае, когда каждая строка номенклатуры занимает ровно одну физическую строчку на бланке. Но если наименование товара длинное, ячейка расширяется по высоте, и фактическая высота строки на листе может быть эквивалентна двум, трем или четырем строкам. В итоге математический алгоритм считает, что страница одна, а при физической печати подвал документа переносится на второй лист. Чтобы избежать подобных ситуаций, в платформе 1С предусмотрен встроенный механизм проверки вывода.

Способ 1: Использование метода ПроверитьВывод() с массивом областей

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

Разберем по шагам, как реализовать такую проверку:

  1. Создаем пустой объект ТабличныйДокумент и обязательно инициализируем его параметры страницы (размер, ориентацию, поля).
  2. Получаем макет формы «Без приложения».
  3. Формируем и заполняем область шапки, добавляем ее в массив.
  4. В цикле обходим строки табличной части документа, заполняем область строки реальными данными и последовательно добавляем каждую заполненную область в массив.
  5. Заполняем область подвала и также помещаем ее в массив.
  6. Вызываем метод ТабДок.ПроверитьВывод(МассивОбластей).

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


Функция ОпределитьВидПечатнойФормы(ДокументСсылка) Экспорт
    
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.РазмерСтраницы = "A4";
    ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
    ТабДок.ПолеСлева = 10;
    ТабДок.ПолеСправа = 10;
    ТабДок.ПолеСверху = 10;
    ТабДок.ПолеСнизу = 10;
    ТабДок.АвтоМасштаб = Ложь;
    ТабДок.МасштабПечати = 100;
    
    Макет = ДокументСсылка.ПолучитьОбъект().ПолучитьМакет("ТТН_БезПриложения");
    
    МассивОбластей = Новый Массив;
    
    // 1. Шапка
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьШапка.Параметры.Заполнить(ДокументСсылка);
    МассивОбластей.Добавить(ОбластьШапка);
    
    // 2. Строки табличной части
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    Для Каждого СтрТовар Из ДокументСсылка.Товары Цикл
        ОбластьСтрока.Параметры.Заполнить(СтрТовар);
        МассивОбластей.Добавить(ОбластьСтрока);
    КонецЦикла;
    
    // 3. Подвал
    ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
    ОбластьПодвал.Параметры.Заполнить(ДокументСсылка);
    МассивОбластей.Добавить(ОбластьПодвал);
    
    // Проверяем, помещается ли весь документ на одну страницу
    Если ТабДок.ПроверитьВывод(МассивОбластей) Тогда
        Возврат "БезПриложения";
    Иначе
        Возврат "СПриложением";
    КонецЕсли;

КонецФункции

Способ 2: Формирование документа целиком и проверка количества страниц

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

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


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

КонецФункции

Обязательные требования к настройкам табличного документа

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

  1. Явное указание параметров страницы: Обязательно задавайте свойства РазмерСтраницы, ОриентацияСтраницы и значения полей (ПолеСлева, ПолеСправа, ПолеСверху, ПолеСнизу) до выполнения проверки. Если параметры не заданы явно, платформа будет использовать системные настройки принтера по умолчанию, которые могут отличаться на разных рабочих местах.
  2. Фиксация масштаба: Убедитесь, что свойство АвтоМасштаб отключено (ТабДок.АвтоМасштаб = Ложь), а МасштабПечати установлен в значение 100, если для бланков строгой отчетности недопустимо сжатие.
  3. Шрифты на сервере: Если формирование и проверка выполняются на стороне сервера 1С под управлением Linux, убедитесь, что в операционной системе установлены шрифты Microsoft Core Fonts (Arial, Times New Roman и др.). Отсутствие шрифтов приводит к искажению метрик и некорректному расчету автовысоты строк.

Альтернативные варианты решения

Если бизнес-процесс допускает незначительные отклонения в оформлении, можно рассмотреть дополнительные варианты:

  1. Включение автомасштабирования: Если включить ТабДок.АвтоМасштаб = Истина, платформа автоматически пропорционально уменьшит масштаб документа так, чтобы он уместился на один лист по ширине и высоте, исключая необходимость формирования приложения.
  2. Контроль длины текста в ячейке: В свойствах ячейки макета можно изменить режим размещения текста с Автовысота на Обрезать или программно сокращать слишком длинные наименования товаров с добавлением многоточия. В таком случае высота строки всегда будет строго фиксированной.
← На главную