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

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

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

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

Метод ПроверитьВывод: основной инструмент контроля

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

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


// Создаем массив для проверки
МассивДляПроверки = Новый Массив;

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

// После цикла выводим подвал, который теперь гарантированно будет либо под строкой,
// либо на новом листе вместе с последней строкой (или частью строк)
ТабДок.Вывести(ОбластьПодвал);

Обратите внимание на важный нюанс: метод ПроверитьВывод() принимает именно Массив областей. Если вы передадите в него только одну область, система проверит лишь её, и вы снова рискуете получить подвал на отдельном листе. Проверяя массив [Строка, Подвал], мы заставляем систему "заглянуть в будущее".

Оптимизация производительности при больших документах

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

Чтобы ускорить процесс, мы можем применить стратегию шаговой проверки. Вместо того чтобы вызывать проверку на каждой итерации цикла, мы можем делать это, например, каждые 5-10 строк, или только когда количество выведенных строк приближается к среднестатистическому пределу страницы. Однако наиболее точным остается метод проверки каждой строки перед завершением таблицы.

Использование свойств макета: ВместеСоСледующим

Существует и альтернативный, менее "кодингозатратный" способ, основанный на настройках самого макета 1С. В палитре свойств для каждой строки макета можно установить флаг ВместеСоСледующим.

Разберем, как это работает:

  1. Откройте макет печатной формы.
  2. Выделите строки, относящиеся к Подвалу.
  3. В свойствах установите параметр "Вместе со следующим" (KeepWithNext).
  4. Для последней строки Табличной части также можно установить это свойство, чтобы она "тянула" за собой первую строку подвала.

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

Повтор шапки на каждой странице

Если мы принудительно переносим строку товара на новый лист, чтобы она "составила компанию" подвалу, логично вывести там и заголовок таблицы. В 1С это реализуется через свойство табличного документа ПовторятьНаКаждойСтранице.

Проанализируем, как это настроить программно:


// Указываем диапазон строк макета, которые являются шапкой таблицы
// Например, это строки с 5 по 7
ТабДок.ПовторятьНаКаждойСтраницеСтроки = ТабДок.Область(5, , 7, );

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

Почему ПроверитьВывод может "врать"?

Иногда программисты жалуются, что ПроверитьВывод() возвращает Ложь, хотя визуально на листе еще много места. Выясним причины такого поведения:

  1. Отсутствие принтера: Метод требует наличия установленного принтера по умолчанию в операционной системе. Если код выполняется на сервере (в фоновом задании), убедитесь, что на сервере установлен хотя бы виртуальный принтер (например, PDF).
  2. Автомасштаб: Если у ТабличногоДокумента включено свойство АвтоМасштаб = Истина, расчеты могут быть неточными, так как система пытается "ужать" документ по ширине, что влияет на пропорции высоты.
  3. Поля документа: Если программно установлены очень маленькие поля (например, 0мм), а драйвер принтера имеет "непечатные зоны" (например, 5мм), ПроверитьВывод() может ориентироваться на физические возможности принтера, а не на ваши настройки.

Итоги и рекомендации

Для создания качественной печатной формы мы рекомендуем комбинированный подход:

  1. Используйте ПовторятьНаКаждойСтраницеСтроки для фиксации шапки.
  2. В цикле вывода строк используйте ПроверитьВывод(), передавая в него массив из текущей строки и всего блока подвала.
  3. Если проверка вернула Ложь, выводите горизонтальный разделитель страниц.
  4. Всегда устанавливайте АвтоМасштаб = Истина, чтобы документ корректно вписался в ширину листа А4 у конечного пользователя.

Применяя эти правила, вы добьетесь того, что ваши печатные формы будут выглядеть аккуратно, а реквизиты компании и подписи сторон никогда не окажутся в одиночестве на последнем листе документа.

← На главную