Как сделать горизонтальную группировку строк и объединить ячейки в СКД 1С

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

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

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

---

Шаг 1. Настройка горизонтального расположения группировок (в отдельные колонки)

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

  1. Откроем схему компоновки данных нашего отчета и перейдем на вкладку «Настройки».
  2. В структуре отчета создадим иерархию подчиненных группировок. Например, корневой группировкой сделаем Организация, внутрь нее добавим подчиненную группировку Склад, а внутрь склада — Ответственный.
  3. Выделим корневой элемент структуры (или весь отчет в целом) и перейдем на вкладку «Другие настройки» (в правом нижнем окне конфигуратора).
  4. Найдем параметр «Расположение полей группировок». По умолчанию там установлено значение Вместе, из-за чего все поля выводятся в одной первой колонке со сдвигом вправо.
  5. Изменим это значение на «Отдельно и только в итогах» (или просто Отдельно).

Проанализируем разницу между этими режимами:

Выбрав вариант «Отдельно и только в итогах», мы получим отчет, где группировки распределены по колонкам горизонтально, а значения не дублируются бесконечно вниз. Но здесь возникает визуальная проблема: ячейки родительских группировок выглядят разорванными, и у пользователя не создается ощущения «единой» группы. Рассмотрим, как решить эту проблему.

---

Шаг 2. Визуальное «псевдообъединение» ячеек через условное оформление

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

Разберем алгоритм настройки этого эффекта:

  1. В схеме СКД перейдем на вкладку «Вычисляемые поля» и добавим вспомогательное поле, например, ИндексСтроки. В поле «Выражение» укажем функцию нумерации: СистемныеПоля.НомерПоПорядкуВГруппе. Это поле будет автоматически рассчитывать порядковый номер подчиненной строки внутри каждого родителя.
  2. Перейдем на вкладку «Настройки», откроем вкладку «Условное оформление» и добавим новое правило.
  3. В параметрах оформления найдем свойство «Границы» (или «Оформление границ»). Нам необходимо отключить верхнюю и нижнюю границы (задать для них тип линии «Нет линии» или установить цвет, совпадающий с цветом фона). Также можно очистить текст дублирующихся строк.
  4. В условиях оформления укажем: ИндексСтроки > 1.
  5. В оформляемых полях выберем поле нашей родительской группировки (например, Организация).

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

---

Шаг 3. Профессиональное программное объединение ячеек (постобработка)

Если перед нами стоит задача сделать настоящее, физическое объединение ячеек по вертикали (чтобы при выгрузке в Excel или печати области объединялись методом Объединить()), нам потребуется написать небольшой код постобработки в модуле отчета.

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

Откроем модуль объекта нашего отчета и переопределим стандартное событие ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отменяем стандартный автоматический вывод отчета
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем стандартный процесс компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    // Запускаем процедуру постобработки для объединения ячеек
    ОбъединитьГруппировкиПоВертикали(ДокументРезультат);
    
КонецПроцедуры

Теперь напишем саму процедуру постобработки табличного документа. Алгоритм будет обходить указанные колонки сверху вниз, находить одинаковые значения в смежных строках и объединять их:


Процедура ОбъединитьГруппировкиПоВертикали(ТабДок)
    
    ВысотаТаблицы = ТабДок.ВысотаТаблицы;
    
    // Предположим, что наши группировки выводятся в колонках 1 и 2
    ГраницаКолонок = 2; 
    
    Для НомерКолонки = 1 По ГраницаКолонок Цикл
        
        СтартоваяСтрока = 0;
        ПредыдущееЗначение = "";
        
        Для НомерСтроки = 1 По ВысотаТаблицы Цикл
            
            ТекущаяОбласть = ТабДок.Область(НомерСтроки, НомерКолонки);
            ТекущееЗначение = ТекущаяОбласть.Текст;
            
            // Пропускаем пустые строки и строки шапки/подвала, если они не содержат данных
            Если ПустаяСтрока(ТекущееЗначение) Тогда
                Если СтартоваяСтрока > 0 И (НомерСтроки - СтартоваяСтрока) > 1 Тогда
                    // Объединяем накопленный диапазон перед пустой строкой
                    ОбластьДляОбъединения = ТабДок.Область(СтартоваяСтрока, НомерКолонки, НомерСтроки - 1, НомерКолонки);
                    ОбластьДляОбъединения.Объединить();
                    ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
                КонецЕсли;
                СтартоваяСтрока = 0;
                ПредыдущееЗначение = "";
                Продолжить;
            КонецЕсли;
            
            Если ТекущееЗначение = ПредыдущееЗначение Тогда
                // Если значение совпадает с предыдущим, фиксируем начало диапазона
                Если СтартоваяСтрока = 0 Тогда
                    СтартоваяСтрока = НомерСтроки - 1;
                КонецЕсли;
            Иначе
                // Значение изменилось, пора объединить предыдущую группу строк
                Если СтартоваяСтрока > 0 Тогда
                    ОбластьДляОбъединения = ТабДок.Область(СтартоваяСтрока, НомерКолонки, НомерСтроки - 1, НомерКолонки);
                    ОбластьДляОбъединения.Объединить();
                    // Выравниваем текст по центру объединенной ячейки
                    ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
                КонецЕсли;
                
                // Сбрасываем маркер на текущую строку
                СтартоваяСтрока = 0;
                ПредыдущееЗначение = ТекущееЗначение;
            EndЕсли;
            
        КонецЦикла;
        
        // Не забываем объединить оставшийся «хвост» в конце таблицы
        Если СтартоваяСтрока > 0 Тогда
            ОбластьДляОбъединения = ТабДок.Область(СтартоваяСтрока, НомерКолонки, ВысотаТаблицы, НомерКолонки);
            ОбластьДляОбъединения.Объединить();
            ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

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

---

Шаг 4. Использование собственных макетов группировок

Еще один продвинутый способ создания горизонтальной структуры — это использование вкладки «Макеты» в схеме СКД. Этот вариант подходит, если структура вашего отчета статична и пользователи не будут динамически отключать или менять местами группировки в режиме «1С:Предприятие».

Рассмотрим, как настроить такой макет:

  1. Перейдем на вкладку «Макеты» нашей схемы компоновки данных.
  2. Нажмем кнопку «Добавить макет группировки». В появившемся окне укажем имя группировки (например, Организация) и тип макета (например, Заголовок или Подвал).
  3. В сетке табличного документа макета выделим нужную область ячеек по вертикали и вызовем стандартное контекстное меню «Объединить».
  4. Назначим объединенной ячейке параметр (например, ПараметрОрганизация) и свяжем его в свойствах макета с полем схемы Организация.

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

---

Резюме и рекомендации

Мы проанализировали три основных подхода к реализации горизонтальных группировок с объединенными ячейками. Подведем итоги, в каких ситуациях какой метод использовать наиболее эффективно:

← На главную