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

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

Три способа присоединить данные в отчёте СКД

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

СпособКакКогда выбирать
Соединение в запросеЛЕВОЕ СОЕДИНЕНИЕ в тексте одного набораОбе таблицы в одной базе — выбор по умолчанию
Связь по полямВторой набор целиком + связь «Автор = Пользователь»Второй набор — таблица значений или внешний источник, его объём невелик
Связь с параметромВторой набор фильтруется параметром, значения приходят из источникаПриёмник большой, нужна выборка только по встречающимся значениям

Вариант 1. Соединение в одном наборе

Запрос 1С
ВЫБРАТЬ
	Документы.Ссылка КАК Документ,
	Документы.Автор КАК Автор,
	Сведения.Подразделение КАК Подразделение,
	Сведения.Должность КАК Должность
ИЗ
	Документ.ЗаказКлиента КАК Документы
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОПользователях КАК Сведения
		ПО Документы.Автор = Сведения.Пользователь

Имена регистра и реквизитов условные — подставьте свои. Такой запрос СУБД выполнит одним планом, с использованием индексов. Если оба источника в одной базе, начинать нужно с этого варианта.

Связь наборов данных СКД по полям

Второй набор описывается отдельно, например так:

Запрос 1С
ВЫБРАТЬ
	Сведения.Пользователь КАК Пользователь,
	Сведения.Подразделение КАК Подразделение,
	Сведения.Должность КАК Должность
ИЗ
	РегистрСведений.СведенияОПользователях КАК Сведения

На вкладке «Связи наборов данных» добавляется строка:

КолонкаЗначение
Источник связиДокументы (основной набор)
Приёмник связиСотрудники
Выражение источникАвтор
Выражение приёмникПользователь
Обязательнаяснят — левое соединение
Связи наборов данных СКД: основной набор соединяется с дополнительным по общему полю
Связи наборов данных СКД: основной набор соединяется с дополнительным по общему полю

Что важно помнить о связях:

  • Направление имеет значение. Сохраняются все строки источника; строки приёмника без пары отбрасываются.
  • Флажок «Обязательная» превращает связь во что-то близкое к внутреннему соединению: строки источника без пары в приёмнике не выводятся.
  • Связь работает только если поля из приёмника выбраны в настройках. Если пользователь не вывел ни одного поля второго набора, платформа может вообще не выполнять его запрос — это полезная оптимизация, но удивляет при отладке.
  • Наборы без связи выводятся как независимые: СКД не соединяет их «крест-накрест», а пытается вывести общие поля вместе. Если поля наборов пересекаются по именам, получаются неочевидные результаты — давайте полям разные имена или связывайте наборы явно.

Связь с параметром: выбираем только нужное

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

Запрос 1С
ВЫБРАТЬ
	Сведения.Пользователь КАК Пользователь,
	Сведения.Подразделение КАК Подразделение,
	Сведения.Должность КАК Должность
ИЗ
	РегистрСведений.СведенияОПользователях КАК Сведения
ГДЕ
	Сведения.Пользователь В (&Пользователь)

В строке связи дополнительно указывается Параметр — Пользователь. Тогда платформа передаёт значения поля источника в параметр запроса приёмника.

Ключевая настройка — флажок «Список параметров»:

  • включён — в параметр передаётся список всех значений источника, и запрос приёмника выполняется один раз с условием В (&Пользователь);
  • выключен — запрос может выполняться отдельно для каждого значения, и на больших выборках отчёт замедляется в разы.

На проектах я почти всегда включаю «Список параметров» и пишу условие через В. Вариант с параметром без списка оправдан разве что для очень маленьких источников.

Связь с таблицей значений или внешним источником

Самый частый реальный сценарий связи — когда один из наборов не запрос, а набор-объект: таблица, загруженная из Excel, ответ HTTP-сервиса, результат расчёта. Соединить такую таблицу с данными базы в запросе нельзя без временной таблицы, а в СКД это делается одной строкой связи. Таблица передаётся в процессор компоновки структурой внешних наборов по имени объекта.

Несколько схем компоновки в одном отчёте

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

Несколько схем компоновки в одном отчёте: пользователь выбирает схему, отчёт перестраивает настройки
Несколько схем компоновки в одном отчёте: пользователь выбирает схему, отчёт перестраивает настройки

Заготовка отчёта

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

Код формы

