Как в 1С СКД соединить таблицу самой с собой или развернуть данные по компонентам в колонки?

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

При разработке отчетов в Системе Компоновки Данных (СКД) часто возникает задача горизонтального разворачивания данных. Напримере справочника или регистра с полями Этап, Подэтап и Компонент требуется вывести разные компоненты одной пары этапа и подэтапа в соседних колонках одной строки.

Рассмотри подробно несколько эффективных способов решения этой задачи: разворот данных средствами настройки структуры отчета (кросс-таблица), самосоединение таблицы в запросе и условная агрегация.

Способ 1. Использование структуры «Таблица» с группировкой по колонкам в СКД

Самый простой и гибкий способ получить требуемый вид отчета без усложнения запроса — использование элемента структуры отчета Таблица (кросс-таблица).

Разберем по шагам порядок настройки схемы компоновки данных:

  1. Перейдем на вкладку Настройки в схеме компоновки данных.
  2. В окне структуры отчета добавим элемент Таблица.
  3. В секцию Строки добавим группировку по полям Этап и Подэтап.
  4. В секцию Колонки добавим группировку по полю Компонент.
  5. Для отображения данных на пересечении строк и колонок перейдем на вкладку Ресурсы и зададим выражения ресурсов для выводимых полей, например, Максимум(Компонент), Сумма(Сумма_USD) и Сумма(Сумма_EUR).

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

Способ 2. Самосоединение таблицы в языке запросов 1С

Если плоскую структуру колонок необходимо получить непосредственно в результате выполнения запроса (например, для обработки в коде или выгрузки в другие системы), задействуем левое соединение временной таблицы с самой собой.

Проанализируем ключевое правило: чтобы исключить дублирование записей (декартово произведение), необходимо связать таблицы по полям Этап и Подэтап, а также явно указать целевое значение компонента для каждого соединения.

Рассмотрим пример построения запроса:


ВЫБРАТЬ
	ИсходныеДанные.Этап КАК Этап,
	ИсходныеДанные.Подэтап КАК Подэтап,
	ИсходныеДанные.Компонент КАК Компонент,
	ИсходныеДанные.Сумма_USD КАК Сумма_USD,
	ИсходныеДанные.Сумма_EUR КАК Сумма_EUR
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
	Справочник.СправочникЭтапов КАК ИсходныеДанные
;

ВЫБРАТЬ РАЗЛИЧНЫЕ
	ВТ.Этап КАК Этап,
	ВТ.Подэтап КАК Подэтап
ПОМЕСТИТЬ ВТ_Ключи
ИЗ
	ВТ_ИсходныеДанные КАК ВТ
;

ВЫБРАТЬ
	Ключи.Этап КАК Этап1,
	Ключи.Подэтап КАК Подэтап1,
	Т1.Компонент КАК Компонент1,
	Т1.Сумма_USD КАК Сумма_USD1,
	Ключи.Этап КАК Этап2,
	Ключи.Подэтап КАК Подэтап2,
	Т2.Компонент КАК Компонент2,
	Т2.Сумма_USD КАК Сумма_USD2,
	Ключи.Этап КАК Этап3,
	Ключи.Подэтап КАК Подэтап3,
	Т3.Компонент КАК Компонент3,
	Т3.Сумма_USD КАК Сумма_USD3
ИЗ
	ВТ_Ключи КАК Ключи
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т1
			ПО Ключи.Этап = Т1.Этап
			И Ключи.Подэтап = Т1.Подэтап
			И Т1.Компонент = "A"
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т2
			ПО Ключи.Этап = Т2.Этап
			И Ключи.Подэтап = Т2.Подэтап
			И Т2.Компонент = "B"
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т3
			ПО Ключи.Этап = Т3.Этап
			И Ключи.Подэтап = Т3.Подэтап
			И Т3.Компонент = "C"

Способ 3. Условная агрегация (альтернатива соединению)

Если список компонентов фиксирован и заранее известен (например, «A», «B», «C»), оптимальным решением с точки зрения производительности СУБД будет использование условной агрегации с группировкой по полям Этап и Подэтап.

Разберем пример запроса с условным выбором:


ВЫБРАТЬ
	ИсходныеДанные.Этап КАК Этап,
	ИсходныеДанные.Подэтап КАК Подэтап,
	МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "A" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент1,
	СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "A" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD1,
	МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "B" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент2,
	СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "B" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD2,
	МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "C" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент3,
	СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "C" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD3
ИЗ
	Справочник.СправочникЭтапов КАК ИсходныеДанные
ГРУППИРОВАТЬ ПО
	ИсходныеДанные.Этап,
	ИсходныеДанные.Подэтап

Выбор конкретного метода зависит от требований к отчету: для работы с неизвестным заранее количеством компонентов рекомендуется использовать встроенную кросс-таблицу СКД, а для фиксированного перечня полей — условную агрегацию в запросе.

← На главную