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

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

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

Решение 1: Подготовка данных в запросе для СКД

Этот метод является одним из самых "правильных", поскольку он позволяет использовать всю мощь Системы Компоновки Данных (СКД) для дальнейшей настройки отчета пользователем. Основная идея — заранее рассчитать "координаты" (номер строки и номер колонки) для каждой записи прямо в запросе.

Разберем алгоритм по шагам:

  1. Получаем общее количество записей. Нам нужно знать, сколько всего позиций будет выведено, чтобы рассчитать геометрию нашей будущей таблицы. Это можно сделать отдельным запросом или программно.
  2. Рассчитываем количество строк. Зная общее количество позиций и желаемое число колонок, вычисляем, сколько строк понадобится для вывода. Формула для этого:
    
    КоличествоСтрокВКолонке = Цел(ОбщееКоличествоПозиций / КоличествоКолонок) + ?(ОбщееКоличествоПозиций % КоличествоКолонок = 0, 0, 1);
    
    Эта формула гарантирует, что все позиции поместятся. Например, для 11 позиций в 2 колонки понадобится Цел(11/2) + 1 = 6 строк.
  3. Формируем запрос с вычислением координат. В основном запросе мы должны пронумеровать все записи по порядку и на основе этого номера рассчитать, в какую строку и колонку попадет каждая из них.

Посмотрим на пример запроса. Предположим, у нас есть таблица товаров ТоварыКОтгрузке, а выводить мы хотим в 3 колонки (&КоличествоКолонок = 3).

Сначала поместим данные с автонумерацией во временную таблицу:


ВЫБРАТЬ
    ТоварыКОтгрузке.Номенклатура,
    ТоварыКОтгрузке.Количество,
    КОЛИЧЕСТВО(*) КАК ОбщееКоличество // Получаем общее количество для расчета
ПОМЕСТИТЬ втВсегоЗаписей
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТоварыКОтгрузке
ГДЕ
    ТоварыКОтгрузке.Ссылка = &СсылкаНаДокумент
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТоварыКОтгрузке.Номенклатура,
    ТоварыКОтгрузке.Количество,
    АВТОНОМЕР() КАК ПорядковыйНомер // Нумеруем все записи
ПОМЕСТИТЬ втПронумерованныйСписок
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТоварыКОтгрузке
ГДЕ
    ТоварыКОтгрузке.Ссылка = &СсылкаНаДокумент
УПОРЯДОЧИТЬ ПО
    ТоварыКОтгрузке.НомерСтроки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    втПронумерованныйСписок.Номенклатура,
    втПронумерованныйСписок.Количество,
    // Рассчитываем номер строки и колонки для каждой записи
    (втПронумерованныйСписок.ПорядковыйНомер - 1) % (Цел((втВсегоЗаписей.ОбщееКоличество - 1) / &КоличествоКолонок) + 1) КАК НомерСтроки,
    Цел((втПронумерованныйСписок.ПорядковыйНомер - 1) / (Цел((втВсегоЗаписей.ОбщееКоличество - 1) / &КоличествоКолонок) + 1)) КАК НомерКолонки,
    втПронумерованныйСписок.ПорядковыйНомер
ИЗ
    втПронумерованныйСписок КАК втПронумерованныйСписок,
    втВсегоЗаписей КАК втВсегоЗаписей

Важный момент: в этом запросе используется так называемое вертикальное заполнение — сначала заполняется первая колонка сверху вниз, потом вторая и так далее. Это наиболее распространенный способ.

После того как запрос готов, настраиваем отчет в СКД:

  1. Создаем новый отчет с набором данных-запросом.
  2. В настройках структуры отчета выбираем тип "Таблица".
  3. В область "Строки" перетаскиваем наше вычисляемое поле НомерСтроки.
  4. В область "Колонки" перетаскиваем поле НомерКолонки.
  5. В область пересечения строк и колонок помещаем поля, которые нужно отобразить: Номенклатура, Количество и ПорядковыйНомер (для нумерации позиций).

В результате СКД автоматически сгруппирует данные в виде таблицы с нужным количеством колонок.

Решение 2: Программное формирование Табличного документа

Этот метод дает полный контроль над внешним видом печатной формы, но требует больше ручного кодирования. Он идеален, когда нужно реализовать сложную логику форматирования, которую сложно описать в СКД.

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

  1. Подготовка данных. Выполняем простой запрос и выгружаем результат в ТаблицуЗначений или МассивСтруктур.
  2. Расчет геометрии. Как и в первом способе, вычисляем количество строк, которое потребуется для вывода всех данных. Используем ту же формулу:
    
    ВсегоСтрок = РезультатЗапроса.Количество();
    ЧислоКолонок = 3; // Например
    КоличествоСтрокДляВывода = Цел((ВсегоСтрок - 1) / ЧислоКолонок) + 1;
    
  3. Циклический вывод. Организуем цикл по всем записям из нашего результата запроса. Внутри цикла для каждой записи вычисляем ее координаты в табличном документе и выводим данные в соответствующие ячейки.

Посмотрим на пример кода. Предположим, ТабДок — это наш табличный документ, а ВыборкаДетальныеЗаписи — результат запроса.


// Получаем макет и области
Макет = ПолучитьМакет("НашМакет");
ОбластьСтроки = Макет.ПолучитьОбласть("Строка");

// Рассчитываем геометрию
ВсегоСтрок = ВыборкаДетальныеЗаписи.Количество();
ЧислоКолонок = 3; 
КоличествоСтрокВКолонке = Цел((ВсегоСтрок - 1) / ЧислоКолонок) + 1;

// Организуем вывод
Индекс = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    
    // Вычисляем координаты для текущей записи
    ТекущаяСтрока = Индекс % КоличествоСтрокВКолонке + 1; // +1 т.к. номера строк в ТабДоке с 1
    ТекущаяКолонка = Цел(Индекс / КоличествоСтрокВКолонке);
    
    // Рассчитываем смещение по колонкам в макете
    // Предположим, одна позиция в макете занимает 3 колонки (№, Товар, Кол-во)
    СмещениеКолонки = ТекущаяКолонка * 3; 

    // Заполняем параметры области
    ОбластьСтроки.Параметры.НомерПП = Индекс + 1;
    ОбластьСтроки.Параметры.Товар = ВыборкаДетальныеЗаписи.Номенклатура;
    ОбластьСтроки.Параметры.Количество = ВыборкаДетальныеЗаписи.Количество;
    
    // Выводим область со смещением
    ТабДок.Присоединить(ОбластьСтроки, ТекущаяСтрока, , , СмещениеКолонки);

    Индекс = Индекс + 1;

КонецЦикла;

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

Практические соображения

Выбор конкретного метода зависит от задачи. Если нужна гибкость и возможность донастройки отчета пользователем — выбирайте СКД. Если требуется полный контроль над каждым элементом печатной формы и сложная логика вывода — лучше подойдет программное формирование табличного документа.

← На главную