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