Временные таблицы 1С

Временные таблицы часто используются как для реализации сложных запросов, так и для их оптимизации.

Временные таблицы в 1С

Временные таблицы — это объекты СУБД, никаких временных таблиц на сервере 1С нет, не путайте пожалуйста, их с таблицами значений.

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

Физически временные таблицы по умолчанию создаются в оперативной памяти, а именно в буферном кэше.

Конечно, есть исключения. Например, если таблица слишком большая, то сервер может принять решение сбросить ее на диск. Также возможна ситуация, когда сервер по каким-либо причинам решил отдать память под другие данные, тогда таблица тоже будет записана на диск.

Почему таблица создается именно в памяти? Тут все очевидно, дело в производительности, думаю не стоит объяснять, что чтение из оперативной памяти гораздо быстрее чтения с диска, даже если этот диск SSD.
Чтобы создать временную таблицу, используется ключевое слово «ПОМЕСТИТЬ», например:

ВЫБРАТЬ * ИЗ Справочник.Номенклатура ПОМЕСТИТЬ ВТТовары

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

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

Готовую таблицу значений из памяти можно выгружать в менеджер временных таблиц запроса. Единственное условие — колонки таблицы значений должны быть типизированными, т.е. иметь тип. Вот пример, демонстрирующий это:

ТЗ = Новый ТаблицаЗначений(); //Колонки должны быть типизированы
ТЗ.Колонки.Добавить("А", Новый ОписаниеТипов("Строка"));
ТЗ.Колонки.Добавить("Б", Новый ОписаниеТипов("Строка"));

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

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

Вместо перечисления списка полей можно использовать «ВЫБРАТЬ *».

Если есть ТЗ, в каждой колонке которой значения всего одного типа, для типизации колонок, можно воспользоваться функцией:

Процедура ТипизацияТЗ(ТЗ) Экспорт
  РезультатТЗ = новый ТаблицаЗначений;
  Для Каждого Колонка из ТЗ.Колонки Цикл
    Имя = Колонка.Имя;
    МассивТипов = новый Массив(1);
    МассивТипов[0] = ТипЗнч(ТЗ[0][Имя]);
    Описатель = новый ОписаниеТипов(МассивТипов);
    РезультатТЗ.Колонки.Добавить(Имя, Описатель);
  КонецЦикла;

  Для каждого Строка из ТЗ Цикл
    СтрокаРез = РезультатТЗ.Добавить();
    ЗаполнитьЗначенияСвойств(СтрокаРез, Строка);
  КонецЦикла;

  ТЗ = РезультатТЗ.Скопировать();
КонецПроцедуры

Остались вопросы? Спрашивайте в комментариях.

© Гений 1С Источник: http://kb.mista.ru/article.php?id=628

3 комментария

  1. Приветствую, Алексей!
    Есть ли возможность использовать временную таблицу (в ней данные ТЧ документа) в качестве условия виртуальной, чтобы не обращаться к ним ещё раз вложенным запросом?

    1. Добрый день, Дмитрий. Спасибо за внимательность 🙂 Конечно «В» не нужно, это опечатка, а не написано специально

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *