Язык запросов 1С

Менеджер временных таблиц и пакет запросов в 1С 8.3: ИНДЕКСИРОВАТЬ ПО и отладка ВТ

Коротко

Если временная таблица создаётся и читается внутри одного пакетного запроса (части разделены ;), создавать МенеджерВременныхТаблиц не нужно. Объект Новый МенеджерВременныхТаблиц обязателен, когда временную таблицу через ПОМЕСТИТЬ ВТ нужно сохранить между несколькими вызовами Запрос.Выполнить(), передать в другой объект Запрос или подать на вход ПроцессорКомпоновкиДанных.Инициализировать(...).

Для ускорения соединений и отборов по крупным ВТ добавляйте ИНДЕКСИРОВАТЬ ПО в запрос с ПОМЕСТИТЬ, а после использования освобождайте ресурсы СУБД оператором УНИЧТОЖИТЬ ВТ или методом МенеджерВТ.Закрыть(). Чтобы посмотреть строки ВТ в отладчике 1С 8.3, вычислите выражение МенеджерВТ.Таблицы.Найти("ИмяВТ").ПолучитьДанные().Выгрузить() либо вызовите Запрос.ВыполнитьПакетСПромежуточнымиДанными().

Зачем нужен МенеджерВременныхТаблиц в запросе 1С 8.3

В платформе 1С:Предприятие 8.3 временная таблица (ВТ) не существует сама по себе — она привязана либо к контексту текущего исполнения одного пакета, либо к экземпляру объекта МенеджерВременныхТаблиц. Если в свойстве Запрос.МенеджерВременныхТаблиц стоит значение по умолчанию Неопределено, все созданные в пакете временные таблицы автоматически уничтожаются сразу после завершения вызова Запрос.Выполнить().

Явное создание МенеджерВТ = Новый МенеджерВременныхТаблиц решает три практические задачи:

  • Передача временных таблиц между разными объектами Запрос. Например, общая процедура модуля формирует базовую выборку документов или цен во временную таблицу ВТ_Товары, а несколько последующих запросов в разных функциях обращаются к ИЗ ВТ_Товары без повторного чтения регистров.
  • Пошаговая сборка данных и загрузка ТаблицаЗначений. Когда нужно сначала поместить типизированную таблицу значений в СУБД отдельным вызовом, а затем в зависимости от логики модуля выполнить один из расчётных запросов.
  • Использование в качестве контейнера внешних таблиц для СКД. Готовый менеджер с рассчитанными в коде временными таблицами передаётся шестым параметром в метод ПроцессорКомпоновкиДанных.Инициализировать(...).
МенеджерВТ = Новый МенеджерВременныхТаблиц;

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

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

// Освобождаем временные таблицы в СУБД сразу после использования
МенеджерВТ.Закрыть();
МенеджерВременныхТаблиц
Новый МенеджерВременныхТаблицконструктор без параметров; создаёт хранилище ВТ
ТаблицыВременныеТаблицыЗапроса — коллекция созданных таблиц (только чтение)
Закрыть()удаляет все ВТ в менеджере и запрещает дальнейшую работу с объектом
→ МенеджерВременныхТаблиц

Внутри одного экземпляра МенеджерВременныхТаблиц каждая таблица идентифицируется своим именем. Временные таблицы живут до вызова МенеджерВТ.Закрыть(), явного оператора УНИЧТОЖИТЬ в запросе или уничтожения переменной МенеджерВТ сборщиком мусора по выходу из процедуры. Кроме того, если временная таблица была создана внутри транзакции, при откате транзакции (ОтменитьТранзакцию()) платформа автоматически удалит её из менеджера.

Передача МенеджерВременныхТаблиц в ПроцессорКомпоновкиДанных

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

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

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

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

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

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

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

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

    МенеджерВТ.Закрыть();

КонецПроцедуры
ПроцессорКомпоновкиДанных.Инициализировать
МакетМакетКомпоновкиДанных
ВнешниеНаборыДанныхСтруктура внешних объектов
ДанныеРасшифровкиДанныеРасшифровкиКомпоновкиДанных
ВозможностьИспользованияВнешнихФункцийБулево (по умолчанию Ложь)
ОграничиватьПолучениеПолейПоСсылкамПоПравуПросмотрБулево (по умолчанию Истина)
МенеджерВременныхТаблицМенеджерВременныхТаблиц для запросов СКД
→ (процедура)

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

