Менеджер временных таблиц в СКД позволяет подготовить данные кодом, положить их во временную таблицу и использовать её в запросе набора данных так, будто это обычная таблица базы. Для этого у метода ПроцессорКомпоновкиДанных.Инициализировать() есть шестой параметр — МенеджерВременныхТаблиц. В запросе схемы таблица упоминается по имени без ПОМЕСТИТЬ, а на неё работают соединения и пользовательские отборы.
Прием полезен, когда часть данных нельзя получить одним запросом: иерархия подчинения, рассчитанная рекурсивно, результат обращения к внешнему сервису, сложный расчёт в коде. Ниже — пошаговая схема, код модуля отчёта и подводные камни.
Три способа подать внешние данные в СКД
| Способ | Как работает | Ограничения |
|---|---|---|
| Набор «Объект» | Таблица передаётся во ВнешниеНаборыДанных процессора | Нельзя соединить с таблицами базы в запросе, только связи наборов |
| Параметр запроса | ВЫБРАТЬ ... ИЗ &Таблица внутри набора | Параметр заполняется до компоновки, неудобно в вариантах БСП |
| Менеджер временных таблиц | Таблица создаётся заранее, запрос схемы ссылается на неё по имени | Нужна ручная компоновка в ПриКомпоновкеРезультата |
Третий вариант даёт полноценный SQL: соединения, группировки, отборы в {ГДЕ}. Я использую его, когда внешняя таблица большая и её нужно фильтровать и соединять с регистрами на стороне СУБД, а не в памяти.

