В процессе работы часто возникает задача компактного размещения информации на печатной форме. Например, нужно сформировать прайс-лист или маршрутный лист для водителя, где номенклатура с количеством выводится не в одну длинную колонку, а в две, три или более, чтобы сэкономить бумагу и сделать документ более удобным для чтения. Рассмотрим несколько способов решения этой задачи в 1С без использования сложных настроек макета.
Этот метод является одним из самых "правильных", поскольку он позволяет использовать всю мощь Системы Компоновки Данных (СКД) для дальнейшей настройки отчета пользователем. Основная идея — заранее рассчитать "координаты" (номер строки и номер колонки) для каждой записи прямо в запросе.
Разберем алгоритм по шагам:
КоличествоСтрокВКолонке = Цел(ОбщееКоличествоПозиций / КоличествоКолонок) + ?(ОбщееКоличествоПозиций % КоличествоКолонок = 0, 0, 1);
Цел(11/2) + 1 = 6 строк.
Посмотрим на пример запроса. Предположим, у нас есть таблица товаров ТоварыКОтгрузке, а выводить мы хотим в 3 колонки (&КоличествоКолонок = 3).
Сначала поместим данные с автонумерацией во временную таблицу:
ВЫБРАТЬ
ТоварыКОтгрузке.Номенклатура,
ТоварыКОтгрузке.Количество,
КОЛИЧЕСТВО(*) КАК ОбщееКоличество // Получаем общее количество для расчета
ПОМЕСТИТЬ втВсегоЗаписей
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК ТоварыКОтгрузке
ГДЕ
ТоварыКОтгрузке.Ссылка = &СсылкаНаДокумент
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТоварыКОтгрузке.Номенклатура,
ТоварыКОтгрузке.Количество,
АВТОНОМЕР() КАК ПорядковыйНомер // Нумеруем все записи
ПОМЕСТИТЬ втПронумерованныйСписок
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК ТоварыКОтгрузке
ГДЕ
ТоварыКОтгрузке.Ссылка = &СсылкаНаДокумент
УПОРЯДОЧИТЬ ПО
ТоварыКОтгрузке.НомерСтроки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
втПронумерованныйСписок.Номенклатура,
втПронумерованныйСписок.Количество,
// Рассчитываем номер строки и колонки для каждой записи
(втПронумерованныйСписок.ПорядковыйНомер - 1) % (Цел((втВсегоЗаписей.ОбщееКоличество - 1) / &КоличествоКолонок) + 1) КАК НомерСтроки,
Цел((втПронумерованныйСписок.ПорядковыйНомер - 1) / (Цел((втВсегоЗаписей.ОбщееКоличество - 1) / &КоличествоКолонок) + 1)) КАК НомерКолонки,
втПронумерованныйСписок.ПорядковыйНомер
ИЗ
втПронумерованныйСписок КАК втПронумерованныйСписок,
втВсегоЗаписей КАК втВсегоЗаписей
Важный момент: в этом запросе используется так называемое вертикальное заполнение — сначала заполняется первая колонка сверху вниз, потом вторая и так далее. Это наиболее распространенный способ.
После того как запрос готов, настраиваем отчет в СКД:
НомерСтроки.НомерКолонки.Номенклатура, Количество и ПорядковыйНомер (для нумерации позиций).В результате СКД автоматически сгруппирует данные в виде таблицы с нужным количеством колонок.
Этот метод дает полный контроль над внешним видом печатной формы, но требует больше ручного кодирования. Он идеален, когда нужно реализовать сложную логику форматирования, которую сложно описать в СКД.
Проанализируем алгоритм:
ТаблицуЗначений или МассивСтруктур.
ВсегоСтрок = РезультатЗапроса.Количество();
ЧислоКолонок = 3; // Например
КоличествоСтрокДляВывода = Цел((ВсегоСтрок - 1) / ЧислоКолонок) + 1;
Посмотрим на пример кода. Предположим, ТабДок — это наш табличный документ, а ВыборкаДетальныеЗаписи — результат запроса.
// Получаем макет и области
Макет = ПолучитьМакет("НашМакет");
ОбластьСтроки = Макет.ПолучитьОбласть("Строка");
// Рассчитываем геометрию
ВсегоСтрок = ВыборкаДетальныеЗаписи.Количество();
ЧислоКолонок = 3;
КоличествоСтрокВКолонке = Цел((ВсегоСтрок - 1) / ЧислоКолонок) + 1;
// Организуем вывод
Индекс = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Вычисляем координаты для текущей записи
ТекущаяСтрока = Индекс % КоличествоСтрокВКолонке + 1; // +1 т.к. номера строк в ТабДоке с 1
ТекущаяКолонка = Цел(Индекс / КоличествоСтрокВКолонке);
// Рассчитываем смещение по колонкам в макете
// Предположим, одна позиция в макете занимает 3 колонки (№, Товар, Кол-во)
СмещениеКолонки = ТекущаяКолонка * 3;
// Заполняем параметры области
ОбластьСтроки.Параметры.НомерПП = Индекс + 1;
ОбластьСтроки.Параметры.Товар = ВыборкаДетальныеЗаписи.Номенклатура;
ОбластьСтроки.Параметры.Количество = ВыборкаДетальныеЗаписи.Количество;
// Выводим область со смещением
ТабДок.Присоединить(ОбластьСтроки, ТекущаяСтрока, , , СмещениеКолонки);
Индекс = Индекс + 1;
КонецЦикла;
Важный совет: Вместо вывода отдельных ячеек (ТабДок.Область(R,C).Текст = ...) лучше использовать заранее подготовленные в макете области (ОбластьМакета). Это позволяет легко управлять шрифтами, границами и форматами. Метод Присоединить() с указанием смещения идеально подходит для этой задачи.
ТабДок.Область(НомерСтроки, ,НомерСтроки,).ВысотаСтроки = ....Выбор конкретного метода зависит от задачи. Если нужна гибкость и возможность донастройки отчета пользователем — выбирайте СКД. Если требуется полный контроль над каждым элементом печатной формы и сложная логика вывода — лучше подойдет программное формирование табличного документа.