При программном формировании отчетов и печатных форм часто возникает задача визуального оформления группировок: например, при выводе списка товаров по складам требуется не дублировать название склада в каждой строке, а объединить ячейки колонки склада по всей высоте позиций номенклатуры. Поскольку количество строк номенклатуры по каждому складу заранее неизвестно, настроить такое поведение статически в макете невозможно. Разберем основные способы реализации данной задачи, особенности работы платформы 1С и альтернативные варианты построения отчета.
Рассмотрим классический и наиболее распространенный подход. Суть метода заключается в фиксации начального номера строки перед выводом детальных записей группы, последовательном выводе строк и последующем объединении ячеек первой колонки от начала группы до текущей позиции.
Разберем по шагам логику реализации при обходе выборки запроса с группировками:
ИТОГИ ПО).ВысотаТаблицы.Объединить() для полученной области ячеек.Посмотрим на пример программного кода:
// Получаем макет и области
Макет = ПолучитьМакет("Макет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ТабДок.Вывести(ОбластьШапка);
ВыборкаСклад = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаСклад.Следующий() Цикл
// Запоминаем номер строки, с которой начнется вывод текущей группы
НомерПервойСтроки = ТабДок.ВысотаТаблицы + 1;
ВыборкаДетали = ВыборкаСклад.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
ОбластьСтрока.Параметры.Склад = ВыборкаСклад.Склад;
ОбластьСтрока.Параметры.Номенклатура = ВыборкаДетали.Номенклатура;
ОбластьСтрока.Параметры.Количество = ВыборкаДетали.Количество;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
НомерПоследнейСтроки = ТабДок.ВысотаТаблицы;
// Если в группе выведено более одной строки, объединяем ячейки склада
Если НомерПоследнейСтроки > НомерПервойСтроки Тогда
НомерКолонкиСклада = 1;
ОбластьОбъединения = ТабДок.Область(НомерПервойСтроки, НомерКолонкиСклада, НомерПоследнейСтроки, НомерКолонкиСклада);
ОбластьОбъединения.Объединить();
ОбластьОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Верх;
КонецЕсли;
КонецЦикла;
Обратите внимание на свойство ВертикальноеПоложение = ВертикальноеПоложение.Верх. По умолчанию после объединения текст может центрироваться по вертикали, что делает его чтение менее удобным при большом количестве строк.
Проанализируем технические особенности платформы 1С, с которыми можно столкнуться при использовании метода Объединить():
АвтоВысотаСтроки = Истина, платформа не рассчитывает автоматическую высоту по ячейкам, объединенным по вертикали. Если в соседних колонках (например, в наименовании номенклатуры) текст переносится на несколько строк, высота объединенной ячейки может отображаться некорректно.ПроверитьВывод() необходимо проверять массив строк всей группы целиком до вывода в документ.Объединить() может замедлить результирующее время построения отчета.Если необходимо избежать проблем с постраничным переносом и автовысотой строк, разберем альтернативный подход — имитацию объединения ячеек.
Для этого название склада заполняется только в первой строке группы, а для всех последующих строк той же группы ячейка склада выводится пустой. При этом у промежуточных ячеек убирается нижняя граница:
Пока ВыборкаСклад.Следующий() Цикл
ПерваяСтрокаГруппы = Истина;
ВыборкаДетали = ВыборкаСклад.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
Если ПерваяСтрокаГруппы Тогда
ОбластьСтрока.Параметры.Склад = ВыборкаСклад.Склад;
ПерваяСтрокаГруппы = Ложь;
Иначе
ОбластьСтрока.Параметры.Склад = "";
КонецЕсли;
ОбластьСтрока.Параметры.Номенклатура = ВыборкаДетали.Номенклатура;
ОбластьСтрока.Параметры.Количество = ВыборкаДетали.Количество;
ТабДок.Вывести(ОбластьСтрока);
// Убираем нижнюю линию у ячейки склада текущей строки, кроме последней
Если ВыборкаДетали.Количество() > 1 Тогда
ЯчейкаСклада = ТабДок.Область(ТабДок.ВысотаТаблицы, 1, ТабДок.ВысотаТаблицы, 1);
ЯчейкаСклада.ЛинияСнизу = Новый Линия(ТипЛинииТабличногоДокумента.НетЛинии);
КонецЕсли;
КонецЦикла;
КонецЦикла;
В результате таблица визуально выглядит как объединенная, однако каждая строка остается независимой, что корректно обрабатывается механизмом печати платформы.
Если отчет разрабатывается с использованием СКД, писать программный код для объединения ячеек не требуется. Подобное представление настраивается штатными средствами схемы компоновки: