При формировании печатных форм и отчетов в системе «1С:Предприятие» разработчики часто используют механизмы разбиения документа на страницы. Платформа позволяет добавлять разделители как интерактивно (через меню настройки печати), так и программно с помощью специализированных методов. Однако в процессе динамического изменения структуры отчета или при подготовке документа к выводу на экран в режиме управляемых форм возникает обратная задача — полностью убрать ранее установленные разрывы страниц, чтобы представить данные единым непрерывным полотном.
В стандартной командной панели табличного документа управляемого приложения отсутствует штатная кнопка для быстрого удаления разделителей страниц. В этой статье мы подробно разберем, как решить эту задачу программным путем, обойти распространенные ошибки платформы и оптимизировать вывод печатных форм.
Прежде чем переходить к написанию кода, важно разграничить два типа разрывов страниц, которые могут присутствовать в табличном документе (объект ТабличныйДокумент):
ВывестиГоризонтальныйРазделительСтраниц() или ВывестиВертикальныйРазделительСтраниц(), либо добавлены пользователем вручную. Именно эти разрывы хранятся в свойствах форматирования строк и колонок, и именно их мы можем удалить программно.Рассмотрим детально методы программного управления жесткими разрывами страниц, а также способы оптимизации вывода для исключения появления нежелательных мягких разделителей.
Горизонтальные разрывы страниц привязаны к конкретным строкам табличного документа. Чтобы удалить их, необходимо обойти все строки таблицы и сбросить свойства разметки страниц. За управление разрывами отвечают три основных свойства области ячеек:
НачалоСтраницы — определяет, будет ли строка принудительно перенесена на новый лист.КонецСтраницы — устанавливает принудительный разрыв страницы сразу после текущей строки.ВместеСоСледующим — указывает платформе, что текущая строка должна выводиться на одной странице со следующей строкой (предотвращает появление «сиротских» строк).Рассмотрим классический пример кода для удаления всех горизонтальных разделителей страниц:
// Создаем или получаем существующий табличный документ
ТабДокумент = ПолучитьТабличныйДокумент();
// Определяем количество строк в таблице
ВысотаТаблицы = ТабДокумент.ВысотаТаблицы;
// Обходим документ построчно
Для Сч = 1 По ВысотаТаблицы Цикл
// Важно: получаем область, которая является целой строкой
ОбластьСтроки = ТабДокумент.Область(Сч, , Сч, );
// Сбрасываем флаги разметки страниц
Если ОбластьСтроки.КонецСтраницы Тогда
ОбластьСтроки.КонецСтраницы = Ложь;
EndIf;
Если ОбластьСтроки.НачалоСтраницы Тогда
ОбластьСтроки.НачалоСтраницы = Ложь;
EndIf;
Если ОбластьСтроки.ВместеСоСледующим Тогда
ОбластьСтроки.ВместеСоСледующим = Ложь;
EndIf;
КонецЦикла;
Разберем важную синтаксическую особенность приведенного кода. Обратите внимание на метод получения области: ТабДокумент.Область(Сч, , Сч, ). Мы опустили индексы колонок. Это сделано намеренно. Платформа 1С накладывает жесткое ограничение: свойства НачалоСтраницы, КонецСтраницы и ВместеСоСледующим доступны только для областей, представляющих собой полные строки или полные колонки.
Если попытаться обратиться к свойству КонецСтраницы у прямоугольной области ячеек (например, ТабДокумент.Область(Сч, 1, Сч, 5).КонецСтраницы = Ложь или у одиночной ячейки ТабДокумент.Область(1,1)), система вызовет исключение и аварийно завершит работу скрипта с ошибкой доступа к свойству. Поэтому всегда адресуйте строку целиком.
Если табличный документ слишком широкий, разработчики могут использовать вертикальные разделители страниц, чтобы принудительно разбивать отчет на листы по горизонтали. Вертикальный разрез выполняется с помощью метода ВывестиВертикальныйРазделительСтраниц().
Принцип удаления вертикальных разрывов полностью аналогичен работе со строками, но цикл обхода выполняется по ширине табличного документа (по колонкам). Выясним, как выглядит программный код для решения этой задачи:
ТабДокумент = ПолучитьТабличныйДокумент();
ШиринаТаблицы = ТабДокумент.ШиринаТаблицы;
// Обходим документ по колонкам
Для Сч = 1 По ШиринаТаблицы Цикл
// Получаем область, являющуюся полной колонкой (строки опущены)
ОбластьКолонки = ТабДокумент.Область(, Сч, , Сч);
// Сбрасываем флаги разметки для колонки
Если ОбластьКолонки.КонецСтраницы Тогда
ОбластьКолонки.КонецСтраницы = Ложь;
КонецЕсли;
Если ОбластьКолонки.НачалоСтраницы Тогда
ОбластьКолонки.НачалоСтраницы = Ложь;
КонецЕсли;
КонецЦикла;
Этот простой цикл гарантирует, что при выводе на печать широкие таблицы не будут принудительно нарезаться на отдельные вертикальные сегменты, если только этого не потребуют физические настройки принтера.
В сложных комплексных отчетах свойства разметки страниц могут быть установлены не только для циклически создаваемых строк, но и содержаться внутри именованных областей макета или быть привязанными к рисункам и графическим объектам, размещенным на табличном поле. Проанализируем пример функции, которая выполняет тотальную зачистку всех возможных разрывов и признаков удержания строк в табличном документе:
Процедура ПолнаяОчисткаРазметкиСтраниц(ТабличныйДокумент) Экспорт
// 1. Очистка разметки по строкам таблицы
Высота = ТабличныйДокумент.ВысотаТаблицы;
Для ИндексСтроки = 1 По Высота Цикл
СтрокаОбласть = ТабличныйДокумент.Область(ИндексСтроки, , ИндексСтроки, );
Если СтрокаОбласть.НачалоСтраницы Тогда
СтрокаОбласть.НачалоСтраницы = Ложь;
КонецЕсли;
Если СтрокаОбласть.КонецСтраницы Тогда
СтрокаОбласть.КонецСтраницы = Ложь;
КонецЕсли;
Если СтрокаОбласть.ВместеСоСледующим Тогда
СтрокаОбласть.ВместеСоСледующим = Ложь;
КонецЕсли;
КонецЦикла;
// 2. Очистка именованных областей коллекции "Области"
Для Каждого ТекущаяОбласть Из ТабличныйДокумент.Области Цикл
// Проверяем тип области ячеек
Если ТипЗнч(ТекущаяОбласть) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Избегаем ошибок при обращении к неполным строкам/колонкам
Попытка
Если ТекущаяОбласть.ВместеСоСледующим Тогда
ТекущаяОбласть.ВместеСоСледующим = Ложь;
КонецЕсли;
Исключение
// Игнорируем ошибку, если область не является строкой или колонкой целиком
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование конструкции Попытка ... Исключение при обходе именованных областей позволяет безопасно обрабатывать произвольные области макета без риска аварийного прерывания работы программного кода.
Очистка жестких разделителей с помощью свойств КонецСтраницы = Ложь решит проблему только в том случае, если разрывы были добавлены в макет статически. Если же табличный документ физически не помещается на стандартный лист бумаги формата А4, движок визуализации 1С все равно автоматически разобьет его на листы при печати.
Чтобы гарантированно управлять этим процессом и предотвратить неконтролируемое появление «мягких» разрывов, рекомендуется использовать специализированные свойства самого объекта ТабличныйДокумент:
АвтоМасштаб): Установка этого свойства в значение Истина заставит систему автоматически сжать и масштабировать документ по ширине страницы при выводе на печать. Это полностью решает проблему случайного возникновения вертикальных разрывов и ухода колонок на соседние листы.
ТабДокумент.АвтоМасштаб = Истина;
ПосадитьНаСтраницу): Данное свойство указывает платформе необходимость принудительно уместить документ на заданное количество страниц по ширине и высоте.
ТабДокумент.ПосадитьНаСтраницу = Истина;
ТабДокумент.ПолеСлева = 5; // Поля в миллиметрах
ТабДокумент.ПолеСправа = 5;
ТабДокумент.ПолеСверху = 5;
ТабДокумент.ПолеСнизу = 5;
ПроверитьВывод(): Данный метод позволяет разработчику перед непосредственным выводом области в результирующий документ проверить, поместится ли она на текущей странице с учетом всех настроек принтера. Это позволяет гибко управлять логикой заполнения табличного документа.Если перед вами стоит задача полностью сбросить структуру документа и избавиться от любого форматирования (включая цвета ячеек, рамки границ, шрифты, объединения и разделители страниц), можно воспользоваться системным методом Очистить().
Синтаксис метода следующий:
ТабличныйДокумент.Очистить(ОчищатьФормат, ОчищатьДанные, ОчищатьПримечания);
Для удаления только разрывов страниц совместно со всем остальным оформлением при сохранении текстовых данных ячеек вызовите метод с параметрами:
ТабДокумент.Очистить(Истина, Ложь, Ложь);
Важное предупреждение: Данный метод является радикальным средством. Он полностью сбросит все визуальное оформление отчета, превратив его в простую текстовую таблицу без стилей. Используйте его только в специфических сценариях, когда визуальный вид отчета не имеет значения (например, при подготовке сырых данных для выгрузки в сторонние системы).
При динамическом формировании сложных комплексных отчетов разработчики часто используют метод Присоединить() для горизонтальной сборки таблиц из отдельных именованных секций. Важно помнить об особенностях поведения разметки страниц при таких операциях.
Свойства разрывов страниц (такие как НачалоСтраницы, КонецСтраницы) копируются в результирующий табличный документ только тогда, когда присоединение секций производится за правой границей текущего документа. Если вы присоединяете области со сложной внутренней разметкой, часть свойств может потеряться. В таких случаях надежнее всего производить финальный обход результирующего табличного документа циклом и корректировать свойства разметки страниц непосредственно перед показом формы пользователю.