Как вывести таблицу значений в две колонки на один лист в макете 1С?

Программист 1С v8.3 (Обычные формы) Сфера услуг, туризм и социальный сектор
← На главную

При разработке печатных форм нередко возникает задача компактного размещения данных: например, когда перечень критериев диагностики автомобиля, опросный лист или длинную спецификацию требуется уместить строго на одной странице альбомной ориентации. Для этого список нужно разделить и вывести в две параллельные колонки. Разберем особенности табличных документов 1С, ограничения координатной сетки и конкретные алгоритмы решения этой задачи.

Особенности координатной сетки и ограничения платформы

Прежде чем приступать к коду, выясним причину, по которой классическая верстка в две колонки может вести себя не так, как ожидается. Рассмотрим ключевые нюансы поведения табличного документа 1С:

  1. Единая высота строки по всей ширине макета. В табличном документе физическая строка неделима. Если в левой ячейке расположен короткий текст в одну строку, а в правой колонке параллельная ячейка растягивается из-за длинного текста на две или три строки, увеличится высота всей строки целиком. В результате правая и левая стороны не могут иметь независимую динамическую высоту ячеек без специальных ухищрений.
  2. Ограничения автовысоты и автопереноса. Если для ячеек включены свойства РазмещениеТекста: Переносить и АвтоВысотаСтроки: Истина, итоговая высота рассчитывается механизмом рендеринга и драйвером печати. Это усложняет математический расчет того, сколько именно строк поместится на странице до момента их фактического вывода.
  3. Поведение свойства АвтоМасштаб. Установка параметра АвтоМасштаб = Истина сжимает документ по ширине, но не подгоняет данные по вертикали, если строки выходят за нижний край страницы.

Способ 1. Вывод параллельных областей через методы Вывести() и Присоединить()

Рассмотрим базовый алгоритм, когда высота строк зафиксирована либо тексты критериев стандартизированы и не вызывают сильного расхождения по высоте. В макете создаются две горизонтальные секции или две области: левая колонка и правая колонка.

Разберем по шагам, как строится такой вывод:

  1. Определяем общее количество строк в исходной таблице значений.
  2. Рассчитываем середину списка, чтобы разделить данные пополам между левой и правой колонками.
  3. В цикле выводим строку левой части методом Вывести(), а затем к этой же физической строке добавляем правую часть методом Присоединить().

Посмотрим на пример программной реализации:


ТабДок = Новый ТабличныйДокумент;
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;

Макет = ПолучитьМакет("МакетДиагностики");
ОбластьСлева = Макет.ПолучитьОбласть("СтрокаСлева");
ОбластьСправа = Макет.ПолучитьОбласть("СтрокаСправа");

ВсегоСтрок = ТЗКритерии.Количество();
СтрокВКолонке = Окр(ВсегоСтрок / 2, 0, 1);

Для НомерСтроки = 0 По СтрокВКолонке - 1 Цикл
    // Заполняем и выводим левую колонку
    ДанныеСлева = ТЗКритерии[НомерСтроки];
    ОбластьСлева.Параметры.Заполнить(ДанныеСлева);
    ТабДок.Вывести(ОбластьСлева);
    
    // Проверяем, есть ли парная строка для правой колонки
    ИндексСправа = НомерСтроки + СтрокВКолонке;
    Если ИндексСправа < ВсегоСтрок Тогда
        ДанныеСправа = ТЗКритерии[ИндексСправа];
        ОбластьСправа.Параметры.Заполнить(ДанныеСправа);
        ТабДок.Присоединить(ОбластьСправа);
    КонецЕсли;
КонецЦикла;

Способ 2. Двухпроходный замер емкости страницы через ПроверитьВывод()

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

Проанализируем работу этого алгоритма:

  1. Создаем невидимый вспомогательный табличный документ с теми же параметрами печати (альбомная ориентация, поля).
  2. Выводим в него шапку и последовательно проверяем строки таблицы через метод ПроверитьВывод().
  3. Как только метод возвращает Ложь, фиксируем индекс: первая страница заполнилась, и все последующие строки пойдут в правую колонку.

Посмотрим на пример замера и последующего вывода:


ВспомТабДок = Новый ТабличныйДокумент;
ВспомТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;

МассивПроверки = Новый Массив;
МассивПроверки.Добавить(ОбластьСлева);

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

После вычисления точного числа строк формируется чистовой документ, где строки свыше значения СтрокВЛевойКолонке выводятся в правую область методом Присоединить() параллельно шапке или строкам первой половины.

Способ 3. Гарантированная подгонка масштаба под один лист

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

Разберем по шагам цикл подгонки масштаба:

  1. Отключаем АвтоМасштаб, установив его в значение Ложь.
  2. Устанавливаем начальное свойство МасштабПечати = 100.
  3. В цикле уменьшаем масштаб с небольшим шагом (например, по 2–3%), пока метод КоличествоСтраниц() не вернет значение 1.

Посмотрим на программный код:


ТабДок.АвтоМасштаб = Ложь;
ТабДок.МасштабПечати = 100;

Пока ТабДок.КоличествоСтраниц() > 1 И ТабДок.МасштабПечати > 60 Цикл
    ТабДок.МасштабПечати = ТабДок.МасштабПечати - 2;
КонецЦикла;

Способ 4. Использование фиксированных статических шаблонов

В случаях, когда список критериев диагностики регламентирован и не меняется динамически от документа к документу (либо существует 2–3 стандартных набора под разные типы кузова или модели), целесообразно использовать подход с предварительно сверстанным макетом. При таком подходе вся сетка левой и правой колонок рисуется в макете вручную как единая область. В коде заполняются только параметры автомобиля и отметки механиков, а секция выводится одним методом Вывести(), что полностью исключает проблемы с несовпадением высоты строк.

← На главную