Как вывести длинную таблицу на печать на одном листе, разместив ее части горизонтально в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Постановка задачи: вывод длинной таблицы на одном листе

Представьте, что вы формируете отчет, который содержит большое количество строк. В стандартном режиме вывода на печать платформа 1С автоматически разбивает такие таблицы на несколько страниц по вертикали. Наша задача состоит в том, чтобы вместо вертикального разбиения, части таблицы располагались рядом друг с другом по горизонтали на одном листе. Это позволит сделать отчет более компактным и удобным для восприятия.

Ключевой инструмент: метод Присоединить() объекта ТабличныйДокумент

Для решения поставленной задачи нам потребуется использовать метод Присоединить() объекта ТабличныйДокумент. Этот метод позволяет добавить содержимое одного табличного документа (или его области) к другому табличному документу справа от уже выведенной области.

Давайте разберем, как работает этот метод и какие нюансы следует учитывать при его использовании.

  1. Суть метода Присоединить(): Метод ТабличныйДокумент.Присоединить(ПрисоединяемыйДокумент, ТипПрисоединения) добавляет содержимое ПрисоединяемыйДокумент к текущему табличному документу. По умолчанию, присоединение происходит справа от последней выведенной области, начиная с той же строки, с которой была выведена предыдущая часть. Это критически важное поведение, которое необходимо понимать для корректного построения печатной формы.

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

    • Как отдельные области макета: Если части таблицы относительно небольшие или их структура статична, мы можем определить в макете несколько областей и последовательно выводить их, используя Присоединить().

    • Как отдельные временные табличные документы: Это наиболее гибкий и часто рекомендуемый подход, особенно для динамически формируемых длинных таблиц. Мы создаем два (или более) отдельных объекта ТабличныйДокумент, формируем в каждом из них соответствующую часть таблицы, а затем "склеиваем" эти документы в один итоговый.

Два основных подхода к горизонтальному размещению таблицы

В зависимости от структуры и сложности таблицы, а также от ваших предпочтений, мы можем использовать один из двух основных подходов, которые обсуждались на форуме:

Подход 1: Построчное присоединение

Этот подход подразумевает, что мы формируем печатную форму строка за строкой, поочередно выводя и присоединяя соответствующие части таблицы. То есть, выводим первую строку левой части, затем присоединяем первую строку правой части, затем вторую строку левой части, вторую строку правой части и так далее.

  1. Инициализация: Создаем основной ТабличныйДокумент, в который будем выводить результат.

  2. Цикл по строкам: В основном цикле по строкам данных мы:

    1. Получаем область для вывода левой части текущей строки.

    2. Выводим эту область в основной ТабличныйДокумент с помощью Вывести().

    3. Получаем область для вывода правой части текущей строки.

    4. Присоединяем эту область к основному ТабличныйДокумент с помощью Присоединить(). Важно понимать, что Присоединить() будет присоединять к той же строке, что и предыдущий вызов Вывести() или Присоединить(). Таким образом, части строк будут располагаться рядом.

Особенности: Этот метод требует очень точного управления областями и данными для каждой строки. Может быть сложнее в реализации, если у частей таблицы разное количество строк или разная высота строк. Именно здесь возникает нюанс, описанный в сообщении 7, где Присоединить() лепит к ранее выведенной части, а не к вершине таблицы, если мы пытаемся присоединить области, а не целые документы.

Подход 2: Склеивание двух (или более) табличных документов

Это более гибкий и часто предпочтительный подход, особенно если у вас есть сложные шапки, подвалы или динамические блоки в каждой части таблицы. Мы формируем каждую часть таблицы как полностью независимый ТабличныйДокумент, а затем объединяем их в итоговый ТабличныйДокумент.

  1. Формирование первой части: Создаем новый объект ТабличныйДокумент (например, ТабДокЛеваяЧасть) и полностью формируем в нем первую (левую) часть нашей таблицы со всеми шапками, строками, подвалами и прочим.

  2. Формирование второй части: Аналогично, создаем еще один объект ТабличныйДокумент (например, ТабДокПраваяЧасть) и полностью формируем в нем вторую (правую) часть таблицы.

  3. Объединение в итоговый документ:

    1. Создаем итоговый ТабличныйДокумент (например, ИтоговыйТабДок).

    2. Выводим в него первую сформированную часть: ИтоговыйТабДок.Вывести(ТабДокЛеваяЧасть);

    3. Присоединяем вторую сформированную часть: ИтоговыйТабДок.Присоединить(ТабДокПраваяЧасть);

Важный момент для Подхода 2: Когда мы вызываем ИтоговыйТабДок.Вывести(ТабДокЛеваяЧасть), весь содержимый ТабДокЛеваяЧасть выводится в ИтоговыйТабДок, начиная с его верхней левой позиции. После этого вызов ИтоговыйТабДок.Присоединить(ТабДокПраваяЧасть) приведет к тому, что ТабДокПраваяЧасть будет присоединен справа от ТабДокЛеваяЧасть, начиная с той же строки, с которой был выведен ТабДокЛеваяЧасть. Это гарантирует правильное выравнивание по верхнему краю, как будто мы "склеиваем" два независимых листа бумаги рядом. Этот подход подтверждает решение, описанное в сообщении 8: "Либо вывести в разные табДоки и потом их склеить по горизонтали".

