Как передать менеджер временных таблиц в СКД и оптимизировать отчеты в 1С?

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

Долгое время разработчики в экосистеме 1С:Предприятие были вынуждены идти на различные архитектурные ухищрения, чтобы передать предварительно подготовленные в коде данные в систему компоновки данных (СКД). С выходом платформы 8.3.17 сбылась давняя мечта многих специалистов: была реализована возможность прямой передачи Менеджера временных таблиц (МВТ) в СКД. Это новшество кардинально изменило подходы к оптимизации тяжелых отчетов и интеграции сложных расчетных механизмов с подсистемой вывода данных.

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

Как это работает на уровне кода: пошаговая инструкция

Для того чтобы задействовать менеджер временных таблиц в механизме СКД, нам необходимо выполнить три последовательных шага во встроенном языке 1С.

Шаг 1. Создание и наполнение менеджера временных таблиц

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


// Создаем менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременныхТаблиц;

// Инициализируем запрос и связываем его с МВТ
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

// Наполняем временную таблицу данными
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Сотрудники.Ссылка КАК Сотрудник,
    |	Сотрудники.Подразделение КАК Подразделение,
    |	10000 КАК ПлановыйОклад
    |ПОМЕСТИТЬ ВТ_ПредварительныеДанные
    |ИЗ
    |	Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |	Сотрудники.ПометкаУдаления = ЛОЖЬ";

Запрос.Выполнить();

Шаг 2. Настройка схемы компоновки данных

В самой схеме СКД (в конструкторе макета или программно) мы пишем стандартный запрос в наборе данных, который обращается к созданной ранее временной таблице так, будто она уже существует в базе данных:


ВЫБРАТЬ
	вт.Сотрудник КАК Сотрудник,
	вт.Подразделение КАК Подразделение,
	вт.ПлановыйОклад КАК ПлановыйОклад
ИЗ
	ВТ_ПредварительныеДанные КАК вт

Шаг 3. Инициализация процессора компоновки с передачей МВТ

При выводе отчета (обычно в модуле объекта отчета при переопределении процедуры ПриКомпоновкеРезультата или в кодовой части внешней обработки) мы передаем наш МенеджерВременныхТаблиц в качестве шестого параметра метода Инициализировать() процессора компоновки данных.


// Получаем схему и настройки СКД
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

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

// Инициализируем процессор компоновки данных, передавая МенеджерВТ 6-м параметром
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(
    МакетКомпоновки, 
    , // Внешние наборы данных (не требуются при использовании МВТ)
    ДанныеРасшифровки, 
    Истина, // Возможность использования внешних функций
    Ложь,   // Ограничивать получение полей по ссылкам по праву Просмотр
    МенеджерВТ // <- Наш подготовленный Менеджер временных таблиц!
);

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

В чем преимущества МВТ перед внешними наборами данных?

До появления версии 8.3.17 единственным способом передать вовне подготовленную таблицу данных была ее выгрузка в ТаблицуЗначений с последующей передачей через ВнешниеНаборыДанных. Передача через МВТ имеет колоссальные преимущества по сравнению с этим устаревшим подходом:

  1. Производительность СУБД: При передаче внешней таблицы значений СКД вынуждена обрабатывать и соединять эти данные в оперативной памяти сервера приложений 1С. Это приводило к колоссальным нагрузкам на ОЗУ при больших выборках. Использование МВТ позволяет СУБД производить полноценные операции JOIN (соединения) непосредственно на уровне базы данных, используя системные оптимизаторы СУБД и индексы временных таблиц.
  2. Простота проектирования схемы: Для внешнего набора данных типа «Объект» разработчику приходилось скрупулезно вручную описывать каждое поле, его тип и роль в конфигураторе 1С. В случае с МВТ достаточно написать простой SQL-подобный запрос, и СКД автоматически определит структуру полей.

Важная проблема: типизация полей во временных таблицах

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

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

Посмотрим на пример правильного оформления запроса в СКД, использующего типизацию:


ВЫБРАТЬ
	ВЫРАЗИТЬ(вт.Сотрудник КАК Справочник.Сотрудники) КАК Сотрудник,
	ВЫРАЗИТЬ(вт.Подразделение КАК Справочник.Подразделения) КАК Подразделение,
	ЕСТЬNULL(вт.ПлановыйОклад, 0) КАК ПлановыйОклад
ИЗ
	ВТ_ПредварительныеДанные КАК вт

Тонкости работы и ограничение «Одностороннего движения»

Разберем неочевидные архитектурные особенности работы платформы с передаваемыми менеджерами:

1. Ошибка «Таблица не найдена» при вызове Компоновщика макета

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

2. Эффект «Одностороннего движения» данных

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

Архитектурные споры: упрощение или усложнение кода?

Внедрение этой возможности вызвало бурную дискуссию в сообществе разработчиков 1С. Рассмотрим две полярные точки зрения, высказанные практиками:

С одной стороны: Это долгожданное спасение для оптимизации. Крупные типовые конфигурации (такие как ЗУП 3.1 или ERP 2.5) начали активно использовать этот паттерн. Например, при расчете кадровых данных или расчете себестоимости общие модули конфигурации один раз подготавливают сложнейшие срезы данных в МВТ (используя пакетные запросы встроенного языка), а затем этот МВТ передается в десятки различных отчетов СКД. Это кардинально снизило дублирование сложного кода запросов и нагрузку на серверы.

С другой стороны (критика): Использование МВТ усложняет визуальную отладку и доработку отчетов «на местах». Если раньше разработчик мог открыть схему СКД в конструкторе и сразу увидеть целостный запрос, то теперь запрос становится «кусочным». Часть таблиц создается где-то в недрах общего модуля, и если обновить структуру временной таблицы в коде, отчет может неожиданно «отвалиться» в совершенно другом месте (например, из-за изменения состава колонок), что усложняет поддержку и разбор чужого оверинжинирингового кода.

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

← На главную