При формировании широких печатных форм и ведомостей (например, табелей посещаемости, расписаний или графиков с большим числом дат) часто возникает задача ограничить число выводимых колонок на одном печатном листе. Если колонок слишком много, они либо масштабируются до нечитаемого размера, либо обрезаются непредсказуемым образом. Разберем распространенные ошибки при реализации такого алгоритма и выясним, как правильно разбить таблицу по 18 колонок на страницу, настроить вертикальные разделители и корректно спозиционировать ячейки макета.
Рассмотрим типовую ситуацию: в цикле выводятся колонки с датами, и разработчик пытается отследить момент перехода на новую страницу через свойство ТабДок.ШиринаТаблицы = 18. На первой странице это срабатывает, но на последующих листах перенос перестает выполняться. Выясним причину такого поведения.
Свойство ШиринаТаблицы возвращает общую максимальную ширину результирующего табличного документа за все время вывода. Оно не сбрасывается при установке разделителя и не показывает позицию текущего курсора на новом листе. Как только ширина документа превысила 18 колонок, условие перестает выполняться до конца процедуры.
Вторая распространенная ошибка связана с позиционированием областей. Если получать область колонки целиком через Макет.ПолучитьОбласть("Столб"), при выводе ячейки могут смещаться по высоте или выравниваться некорректно. Для построения сетки ячеек необходимо использовать пересечение горизонтальных и вертикальных секций.
Разберем по шагам, как построить надежный алгоритм управления переносом колонок с использованием явного счетчика и вертикального разделителя страниц.
Посмотрим на пример правильной структуры программного кода:
Счетчик = 0;
Для Каждого Колонка Из Расп Цикл
Счетчик = Счетчик + 1;
ОблЭлемент.Параметры.Дата = Формат(Колонка.Дата, "ДФ=dd.MM");
ТабДок.Присоединить(ОблЭлемент);
Если Счетчик = 18 Тогда
ТабДок.Присоединить(ОблОценка);
ТабДок.ВывестиВертикальныйРазделительСтраниц();
Счетчик = 0;
КонецЕсли;
КонецЦикла;
// Выводим замыкающую область для последней неполной страницы
Если Счетчик <> 0 Тогда
ТабДок.Присоединить(ОблОценка);
КонецЕсли;
Обратите внимание на проверку после цикла: важно использовать условие Если Счетчик <> 0 Тогда. Если использовать проверку Счетчик <> 18, то при кратном 18 количестве колонок условие выполнится повторно, так как счетчик был сброшен в ноль внутри цикла.
Проанализируем причину, по которой макет может выводиться криво, а даты съезжать влево или вниз. Когда табличный документ формируется динамически по двум осям (строки и столбцы), ячейка должна принадлежать конкретной именованной строке и именованной колонке.
В макете необходимо выделить горизонтальную область (например, Строка) и вертикальные области колонок (например, Столб и ОблОценка). Получение областей в коде выполняется через оператор пересечения — вертикальную черту |:
// Некорректно (получение всей вертикальной полосы макета):
// ОблЭлемент = Макет.ПолучитьОбласть("Столб");
// Корректно (получение конкретной ячейки на пересечении строки и столбца):
ОблЭлемент = Макет.ПолучитьОбласть("Строка|Столб");
ОблОценка = Макет.ПолучитьОбласть("Строка|ОблОценка");
Такой синтаксис гарантирует, что ячейка сохранит правильные высоту, ширину, рамки и выравнивание текста.
При переносе колонок на следующую страницу возникает потребность повторить заголовочную часть, а также зафиксировать левые колонки (например, ФИО или номер по порядку).
Рассмотрим два подхода к реализации этой задачи.
Если структура последующих листов требует ручного управления, после вызова ВывестиВертикальныйРазделительСтраниц() можно заново вывести секцию шапки и фиксированную левую колонку:
Если Счетчик = 18 Тогда
ТабДок.Присоединить(ОблОценка);
ТабДок.ВывестиВертикальныйРазделительСтраниц();
Счетчик = 0;
ТабДок.Вывести(ОблШапка);
ТабДок.Вывести(ОблНомеров);
КонецЕсли;
Платформа 1С предоставляет специализированные механизмы для сквозных строк и колонок при печати:
ПовторятьПриПечатиСтроки принимает область ячеек результирующего документа, а не макета. Назначать его через присвоение результата метода Вывести() нельзя, так как метод ничего не возвращает.
// Фиксация первых трех строк таблицы в качестве повторяющейся шапки
ТабДок.ПовторятьПриПечатиСтроки = ТабДок.Область(1, , 3, );
ПовторятьПриПечатиКолонки позволяет автоматически печатать левые фиксированные колонки на каждом новом вертикальном листе:
// Фиксация первых двух колонок на каждом листе при горизонтальном переносе
ТабДок.ПовторятьПриПечатиКолонки = ТабДок.Область(, 1, , 2);
Рассмотрим параметры печати, которые напрямую влияют на корректность вывода широких таблиц:
ТабДок.АвтоМасштаб = Истина; или задано ТабДок.ПоШиринеСтраницы = 1;, платформа сожмет все колонки на один лист, проигнорировав ВывестиВертикальныйРазделительСтраниц(). Для корректной разбивки автоподгонку по ширине необходимо отключить.ТабДок.ПорядокПечатиСтраниц, выбирая системное перечисление ПорядокПечатиСтраниц.СлеваНаправоЗатемВниз или ПорядокПечатиСтраниц.СверхуВнизЗатемВправо в зависимости от способа брошюровки документа.