Пакет запросов в 1С: Выполнить, ВыполнитьПакет и ВыполнитьПакетСПромежуточнымиДанными

Пакет запросов — это последовательность самостоятельных запросов в одном свойстве Запрос.Текст, разделённых точкой с запятой (;). Платформа выполняет пакеты строго сверху вниз: каждый шаг пакета отправляется в СУБД отдельным SQL-запросом и может обращаться к временным таблицам, созданным в предыдущих шагах.

У объекта Запрос есть три метода запуска пакета, которые по-разному возвращают результаты шагов ПОМЕСТИТЬ ВТ и УНИЧТОЖИТЬ ВТ:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Товары.Ссылка КАК Номенклатура
    |ПОМЕСТИТЬ ВТ_Номенклатура
    |ИЗ
    |   Справочник.Номенклатура КАК Товары
    |ГДЕ
    |   НЕ Товары.ПометкаУдаления
    |;
    |ВЫБРАТЬ
    |   ВТ_Номенклатура.Номенклатура КАК Номенклатура,
    |   Цены.Цена КАК Цена
    |ИЗ
    |   ВТ_Номенклатура КАК ВТ_Номенклатура
    |   ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата) КАК Цены
    |   ПО ВТ_Номенклатура.Номенклатура = Цены.Номенклатура
    |;
    |УНИЧТОЖИТЬ ВТ_Номенклатура";

Запрос.УстановитьПараметр("Дата", ТекущаяДатаСеанса());

// 1. В прикладном коде: вернёт результат 2-го запроса (выборку с ценами),
//    пропустив финальный шаг УНИЧТОЖИТЬ ВТ_Номенклатура
РезультатИтог = Запрос.Выполнить();

// 2. Массив результатов всех 3 шагов пакета:
//    МассивРезультатов[0] -> 1 строка и 1 колонка (число записей в ВТ_Номенклатура)
//    МассивРезультатов[1] -> РезультатЗапроса с ценами
//    МассивРезультатов[2] -> Неопределено (результат УНИЧТОЖИТЬ)
МассивРезультатов = Запрос.ВыполнитьПакет();

// 3. Для отладки: МассивОтладки[0].Выгрузить() вернёт само содержимое ВТ_Номенклатура!
МассивОтладки = Запрос.ВыполнитьПакетСПромежуточнымиДанными();
ТаблицаВТ = МассивОтладки[0].Выгрузить();
Методы выполнения пакета
Выполнить()возвращает результат последнего запроса, не создающего, не дополняющего и не удаляющего ВТ (если такого нет — результат последнего запроса)
ВыполнитьПакет()возвращает Массив результатов; для ПОМЕСТИТЬ / ДОБАВИТЬ — число помещённых строк, для УНИЧТОЖИТЬ — Неопределено
ВыполнитьПакетСПромежуточнымиДанными()возвращает Массив результатов; для ПОМЕСТИТЬ / ДОБАВИТЬ — все строки и колонки ВТ
→ РезультатЗапроса, Неопределено / Массив

Обратите внимание на поведение обычного Запрос.Выполнить(): он возвращает результат последнего запроса пакета, который не создаёт, не обновляет (ДОБАВИТЬ) и не уничтожает временную таблицу (а если в пакете есть только операции над ВТ — результат самого последнего шага, где для УНИЧТОЖИТЬ возвращается Неопределено). Поэтому в конце расчётного пакетного запроса совершенно безопасно писать ; УНИЧТОЖИТЬ ВТ_Номенклатура — метод Выполнить() всё равно вернёт выборку предпоследнего шага, а временная таблица будет удалена сразу.

Индексация и удаление ВТ: ИНДЕКСИРОВАТЬ ПО, ДОБАВИТЬ и УНИЧТОЖИТЬ

Временная таблица в PostgreSQL или MS SQL Server создаётся без индексов, если вы не указали их явно. Когда ВТ содержит тысячи строк и участвует в соединениях (ЛЕВОЕ СОЕДИНЕНИЕ, ВНУТРЕННЕЕ СОЕДИНЕНИЕ) или отборах ГДЕ следующих пакетов, отсутствие индекса заставляет СУБД выполнять полное сканирование таблицы (Table Scan / Seq Scan).

