Как разбить список физических лиц на страницы в печатной форме 1С с ограничением количества строк?

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

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

Анализ проблемы и базовые инструменты

Для решения задачи нам потребуется работать с объектом ТабличныйДокумент и его методами управления печатью. Основная сложность заключается в том, что стандартный механизм платформы переносит строки автоматически, когда место на листе заканчивается. Нам же нужно совместить два условия:

  1. Бизнес-логика: не более 8 строк на страницу.
  2. Техническая логика: строка должна перенестись, если она физически не влезает на лист (например, из-за большой шапки).

Рассмотрим основные инструменты, которые мы будем использовать:

Типичная ошибка: изменение параметров одной области

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


// ОШИБОЧНЫЙ КОД
Область4 = Макет.ПолучитьОбласть("Область4"); 
Для к = 1 По СписокФизЛиц.Количество() Цикл
    Область4.Параметры.ФИО = СписокФизЛиц[к-1].ФизЛицо;
    ТабДокумент.Вывести(Область4);
КонецЦикла;

В чем здесь проблема? Метод ПолучитьОбласть() создает объект в памяти. Если мы получаем область один раз до цикла, а внутри цикла только меняем её параметры, то в некоторых сценариях (например, при формировании массива для ПроверитьВывод()) все строки в итоговом документе могут оказаться одинаковыми. Правило 1: всегда получайте новую область методом ПолучитьОбласть() на каждой итерации цикла, если вы планируете сложные проверки или пакетный вывод.

Решение №1: Простой счетчик строк

Если ваша печатная форма имеет фиксированную высоту строк и вы точно знаете, что 8 строк всегда влезут на страницу, можно использовать простой счетчик. Проанализируем логику:


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

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

Решение №2: Комбинированный метод (Счетчик + ПроверитьВывод)

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


// Лимит строк на одной странице
ЛимитСтрок = 8;
СчетчикСтрок = 0;

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

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

Оптимизация: Вывести() или Присоединить()?

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

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

Дополнительные советы для идеальной печатной формы

Для того чтобы ваша форма выглядела завершенной, рассмотрим еще два механизма:

1. Повтор шапки таблицы. Если список ФИО разрывается на несколько страниц, пользователю будет удобно видеть заголовки колонок на каждой странице. Используйте свойство табличного документа ПовторятьПриПечатиСтроки. Например:


// Повторять строки с 5-й по 6-ю (где находится заголовок таблицы)
ТабДок.ПовторятьПриПечатиСтроки = ТабДок.Область(5,, 6);

2. Зависимость от принтера. Помните, что метод ПроверитьВывод() работает на основе драйвера принтера, установленного «по умолчанию» у пользователя. Если у программиста форма влезает, а у бухгалтера — нет, проверьте настройки полей и масштаб страницы в параметрах печати (ТабДок.АвтоМасштаб = Истина;).

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

← На главную