При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача «развернуть» данные табличной части. Например, когда для каждого договора в справочнике ДоговорыКонтрагентов нужно вывести информацию о первых трех дополнительных соглашениях не в виде списка под договором, а в виде отдельных колонок: «Соглашение 1», «Соглашение 2», «Соглашение 3». Рассмотрим несколько эффективных способов реализации этой задачи, от простых настроек до программных методов.
Проанализируем самый простой и штатный механизм СКД — создание структуры типа «Таблица». Несмотря на то, что авторы часто ищут более сложные пути, этот метод является наиболее производительным. Разберем его по шагам:
НомерСтроки.Ссылка (или Договор).НомерСтроки.Соглашение) с выражением Максимум(Соглашение).Чтобы ограничить количество выводимых колонок (например, только первые три), добавим в запрос условие:
ГДЕ
ДоговорыКонтрагентовДополнительныеСоглашения.НомерСтроки <= 3
Если нам категорически не подходит структура «Таблица» и мы хотим видеть данные в обычных «Детальных записях», воспользуемся мощью агрегатных функций СКД. Выясним, как это работает через создание массива.
Шаг 1. Создадим ресурс СписокСоглашений с выражением Массив(Соглашение). Важно настроить расчет этого ресурса в разрезе группировки по договору.
Шаг 2. Создадим вычисляемые поля Соглашение1, Соглашение2 и Соглашение3. В выражении для каждого поля пропишем обращение к индексу массива:
СписокСоглашений[0]СписокСоглашений[1]СписокСоглашений[2]Этот метод позволяет жестко зафиксировать колонки в настройках отчета без создания кросс-таблиц. Рассмотрим ситуацию, когда соглашений меньше трех: в этом случае СКД просто выведет пустое значение, не вызывая ошибок обращения к индексу.
Разберем метод, который позволяет подготовить данные еще на уровне SQL-запроса. Это полезно, когда мы хотим максимально упростить настройки самой компоновки. Проанализируем пример использования конструкции ВЫБОР:
ВЫБРАТЬ
Договоры.Ссылка КАК Договор,
МАКСИМУМ(ВЫБОР
КОГДА ТЧ.НомерСтроки = 1
ТОГДА ТЧ.Соглашение
ИНАЧЕ NULL
КОНЕЦ) КАК Соглашение1,
МАКСИМУМ(ВЫБОР
КОГДА ТЧ.НомерСтроки = 2
ТОГДА ТЧ.Соглашение
ИНАЧЕ NULL
КОНЕЦ) КАК Соглашение2,
МАКСИМУМ(ВЫБОР
КОГДА ТЧ.НомерСтроки = 3
ТОГДА ТЧ.Соглашение
ИНАЧЕ NULL
КОНЕЦ) КАК Соглашение3
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов.ДополнительныеСоглашения КАК ТЧ
ПО Договоры.Ссылка = ТЧ.Ссылка
СГРУППИРОВАТЬ ПО
Договоры.Ссылка
В данном примере мы используем ЛЕВОЕ СОЕДИНЕНИЕ и агрегатную функцию МАКСИМУМ. Это позволяет свернуть все строки табличной части обратно в одну строку, распределив значения по именованным колонкам. Важно помнить, что если в табличной части используются неуникальные номера строк (что редко для справочников, но бывает в документах после программных правок), логика может потребовать уточнения.
Посмотрим на более продвинутый способ, который часто используется в типовых конфигурациях 1С. Мы можем описать табличную часть как «Характеристики» объекта прямо в схеме компоновки. Рассмотрим, как это настроить:
СправочникСсылка.ДоговорыКонтрагентов.Ссылка, а идентификатором характеристики — НомерСтроки.После такой настройки в списке доступных полей для договора появятся виртуальные поля, соответствующие строкам табличной части. Это самый элегантный способ, так как он позволяет пользователю самому выбирать в настройках, какие именно «номера строк» он хочет видеть в отчете.
В случаях, когда количество колонок заранее неизвестно или зависит от периода отчета, мы можем прибегнуть к программному изменению схемы в модуле объекта отчета (процедура ПриКомпоновкеРезультата). Рассмотрим алгоритм:
ВыбранныеПоля группировки или детальных записей новые элементы.ВЫБОР КОГДА.Пример кода для добавления поля в СКД:
НовоеПоле = СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
НовоеПоле.Поле = "ДопСоглашение_" + Номер;
НовоеПоле.ПутьКДанным = "ДопСоглашение_" + Номер;
НовоеПоле.Заголовок = "Доп. соглашение №" + Номер;
Проанализировав все способы, можно сделать вывод: для фиксированного количества колонок (как в запросе автора — 3 строки) лучше всего подходит Способ 3 (CASE WHEN в запросе) или Способ 2 (Вычисляемые поля с массивом). Они обеспечивают стабильный результат и простоту сопровождения кода.