В языке запросов 1С 8.3 предусмотрены четыре конструкции для управления структурой и жизненным циклом ВТ:

  • ИНДЕКСИРОВАТЬ ПО Поле1, Поле2 — создаёт один индекс по указанным полям выборки. В конце списка полей допустимо ключевое слово УНИКАЛЬНО (создаёт уникальный индекс для оптимизатора СУБД; у одной временной таблицы уникальным может быть только один индекс, причём использовать его для прикладного контроля дублей документация 1С не рекомендует из-за различий в поведении разных СУБД).
  • ИНДЕКСИРОВАТЬ ПО НАБОРАМ ((Поле1, Поле2), (Поле3) УНИКАЛЬНО) — создаёт сразу несколько отдельных индексов, если в последующих шагах пакета временная таблица соединяется по разным полям. В MS SQL Server первый набор в списке формирует кластерный индекс, а остальные (и все индексы в других СУБД) — некластерные.
  • ДОБАВИТЬ ИмяВТ — дописывает строки в уже существующую временную таблицу с идентичной структурой колонок. Важная деталь: у последнего поля перед словом ДОБАВИТЬ обязательно должен быть указан псевдоним через КАК, иначе парсер запроса примет слово ДОБАВИТЬ за псевдоним колонки.
  • УНИЧТОЖИТЬ ИмяВТ — немедленно удаляет временную таблицу и освобождает память и пространство tempdb до завершения всего пакета. Если таблицы с таким именем нет, возникнет ошибка выполнения.
ВЫБРАТЬ
    РеализацияТовары.Номенклатура КАК Номенклатура,
    РеализацияТовары.Характеристика КАК Характеристика,
    РеализацияТовары.Ссылка.Склад КАК Склад,
    СУММА(РеализацияТовары.Количество) КАК Количество
ПОМЕСТИТЬ ВТ_ДвиженияТоваров
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
ГДЕ
    РеализацияТовары.Ссылка.Проведен
    И РеализацияТовары.Ссылка.Дата МЕЖДУ &ДатаНач И &ДатаКон
СГРУППИРОВАТЬ ПО
    РеализацияТовары.Номенклатура,
    РеализацияТовары.Характеристика,
    РеализацияТовары.Ссылка.Склад
ИНДЕКСИРОВАТЬ ПО НАБОРАМ (
    (Номенклатура, Характеристика),
    (Склад)
)
;
ВЫБРАТЬ
    ПеремещениеТовары.Номенклатура КАК Номенклатура,
    ПеремещениеТовары.Характеристика КАК Характеристика,
    ПеремещениеТовары.Ссылка.СкладОтправитель КАК Склад,
    СУММА(ПеремещениеТовары.Количество) КАК Количество
ДОБАВИТЬ ВТ_ДвиженияТоваров
ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТовары
ГДЕ
    ПеремещениеТовары.Ссылка.Проведен
    И ПеремещениеТовары.Ссылка.Дата МЕЖДУ &ДатаНач И &ДатаКон
СГРУППИРОВАТЬ ПО
    ПеремещениеТовары.Номенклатура,
    ПеремещениеТовары.Характеристика,
    ПеремещениеТовары.Ссылка.СкладОтправитель

Ошибка «Не установлен менеджер временных таблиц»: причины и решение

Исключение Ошибка при вызове метода контекста (Выполнить): Не установлен менеджер временных таблиц возникает в тот момент, когда платформа видит в запросе операцию над временной таблицей, которая не может быть выполнена без внешнего объекта МенеджерВременныхТаблиц:

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

// ИСПРАВЛЕНИЕ 1: назначаем МенеджерВременныхТаблиц перед вызовом Выполнить()
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Выполнить(); // ВТ_Клиенты успешно сохранена в МенеджерВТ

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

Как посмотреть содержимое временной таблицы в отладчике 1С 8.3

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

Благодаря этому разработчик может получить таблицу из менеджера временных таблиц как программно в коде, так и интерактивно на точке останова в Конфигураторе или 1С:EDT:

// Поставьте точку останова после Запрос.Выполнить() (при назначенном МенеджерВТ)
// или используйте этот код для программного чтения ВТ из менеджера:

