Что такое временные таблицы?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Временные таблицы в 1С
Временные таблицы — это специальный объект в 1С для работы с наборами данных, которые не требуют постоянного хранения в БД. Это критически важный инструмент для оптимизации производительности и организации сложных вычислений.
Что это такое
Временная таблица (TempTable) — это таблица значений в памяти 1С, которая:
- Живёт только в текущем сеансе
- Может быть использована в SQL запросах как обычная таблица
- Автоматически удаляется при завершении сеанса
- Не требует прав на создание физических таблиц в БД
Два типа временных таблиц
1. Таблица значений (ТаблицаЗначений) — в памяти клиента
// Создание в памяти
Таблица = Новая ТаблицаЗначений();
Таблица.Колонки.Добавить("Товар");
Таблица.Колонки.Добавить("Количество");
Таблица.Колонки.Добавить("Цена");
// Добавление данных
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Товар = Справочники.Товары.НайтиПоКоду("001");
НоваяСтрока.Количество = 100;
НоваяСтрока.Цена = 500;
// Свойства: только клиент, очень быстро
2. Временная таблица на сервере БД
// Это таблица, которая реально создаётся в БД, но временная
Запрос = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ДанныеДляОтчёта КАК
|ВЫБРАТЬ
| Товары.Ссылка КАК Товар,
| Товары.Наименование,
| СУММА(Движения.Количество) КАК ОбщееКоличество
|ИЗ
| РегистрНакопления.Движения КАК Движения
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
| НА Движения.Товар = Товары.Ссылка
|ГРУППИРОВАТЬ ПО
| Товары.Ссылка,
| Товары.Наименование");
Запрос.Выполнить();
// Теперь её можно использовать как обычную таблицу
Запрос2 = Новый Запрос(
"ВЫБРАТЬ * ИЗ ДанныеДляОтчёта ГДЕ ОбщееКоличество > 100");
Отличия и когда использовать
ТаблицаЗначений (клиентская):
- Живёт в памяти клиента
- Очень быстро для маленьких наборов (до 10-50k строк)
- Нельзя использовать в запросах SQL
- Нельзя использовать между клиентом и сервером
// Пример: Обработка заказа
ТаблицаДетализации = Новая ТаблицаЗначений();
// ... заполнение ...
// Используется только локально для расчётов
ИтоговаяСумма = ВычислитьСумму(ТаблицаДетализации);
Временная таблица БД (серверная):
- Создаётся реально в БД
- Работает для больших объёмов (100k+)
- Может использоваться в нескольких запросах
- Требует выполнения на сервере
// Пример: Большой отчёт с агрегацией
Процедура СформироватьОтчёт() Экспорт
// Создаём временную таблицу с базовыми данными
ЗапросСоздание = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ИсходныеДанные КАК
|ВЫБРАТЬ ... ИЗ Документ.Заказ");
ЗапросСоздание.Выполнить();
// Используем эту таблицу в нескольких запросах
ЗапросОсновной = Новый Запрос(
"ВЫБРАТЬ * ИЗ ИсходныеДанные ГДЕ ...");
КонецПроцедуры
Практические примеры
Пример 1: Кэширование справочных данных
Процедура КэшироватьДанные() Экспорт
// Вместо множества обращений к справочнику,
// создаём временную таблицу
ЗапросПолучения = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ КэшТовары КАК
|ВЫБРАТЬ
| Ссылка КАК Товар,
| Наименование,
| Артикул,
| ВидУпаковки
|ИЗ
| Справочник.Товары
|ГДЕ
| НЕ ПометкаУдаления");
ЗапросПолучения.Выполнить();
// Теперь все дальнейшие запросы используют КэшТовары
ЗапросОтчёта = Новый Запрос(
"ВЫБРАТЬ
| ОстатокИТовары.Товар,
| КэшТовары.Наименование,
| КэшТовары.Артикул,
| ОстатокИТовары.Количество
|ИЗ
| РегистрНакопления.ОстатокТоваров КАК ОстатокИТовары
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ КэшТовары
| НА ОстатокИТовары.Товар = КэшТовары.Товар");
КонецПроцедуры
Пример 2: Промежуточные расчёты в отчёте
Процедура СформироватьСложныйОтчёт() Экспорт
// Шаг 1: Создаём таблицу с доходами
Запрос1 = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ Доходы КАК
|ВЫБРАТЬ
| Статья,
| СУММА(Сумма) КАК СуммаДохода
|ИЗ РегистрСведений.Доходы
|ГРУППИРОВАТЬ ПО Статья");
Запрос1.Выполнить();
// Шаг 2: Создаём таблицу с расходами
Запрос2 = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ Расходы КАК
|ВЫБРАТЬ
| Статья,
| СУММА(Сумма) КАК СуммаРасхода
|ИЗ РегистрСведений.Расходы
|ГРУППИРОВАТЬ ПО Статья");
Запрос2.Выполнить();
// Шаг 3: Объединяем и рассчитываем прибыль
ЗапросИтоговый = Новый Запрос(
"ВЫБРАТЬ
| ВЫБОР
| КОГДА Доходы.Статья НЕ NULL ТОГДА Доходы.Статья
| ИНАЧЕ Расходы.Статья
| КОНЕЦ КАК Статья,
| ВЫБОР КОГДА Доходы.СуммаДохода НЕ NULL ТОГДА Доходы.СуммаДохода ИНАЧЕ 0 КОНЕЦ КАК Доход,
| ВЫБОР КОГДА Расходы.СуммаРасхода НЕ NULL ТОГДА Расходы.СуммаРасхода ИНАЧЕ 0 КОНЕЦ КАК Расход,
| (ВЫБОР КОГДА Доходы.СуммаДохода НЕ NULL ТОГДА Доходы.СуммаДохода ИНАЧЕ 0 КОНЕЦ) -
| (ВЫБОР КОГДА Расходы.СуммаРасхода НЕ NULL ТОГДА Расходы.СуммаРасхода ИНАЧЕ 0 КОНЕЦ) КАК Прибыль
|ИЗ
| Доходы
| ПОЛНОЕ СОЕДИНЕНИЕ Расходы
| НА Доходы.Статья = Расходы.Статья");
ТаблицаРезультата = ЗапросИтоговый.Выполнить().Выгрузить();
КонецПроцедуры
Пример 3: Обработка больших объёмов данных пакетами
Процедура ОбработатьДокументыПакетами() Экспорт
// Создаём временную таблицу документов для обработки
ЗапросСоздания = Новый Запрос(
"СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ДокументыКОбработке КАК
|ВЫБРАТЬ
| Ссылка,
| Номер,
| Дата,
| Сумма
|ИЗ Документ.Заказ
|ГДЕ
| Дата >= &ДатаНачала
| И Статус = &СтатусНовый");
ЗапросСоздания.УстановитьПараметр("ДатаНачала", БольшаяДата(,,-30)); // 30 дней назад
ЗапросСоздания.УстановитьПараметр("СтатусНовый", Перечисления.СтатусыДокумента.Новый);
ЗапросСоздания.Выполнить();
// Обработка пакетами по 100 документов
ЗапросПакетов = Новый Запрос(
"ВЫБРАТЬ * ИЗ ДокументыКОбработке ПОРЯДОК ПО Дата ПРЕДЕЛ 100");
Цикл
РезультатПакета = ЗапросПакетов.Выполнить();
Если РезультатПакета.Пусто() Тогда
Прервать; // Все обработаны
КонецЕсли;
Для Каждого Документ Из РезультатПакета Цикл
ОбработатьДокумент(Документ.Ссылка);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Правила использования
1. Область видимости:
- Временная таблица видна только в текущем соединении
- В фоновых заданиях — отдельное соединение
- Нельзя передать временную таблицу между сеансами
2. Производительность:
- Для маленьких наборов < 10k — лучше ТаблицаЗначений
- Для больших наборов > 100k — временная таблица БД
- Индексы создаются автоматически
3. Очистка:
// В конце работы явно удаляй временные таблицы
ЗапросУдаления = Новый Запрос(
"УДАЛИТЬ ИЗ ВременнаяТаблица");
ЗапросУдаления.Выполнить();
// Или просто заверши сеанс — удалятся сами
4. Типичные ошибки:
- Использование временной таблицы после завершения сеанса
- Забыли, что временная таблица видна только в текущем соединении
- Создали индекс без необходимости
- Не удалили временную таблицу в конце — занимает память
Примеры оптимизации
// ❌ ПЛОХО: Много небольших запросов
Для н = 1 По 1000 Цикл
Запрос = Новый Запрос("ВЫБРАТЬ ... ГДЕ ID = " + Н);
Результат = Запрос.Выполнить();
КонецЦикла;
// ✅ ХОРОШО: Одна временная таблица
ЗапросВсе = Новый Запрос("ВЫБРАТЬ * ИЗ Таблица");
Таблица = ЗапросВсе.Выполнить().Выгрузить();
// Работаешь с таблицей в памяти
Заключение
Временные таблицы — это essential инструмент для:
- Оптимизации сложных отчётов
- Обработки больших объёмов данных
- Кэширования промежуточных результатов
- Разделения логики на понятные шаги
Профессиональное использование временных таблиц значительно ускоряет работу системы и упрощает поддержку кода.