1С
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	АвтоЗаголовок = Ложь;
	ЗаполнитьСписокСхем();

	Если СписокСхем.Количество() = 0 Тогда
		Отказ = Истина;
		Возврат;
	КонецЕсли;

	УстановитьСхему(СписокСхем[0].Значение, СписокСхем[0].Представление);

КонецПроцедуры

&НаСервере
Процедура ЗаполнитьСписокСхем()

	СписокСхем.Очистить();
	МетаданныеОтчета = РеквизитФормыВЗначение("Отчет").Метаданные();
	Для Каждого Макет Из МетаданныеОтчета.Макеты Цикл
		// Берём только схемы, чтобы не попали печатные макеты и двоичные данные
		Если Макет.ТипМакета = Метаданные.СвойстваОбъектов.ТипМакета.СхемаКомпоновкиДанных Тогда
			СписокСхем.Добавить(Макет.Имя, Макет.Синоним);
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ВыбратьСхему(Команда)

	Оповещение = Новый ОписаниеОповещения("ВыбратьСхемуЗавершение", ЭтотОбъект);
	ПоказатьВыборИзСписка(Оповещение, СписокСхем, Элементы.ФормаВыбратьСхему);

КонецПроцедуры

&НаКлиенте
Процедура ВыбратьСхемуЗавершение(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт

	Если ВыбранныйЭлемент <> Неопределено Тогда
		УстановитьСхему(ВыбранныйЭлемент.Значение, ВыбранныйЭлемент.Представление);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура УстановитьСхему(ИмяСхемы, Представление)

	Заголовок = "Отчёт: " + Представление;
	Отчет.ИмяСхемы = ИмяСхемы;

	Схема = РеквизитФормыВЗначение("Отчет").ПолучитьМакет(ИмяСхемы);
	// Компоновщик настроек — реквизит формы, поэтому схему передаём через временное хранилище
	АдресСхемы = ПоместитьВоВременноеХранилище(Схема, УникальныйИдентификатор);

	Отчет.КомпоновщикНастроек.Инициализировать(
		Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы));
	Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);

КонецПроцедуры

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

Модуль объекта отчёта

1С
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

	Схема = ПолучитьМакет(ИмяСхемы);
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);

	Процессор = Новый ПроцессорКомпоновкиДанных;
	Процессор.Инициализировать(Макет, , ДанныеРасшифровки, Истина);

	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
	ПроцессорВывода.Вывести(Процессор);

КонецПроцедуры

Если расшифровка должна работать, при её обработке на форме тоже используйте текущую схему: стандартная расшифровка опирается на основную схему отчёта, которой здесь нет.

Типичные ошибки

  • Связь по полю, которого нет в приёмнике. В выражении приёмника указывается путь к данным поля приёмника, а не имя таблицы или реквизита в запросе.
  • Медленный отчёт со связью через параметр. Не включён «Список параметров» или в запросе условие =, а не В.
  • Дубли строк. В приёмнике несколько записей на одно значение связи (например, история сведений) — оставьте срез последних или агрегируйте приёмник.
  • После смены схемы «пропали» настройки. Так и задумано: компоновщик инициализирован новой схемой. Если нужно запоминать настройки по каждой схеме, храните их отдельно, например в хранилище настроек с ключом по имени схемы.
  • Ошибка «Не установлено значение параметра». Параметр приёмника используется не только в связи, но и в отборах — задайте ему значение по умолчанию или ограничьте использование.
Сначала соединение в запросе, связь наборов — когда источники разные, несколько схем — когда отчёты по сути разные. Так отчёт остаётся быстрым и понятным.

Если отчёт со связями наборов строится минутами, причина почти всегда в плане запросов и в том, как платформа выполняет приёмник, — это разбирается на аудите производительности 1С. Сами отчёты под задачи бизнеса я делаю в рамках услуги отчёты на СКД.

Итог

  • Связь наборов данных — левое соединение источника и приёмника по выражениям; «Обязательная» убирает строки без пары.
  • Для таблиц одной базы выгоднее соединение в запросе; связь нужна для таблиц значений и внешних источников.
  • В связи с параметром включайте «Список параметров» и пишите условие В (&Параметр).
  • Несколько схем в отчёте: макеты-схемы, реквизит с именем активной схемы, переинициализация компоновщика через временное хранилище и своя ПриКомпоновкеРезультата.