ВременнаяТаблица = МенеджерВТ.Таблицы.Найти("ВТ_Обороты");
Если ВременнаяТаблица <> Неопределено Тогда

    // Получаем РезультатЗапроса и выгружаем в обычную ТаблицаЗначений
    ТЗ_СодержимоеВТ = ВременнаяТаблица.ПолучитьДанные().Выгрузить();

    // Проверяем типы и имена колонок временной таблицы
    Для Каждого КолонкаВТ Из ВременнаяТаблица.Колонки Цикл
        Сообщить(КолонкаВТ.Имя + ": " + Строка(КолонкаВТ.ТипЗначения));
    КонецЦикла;

КонецЕсли;

// Альтернатива для «Вычислить выражение» (Shift+F9) прямо по имени или индексу:
// Запрос.МенеджерВременныхТаблиц.Таблицы["ВТ_Обороты"].ПолучитьДанные().Выгрузить()
// Запрос.МенеджерВременныхТаблиц.Таблицы[0].ПолучитьДанные().Выгрузить()
ВременнаяТаблицаЗапроса.ПолучитьДанные
Таблицы.Найти(Имя)возвращает ВременнаяТаблицаЗапроса или Неопределено
ПолноеИмяСтрока — имя временной таблицы в менеджере
КолонкиКолонкиВременнойТаблицыЗапроса (Имя, ТипЗначения)
ПолучитьДанные()читает строки существующей ВТ из менеджера
→ РезультатЗапроса

Как посмотреть содержимое временной таблицы в отладчике по шагам:

  1. Убедитесь, что перед выполнением запросу назначен менеджер: Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; (и что таблица не удалена в конце пакета оператором УНИЧТОЖИТЬ).
  2. Поставьте точку останова сразу после строки Запрос.Выполнить() и откройте окно Вычислить выражение (Shift+F9 в Конфигураторе).
  3. Введите выражение Запрос.МенеджерВременныхТаблиц.Таблицы["ВТ_Обороты"].ПолучитьДанные().Выгрузить() (или обратитесь по индексу Таблицы[0]) и нажмите Рассчитать — прямо в окне отладчика откроется ТаблицаЗначений со всеми строками и колонками временной таблицы.
  4. Если в коде не назначен МенеджерВременныхТаблиц, а менять модуль нельзя, вычислите в отладчике выражение Запрос.ВыполнитьПакетСПромежуточнымиДанными()[0].Выгрузить(), подставив индекс нужного пакета с ПОМЕСТИТЬ.

Сравнение способов работы с временными таблицами и пакетами

В таблице ниже сведены все штатные механизмы выполнения и отладки запросов с временными таблицами в 1С 8.3:

Сценарий / метод Нужен ли МенеджерВременныхТаблиц Что возвращает запрос с ПОМЕСТИТЬ ВТ Когда использовать
Одиночный пакет через Запрос.Выполнить() Нет (достаточно Неопределено) Возвращается результат последнего шага выборки; шаги ПОМЕСТИТЬ и УНИЧТОЖИТЬ пропускаются Стандартный расчёт в одном тексте запроса с автоматической очисткой ВТ по завершении вызова
Пакет через Запрос.ВыполнитьПакет() Необязателен (если ВТ не нужны вне пакета) РезультатЗапроса с 1 строкой и 1 колонкой — количество помещённых записей Получение нескольких итоговых выборок за одно обращение к серверу или проверка числа строк в ВТ
Отладка через ВыполнитьПакетСПромежуточнымиДанными() Необязателен Полноценный РезультатЗапроса со всеми строками и колонками созданной ВТ Инспекция всех промежуточных ВТ в консоли запросов или в отладчике (даже если в конце пакета есть УНИЧТОЖИТЬ)
Несколько объектов Запрос с общим МенеджерВТ Обязателен (один экземпляр на все запросы) ВТ сохраняется в МенеджерВТ.Таблицы и доступна через ПолучитьДанные() Пошаговые алгоритмы в разных процедурах, условная сборка запросов, передача ВТ в СКД
В ИИ Консоли запросов 1С вам не нужно вручную прописывать ИНДЕКСИРОВАТЬ ПО и выгружать промежуточные пакеты в отладчике: опишите задачу своими словами, и агент сам построит оптимальный пакетный запрос с временными таблицами по метаданным вашей конфигурации и сверит итоги.