Пример кода для склеивания двух табличных документов

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


// Предполагаем, что у нас есть макет с именем "МакетТаблицы"
// с двумя областями: "Шапка" и "Строка"
// Макет может выглядеть так:
// | Шапка | Колонка 1 | Колонка 2 | ... |
// | Строка | [Колонка1] | [Колонка2] | ... |

// 1. Получаем макет
Макет = ПолучитьМакет("МакетТаблицы");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

// 2. Генерируем тестовые данные
// Представим, что это длинная выборка, которая обычно не помещается на одну страницу.
// Для примера создадим 20 строк данных.
МассивДанных = Новый Массив;
Для Инд = 1 По 20 Цикл 
    СтруктураДанных = Новый Структура;
    Для К = 1 По 5 Цикл // Предположим, у нас 5 колонок в каждой части таблицы
        СтруктураДанных.Вставить("Колонка" + К, "Значение " + Инд + "." + К);
    КонецЦикла;
    МассивДанных.Добавить(СтруктураДанных);
КонецЦикла;

// 3. Определяем точку разделения данных на две части
// Например, делим пополам по количеству строк.
РазделительСтрок = Цел(МассивДанных.Количество() / 2);

// 4. Формируем первую (левую) часть таблицы в отдельном ТабличномДокументе
ТабДокЛеваяЧасть = Новый ТабличныйДокумент;

// Выводим шапку для левой части
ТабДокЛеваяЧасть.Вывести(ОбластьШапка);

// Выводим строки данных для левой части
Для Инд = 0 По РазделительСтрок - 1 Цикл
    ОбластьСтрока.Параметры.Заполнить(МассивДанных[Инд]);
    ТабДокЛеваяЧасть.Вывести(ОбластьСтрока);
КонецЦикла;

// 5. Формируем вторую (правую) часть таблицы в другом ТабличномДокументе
ТабДокПраваяЧасть = Новый ТабличныйДокумент;

// Выводим шапку для правой части
ТабДокПраваяЧасть.Вывести(ОбластьШапка);

// Выводим строки данных для правой части
Для Инд = РазделительСтрок По МассивДанных.Количество() - 1 Цикл
    ОбластьСтрока.Параметры.Заполнить(МассивДанных[Инд]);
    ТабДокПраваяЧасть.Вывести(ОбластьСтрока);
КонецЦикла;

// 6. "Склеиваем" эти две части в итоговый табличный документ
ИтоговыйТабДок = Новый ТабличныйДокумент;

// Выводим первую (левую) часть в итоговый документ.
// Это определит верхнюю позицию, к которой будет присоединяться правая часть.
ИтоговыйТабДок.Вывести(ТабДокЛеваяЧасть);

// Присоединяем правую часть. Она будет добавлена справа от левой части,
// начиная с той же строки, с которой была выведена левая часть.
ИтоговыйТабДок.Присоединить(ТабДокПраваяЧасть);

// 7. Устанавливаем параметры печати для итогового документа
// Рекомендуется альбомная ориентация для широких таблиц
ИтоговыйТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
// Попытка автоматически уместить все по ширине листа
ИтоговыйТабДок.АвтоМасштаб = Истина;

// 8. Показываем результат
ИтоговыйТабДок.Показать();

В этом примере мы сначала формируем две полные, независимые части таблицы в двух разных объектах ТабличныйДокумент. Затем мы выводим первую часть в наш окончательный ИтоговыйТабДок и присоединяем к ней вторую часть. Это обеспечивает правильное горизонтальное расположение и выравнивание по верхнему краю.

Дополнительные настройки печати для оптимизации

Даже после горизонтального размещения частей таблицы, может потребоваться дополнительная настройка параметров печати, чтобы убедиться, что все помещается на одном листе и выглядит наилучшим образом.

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

    ИтоговыйТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
  2. Масштабирование: Если таблица все равно не помещается по ширине, вы можете использовать программное масштабирование. Самый простой способ — это установить свойство АвтоМасштаб = Истина. Это укажет 1С попытаться автоматически подогнать ширину печатной формы под размер листа:

    ИтоговыйТабДок.АвтоМасштаб = Истина;

    Также можно задать произвольный масштаб в процентах через свойства МасштабПечати.

  3. Проверка возможности присоединения: Для более сложных сценариев, когда вы хотите динамически решать, присоединять или выводить новую часть на следующую страницу, существует метод ТабличныйДокумент.ПроверитьПрисоединение(). Он позволяет проверить, изменится ли количество страниц по горизонтали при попытке присоединить новую область, учитывая текущие настройки печати. Это может быть полезно для принятия решения о компоновке в более сложных отчетах.

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

Заключение

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

← На главную