Как правильно использовать внешние временные таблицы в запросах СКД?

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

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

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

Проблема: Ошибка генерации макета

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


МВТ = Новый МенеджерВременныхТаблиц;
ТекстЗапроса = "ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Номенклатура ИЗ Справочник.Номенклатура";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.МенеджерВременныхТаблиц = МВТ;
Запрос.Выполнить();

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

// Ошибка возникает здесь:
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки); 

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

Решение 1: Отключение автозаполнения

Проанализируем работу ГенератораМакета. Основной виновник ошибки — установленный флаг «Автозаполнение» в наборе данных-запросе. Когда этот флаг включен, СКД пытается самостоятельно определить структуру полей, обращаясь к метаданным БД. ВТ не является частью метаданных, поэтому проверка проваливается.

Для исправления ситуации выполним следующие шаги:

  1. Откроем схему компоновки данных.
  2. Перейдем на закладку «Наборы данных».
  3. Выберем наш набор данных-запрос.
  4. Снимем галочку «Автозаполнение».
  5. Вручную добавим все необходимые поля в таблицу «Поля». Важно: имена полей в схеме должны строго соответствовать именам колонок во временной таблице.

После этого КомпоновщикМакета перестанет пытаться «умно» анализировать текст запроса и успешно сгенерирует макет, основываясь на вашем ручном описании полей.

Решение 2: Явная типизация полей в запросе

Даже если мы отключили автозаполнение, СКД критически важна информация о типах данных, особенно если вы планируете использовать эти поля для группировок, отборов или связей. Рассмотрим ситуацию, когда в ВТ хранятся ссылки. Чтобы избежать проблем с определением доступных полей, в тексте запроса СКД рекомендуется использовать оператор ВЫРАЗИТЬ.

Посмотрим на пример правильного запроса в СКД:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ВТ.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
    ВТ.Количество КАК Количество
ИЗ
    ВТ_Данные КАК ВТ

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

Решение 3: Правильная инициализация процессора компоновки

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


// 1. Подготовка данных в МВТ
МВТ = Новый МенеджерВременныхТаблиц;
ЗапросПодготовки = Новый Запрос("ВЫБРАТЬ Ссылка, Цена ПОМЕСТИТЬ ВТ_Цены ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних");
ЗапросПодготовки.МенеджерВременныхТаблиц = МВТ;
ЗапросПодготовки.Выполнить();

// 2. Получение макета (здесь автозаполнение в схеме уже должно быть выключено!)
Схема = ЭтотОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = Схема.НастройкиПоУмолчанию;
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;

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

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

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

Важные нюансы и советы

Рассмотрим дополнительные моменты, которые помогут избежать ошибок при работе с этой технологией:

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

← На главную