Частые ошибки при работе с МенеджерВременныхТаблиц и пакетами

  • Вызов Запрос.Выполнить() для запроса с одним ПОМЕСТИТЬ ВТ без назначенного менеджера. Если в тексте запроса нет завершающего ВЫБРАТЬ, платформа выбросит ошибку «Не установлен менеджер временных таблиц». Назначьте Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц до выполнения.
  • Создание нового Новый МенеджерВременныхТаблиц во втором запросе вместо передачи существующего. Каждый экземпляр менеджера изолирован. Чтобы второй запрос увидел таблицу ВТ_Данные, ему нужно присвоить ссылку на ту же самую переменную МенеджерВТ, в которой таблица создавалась.
  • Повторное выполнение ПОМЕСТИТЬ ВТ_Имя в цикле с одним и тем же менеджером без удаления таблицы. В пределах одного МенеджерВременныхТаблиц имена таблиц должны быть уникальными. Если запрос с ПОМЕСТИТЬ ВТ_Данные выполняется в цикле, перед повторным созданием удаляйте таблицу запросом УНИЧТОЖИТЬ ВТ_Данные или используйте предложение ДОБАВИТЬ ВТ_Данные.
  • Отсутствие псевдонима поля перед ключевым словом ДОБАВИТЬ. В конструкции ВЫБРАТЬ Док.Сумма ДОБАВИТЬ ВТ_Данные парсер языка запросов воспримет слово ДОБАВИТЬ как псевдоним поля Док.Сумма. Всегда явно указывайте псевдоним через КАК: ВЫБРАТЬ Док.Сумма КАК Сумма ДОБАВИТЬ ВТ_Данные.
  • Попытка прочитать МенеджерВТ.Таблицы["ВТ"].ПолучитьДанные() после пакета с УНИЧТОЖИТЬ ВТ. Если последний шаг пакета уничтожил временную таблицу, в коллекции МенеджерВТ.Таблицы её уже не будет (Найти("ВТ") вернёт Неопределено). Для просмотра удаляемых внутри пакета ВТ используйте метод Запрос.ВыполнитьПакетСПромежуточнымиДанными().
  • Усечение строк и чисел при первом ПОМЕСТИТЬ. Типы, длина строки и разрядность числа в колонках временной таблицы жёстко фиксируются по первому запросу ПОМЕСТИТЬ. Если в первом шаге в колонку поместить литерал "" или короткое поле, а во втором шаге через ДОБАВИТЬ записать длинную строку, значение обрежется или вызовет ошибку типов. Задавайте тип явно через ВЫРАЗИТЬ("" КАК Строка(200)).
  • Соединение большой временной таблицы с регистрами без ИНДЕКСИРОВАТЬ ПО. Без индекса по полям соединения СУБД выполняет полный перебор временной таблицы на каждую строку соединения, из-за чего запрос начинает зависать при росте объёма выборки.

Частые вопросы о менеджере временных таблиц и пакетах запросов в 1С

Когда в запросе 1С обязательно создавать Новый МенеджерВременныхТаблиц?

Создавать Новый МенеджерВременныхТаблиц обязательно, если временная таблица должна сохраниться после завершения Запрос.Выполнить(): для обращения к ней из другого объекта Запрос, при выполнении одиночного запроса с ПОМЕСТИТЬ без последующего ВЫБРАТЬ или для передачи временных таблиц шестым параметром в ПроцессорКомпоновкиДанных.Инициализировать. Если ВТ создаётся и используется внутри одного пакетного запроса, менеджер не требуется.

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

Обратитесь к коллекции МенеджерВТ.Таблицы по имени или индексу и вызовите метод ПолучитьДанные().Выгрузить(), например: Запрос.МенеджерВременныхТаблиц.Таблицы["ИмяВТ"].ПолучитьДанные().Выгрузить(). В отладчике Конфигуратора или EDT это выражение можно вычислить через Shift+F9 сразу после выполнения запроса, либо вызвать Запрос.ВыполнитьПакетСПромежуточнымиДанными().

Чем отличается ВыполнитьПакет() от ВыполнитьПакетСПромежуточнымиДанными()?

Оба метода возвращают массив объектов РезультатЗапроса по числу запросов в пакете, но для шагов с предложением ПОМЕСТИТЬ метод ВыполнитьПакет() возвращает результат из одной строки и одной колонки с количеством помещённых записей, тогда как ВыполнитьПакетСПромежуточнымиДанными() возвращает полное содержимое созданной временной таблицы.