Шаг 1. Запрос набора данных ссылается на временную таблицу
В наборе данных «Запрос» пишем текст, где источник — временная таблица, которой в схеме нигде не создаём:
ВЫБРАТЬ
ВЗАИМОСВЯЗИ.Руководитель КАК Руководитель,
ВЗАИМОСВЯЗИ.Сотрудник КАК Сотрудник,
ВЗАИМОСВЯЗИ.ВидРуководителя КАК ВидРуководителя,
ЕСТЬNULL(Кадры.Подразделение, ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)) КАК Подразделение
ИЗ
ВТ_Подчинение КАК ВЗАИМОСВЯЗИ
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_КадровыеДанные КАК Кадры
ПО ВЗАИМОСВЯЗИ.Сотрудник = Кадры.Сотрудник
{ГДЕ
ВЗАИМОСВЯЗИ.Сотрудник.* КАК Подчиненный,
ВЗАИМОСВЯЗИ.Руководитель.*}Имя ВТ_Подчинение должно в точности совпадать с именем таблицы, которую положим в менеджер. Конструктор запроса такой текст разобрать не сможет, поэтому его пишут и правят вручную.
Типы полей
Редактор схемы не знает, что лежит в ВТ_Подчинение, и поля набора получатся без типа. Без типа не работают отборы по реквизитам через точку и выбор значения в отборе. Решения:
- явно привести тип:
ВЫРАЗИТЬ(ВЗАИМОСВЯЗИ.Сотрудник КАК Справочник.Сотрудники) КАК Сотрудник; - использовать
ЕСТЬNULLс пустым значением нужного типа, как в примере выше; - выключить автозаполнение и описать поля набора вручную, указав тип значения.
На проектах предпочитаю ВЫРАЗИТЬ — тип виден прямо в тексте, и следующий разработчик не будет искать его по закладкам схемы.
Шаг 2. Наполняем менеджер временных таблиц
Процедура в модуле объекта отчёта. Таблица значений приходит из расчёта (например, рекурсивного обхода иерархии):
// Помещает таблицу подчинения во временную таблицу ВТ_Подчинение.
// ТаблицаПодчинения - ТаблицаЗначений - колонки Руководитель, Сотрудник, ВидРуководителя
// должны быть типизированы, иначе запрос не примет таблицу в качестве параметра.
Процедура ПоместитьПодчинениеВоВременнуюТаблицу(ТаблицаПодчинения, МенеджерВТ)
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| Т.Руководитель КАК Руководитель,
| Т.Сотрудник КАК Сотрудник,
| Т.ВидРуководителя КАК ВидРуководителя
|ПОМЕСТИТЬ ВТ_Подчинение
|ИЗ
| &ТаблицаПодчинения КАК Т
|
|ИНДЕКСИРОВАТЬ ПО
| Сотрудник";
Запрос.УстановитьПараметр("ТаблицаПодчинения", ТаблицаПодчинения);
Запрос.Выполнить();
КонецПроцедурыКолонки таблицы значений создавайте с ОписаниеТипов: таблицу с нетипизированными колонками платформа в запрос не передаст. ИНДЕКСИРОВАТЬ ПО имеет смысл, если таблица крупная и дальше по ней идёт соединение.
ВТ_КадровыеДанные из примера тоже нужно положить в тот же менеджер — отдельным запросом или в том же пакете.
Шаг 3. Компонуем отчёт вручную
Менеджер передаётся только при ручной инициализации процессора, поэтому в модуле отчёта отключаем стандартную обработку:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
МенеджерВТ = Новый МенеджерВременныхТаблиц;
ТаблицаПодчинения = РассчитатьПодчинение();
ПоместитьПодчинениеВоВременнуюТаблицу(ТаблицаПодчинения, МенеджерВТ);
ПоместитьКадровыеДанныеВоВременнуюТаблицу(МенеджерВТ);
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
Процессор = Новый ПроцессорКомпоновкиДанных;
// Шестой параметр - менеджер с подготовленными временными таблицами
Процессор.Инициализировать(Макет, , ДанныеРасшифровки, Истина, , МенеджерВТ);
ДокументРезультат.Очистить();
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(Процессор);
МенеджерВТ.Закрыть();
КонецПроцедурыПараметры Инициализировать по порядку: макет, внешние наборы данных, данные расшифровки, возможность внешних функций, ограничение получения полей по ссылкам по праву просмотра, менеджер временных таблиц. Пятый оставляем пустым, если нет особых требований.
Пользовательские отборы из настроек отработают как обычно: компоновщик подставит их в запрос, а запрос выполнится в контексте переданного менеджера.
Когда приём оправдан, а когда нет
Подходит:
- данные получаются рекурсией или циклом, а потом их нужно соединить с регистрами;
- внешняя таблица большая, и фильтровать её в памяти дорого;
- нужно переиспользовать одну подготовленную таблицу в нескольких наборах данных схемы.
Не стоит:
- если всё можно получить одним запросом — лишний код без выигрыша;
- если таблица маленькая и не участвует в соединениях — проще набор «Объект».
Типичные ошибки
- «Таблица не найдена». Имя в менеджере и в тексте набора отличается, или временная таблица не создана к моменту компоновки.
- Отчёт не видит менеджер. Забыли
СтандартнаяОбработка = Ложь, и отчёт сформировался штатным механизмом без ваших таблиц. - Поля без типов. Отборы по реквизитам недоступны. Приведите типы через
ВЫРАЗИТЬ. - Параметр-таблица не принимается. Колонки таблицы значений без описания типов.
- Расшифровка не работает. Не передали
ДанныеРасшифровкивВыполнитькомпоновщика макета.
Менеджер временных таблиц превращает данные, собранные кодом, в полноценный источник для запроса СКД, но требует ручной компоновки отчёта.
Подобные отчёты с нестандартными источниками делаю в рамках разработки отчётов на СКД, а если отчёт уже есть и тормозит — смотрю его на аудите производительности.
Итог
- Таблицу готовим кодом и помещаем в
МенеджерВременныхТаблицпод фиксированным именем. - В запросе набора данных ссылаемся на неё по имени, типы полей задаём через
ВЫРАЗИТЬилиЕСТЬNULL. - В
ПриКомпоновкеРезультатаотключаем стандартную обработку и передаём менеджер шестым параметромИнициализировать. - Отборы и соединения работают на стороне СУБД, как с обычными таблицами.




