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