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

В этой статье мы разберем 5 проверенных способов загрузки временных таблиц в запросы 1С, включая нюансы работы с разными версиями платформы (1С:Предприятие 8.3 и 1С:Предприятие 8.2). Вы узнаете, как избежать типичных ошибок, какие методы наиболее эффективны для разных задач, и получите готовые примеры кода для immediate-внедрения в свои проекты. Особое внимание уделим производительности — ведь неправильная работа с временными таблицами может замедлить систему в десятки раз.

Что такое временная таблица в 1С и зачем её загружать в запрос

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

Загрузка временной таблицы в запрос нужна в следующих случаях:

  • 🔹 Оптимизация сложных отчетов. Когда нужно объединить данные из нескольких источников, но делать это напрямую в SQL-запросе неэффективно.
  • 🔹 Промежуточные расчеты. Например, когда вы рассчитываете какие-то показатели (средние значения, отклонения) и потом используете их в основном запросе.
  • 🔹 Работа с большими массивами данных. Если вы обрабатываете тысячи строк, временная таблица поможет избежать таймаутов.
  • 🔹 Динамические фильтры. Когда условия отбора формируются программно и их нельзя жестко прописать в запросе.

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

📊 Как часто вы используете временные таблицы в 1С?
Постоянно, в каждом проекте
Иногда, для сложных отчетов
Реде, только если нет альтернативы
Никогда не использовал

Способ 1: Использование конструктора запросов и параметра &ВременныеТаблицы

Самый простой и визуально понятный способ — загрузка через конструктор запросов с использованием параметра &ВременныеТаблицы. Этот метод подходит для начинающих разработчиков, так как не требует глубоких знаний синтаксиса 1С:Предприятие.

Алгоритм действий:

  1. Создайте временную таблицу с нужной структурой (например, через Новый ТаблицаЗначений).
  2. Заполните её данными.
  3. В конструкторе запросов добавьте параметр &ВременныеТаблицы и укажите вашу таблицу.
  4. В тексте запроса обратитесь к временной таблице как к обычной таблице базы данных.

Пример кода:


ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Код");

ТЗ.Колонки.Добавить("Наименование");

ТЗ.Добавить().Заполнить("1", "Товар 1");

ТЗ.Добавить().Заполнить("2", "Товар 2");

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ТоварыВременные.Код КАК Код,

| ТоварыВременные.Наименование КАК Наименование

|ИЗ

| &ВременныеТаблицы КАК ТоварыВременные";

Запрос.УстановитьПараметр("ВременныеТаблицы", ТЗ);

Результат = Запрос.Выполнить();

Этот метод удобен тем, что не требует ручного формирования временных таблиц в SQL-синтаксисе. Однако у него есть ограничение: не все версии 1С поддерживают такой подход (например, в 1С:Предприятие 7.7 это невозможно). Также стоит помнить, что при большом объеме данных производительность может падать.

💡

Если временная таблица содержит более 10 000 строк, разбейте её на части и обрабатывайте пакетами. Это поможет избежать перегрузки памяти.

Способ 2: Прямое обращение к временной таблице через МенеджерВременныхТаблиц

Более гибкий и производительный способ — использование объекта МенеджерВременныхТаблиц. Этот метод позволяет явно управлять временными таблицами, создавать их с нужной структурой и загружать данные напрямую в запрос.

Преимущества метода:

  • 🔹 Контроль над структурой таблицы. Вы можете явно указать типы данных колонок.
  • 🔹 Высокая производительность. Данные загружаются оптимальным образом, без лишних преобразований.
  • 🔹 Поддержка транзакций. Временные таблицы можно создавать в рамках транзакции и откатывать при необходимости.

Пример использования:


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

// Создаем временную таблицу с явным указанием структуры

Таблица = МенеджерВТ.СоздатьТаблицу("МояВременнаяТаблица");

Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Число"));

Таблица.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка", 100));

// Заполняем данными

Строка = Таблица.Добавить();

Строка.Код = 1;

Строка.Наименование = "Товар 1";

// Используем в запросе

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос.Текст =

"ВЫБРАТЬ

| МояВременнаяТаблица.Код КАК Код,

| МояВременнаяТаблица.Наименование КАК Наименование

|ИЗ

| МояВременнаяТаблица КАК МояВременнаяТаблица";

Результат = Запрос.Выполнить();

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

Что будет, если не очистить МенеджерВременныхТаблиц?

Если не освободить ресурсы (например, не вызвать МенеджерВТ.Очистить()), временные таблицы могут оставаться в памяти до конца сеанса, что приведет к увеличению потребления ОЗУ и возможным ошибкам при длительной работе.

Способ 3: Загрузка данных через параметр &Таблица в запросе

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

Особенности метода:

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

Пример кода:


ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("КодТовара");

ТЗ.Колонки.Добавить("Количество");

ТЗ.Добавить().Заполнить(1, 10);

ТЗ.Добавить().Заполнить(2, 20);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Наименование КАК Наименование,

| Товары.Артикул КАК Артикул,

| &Таблица.Количество КАК Количество

|ИЗ

| Справочник.Товары КАК Товары

| ЛЕВОЕ СОЕДИНЕНИЕ &Таблица КАК ТоварыКоличество

| ПО Товары.Ссылка = ТоварыКоличество.КодТовара";

Запрос.УстановитьПараметр("Таблица", ТЗ);

Результат = Запрос.Выполнить();

Этот метод часто используется для динамического формирования условий отбора. Например, когда список товаров для запроса формируется программно на основе пользовательского ввода. Однако помните, что ТаблицаЗначений в параметре запроса не оптимизирована для больших данных — при объеме более 1000 строк лучше использовать МенеджерВременныхТаблиц.

☑️ Подготовка к использованию временных таблиц

Выполнено: 0 / 4

Способ 4: Использование временных таблиц в пакетных запросах

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

Преимущества пакетных запросов:

  • 🔹 Минимизация сетевого трафика. Все операции выполняются на сервере.
  • 🔹 Повышение производительности. Нет необходимости передавать промежуточные результаты на клиент.
  • 🔹 Поддержка транзакций. Можно откатить все изменения, если что-то пойдет не так.

Пример пакетного запроса с временной таблицей:


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

ТаблицаЗаказов = МенеджерВТ.СоздатьТаблицу("ЗаказыДляАнализа");

// Заполняем временную таблицу (например, заказы за последний месяц)

Запрос1 = Новый Запрос;

Запрос1.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос1.Текст =

"ВЫБРАТЬ

| ЗаказыПокупателей.Ссылка КАК Ссылка,

| ЗаказыПокупателей.Дата КАК Дата,

| ЗаказыПокупателей.СуммаДокумента КАК Сумма

|ПОМЕСТИТЬ ЗаказыДляАнализа

|ИЗ

| Документ.ЗаказПокупателя КАК ЗаказыПокупателей

|ГДЕ

| ЗаказыПокупателей.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос1.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));

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

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

// Теперь используем временную таблицу в другом запросе

Запрос2 = Новый Запрос;

Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос2.Текст =

"ВЫБРАТЬ

| ЗаказыДляАнализа.Дата КАК Дата,

| СУММА(ЗаказыДляАнализа.Сумма) КАК ИтогоСумма

|ИЗ

| ЗаказыДляАнализа КАК ЗаказыДляАнализа

|СГРУППИРОВАТЬ ПО

| ЗаказыДляАнализа.Дата";

Результат = Запрос2.Выполнить();

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

💡

Пакетные запросы с временными таблицами сокращают время выполнения в 2-3 раза по сравнению с последовательным выполнением отдельных запросов.

Способ 5: Загрузка данных из XML или JSON во временную таблицу

Иногда данные для временной таблицы поступают из внешних источников — например, в формате XML или JSON. В этом случае их нужно сначала преобразовать в ТаблицуЗначений, а затем загрузить в запрос.

Алгоритм работы:

  1. Получите данные из внешнего источника (например, через HTTPЗапрос).
  2. Разберите XML/JSON и заполните ТаблицуЗначений.
  3. Передайте таблицу в запрос одним из описанных выше методов.

Пример загрузки данных из JSON:


// Получаем JSON из внешнего API

HTTPЗапрос = Новый HTTPЗапрос("https://api.example.com/data");

Ответ = HTTPЗапрос.Выполнить();

ТекстJSON = Ответ.ПолучитьТекст();

// Разбираем JSON и формируем таблицу значений

ЧтениеJSON = Новый ЧтениеJSON;

ЧтениеJSON.УстановитьСтроку(ТекстJSON);

Данные = ПрочитатьJSON(ЧтениеJSON);

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("ID");

ТЗ.Колонки.Добавить("Name");

Для Каждого Элемент Из Данные.Элементы Цикл

Строка = ТЗ.Добавить();

Строка.ID = Элемент.ID;

Строка.Name = Элемент.Name;

КонецЦикла;

// Используем таблицу в запросе

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ВнешниеДанные.ID КАК ВнешнийID,

| ВнешниеДанные.Name КАК Наименование

|ИЗ

| &ВнешниеДанные КАК ВнешниеДанные";

Запрос.УстановитьПараметр("ВнешниеДанные", ТЗ);

Результат = Запрос.Выполнить();

Этот метод актуален для интеграций с внешними системами, когда данные приходят в структурированном виде и их нужно быстро обработать в . Однако здесь важно учитывать формат данных — если JSON/XML имеет сложную вложенную структуру, его разбор может занять значительное время.

💡

Для ускорения разбора больших JSON-файлов используйте потоковое чтение (ПотокЧтенияJSON), а не загрузку всего документа в память.

Типичные ошибки и как их избежать

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

Ошибка 1: Неосвобождение ресурсов

Если вы создали временную таблицу через МенеджерВременныхТаблиц, но не очистили её после использования, она может оставаться в памяти до конца сеанса. Это приводит к утечкам памяти, особенно критично в длительных сеансах (например, в фоновом задании).

⚠️ Внимание: Всегда вызывайте МенеджерВТ.Очистить() после завершения работы с временными таблицами, если они больше не нужны.

Ошибка 2: Передача больших таблиц в параметре запроса

Если вы передаете ТаблицуЗначений с тысячами строк через параметр &Таблица, это может привести к значительному увеличению времени выполнения запроса. Временные таблицы на сервере работают намного быстрее.

Ошибка 3: Несоответствие типов данных

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

⚠️ Внимание: Всегда проверяйте соответствие типов данных между временной таблицей и полями в запросе. Используйте ОписаниеТипов для явного указания типов.

Ошибка 4: Использование временных таблиц в транзакциях без контроля

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

В таблице ниже собраны основные ошибки и способы их исправления:

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

FAQ: Ответы на частые вопросы

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

Да, временные таблицы можно использовать в Системе Компоновки Данных (СКД). Для этого нужно:

  1. Создать временную таблицу через МенеджерВременныхТаблиц.
  2. В настройках схемы компоновки данных указать её как источник.
  3. При формировании отчета передать менеджер временных таблиц в параметры выполнения.

Пример:


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

ТаблицаДанных = МенеджерВТ.СоздатьТаблицу("ДанныеДляОтчета");

// Заполняем таблицу...

Отчет = ПолучаемОтчет();

Отчет.КомпоновщикНастроек.Настройки.ИсточникДанных.УстановитьПараметр("МенеджерВТ", МенеджерВТ);

Отчет.СкомпоноватьРезультаты();

Как передать временную таблицу между серверными вызовами?

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

  • 🔹 Хранилище значений (для небольших объемов данных).
  • 🔹 Регистры сведений (для больших объемов, но с накладными расходами на запись/чтение).
  • 🔹 Временные файлы (сериализация таблицы в JSON/XML и сохранение во временный файл).

Пример с сериализацией:


// Сериализация

ЗаписьJSON = Новый ЗаписьJSON;

ЗаписьJSON.УстановитьСтроку();

ЗаписатьJSON(ЗаписьJSON, ТаблицаДанных);

ТекстJSON = ЗаписьJSON.Закрыть();

// Сохранение во временный файл

ИмяФайла = ПолучениеИмениВременногоФайла("json");

ТекстJSON.Записать(ИмяФайла);

// В другом вызове:

ТекстJSON = Новый ЧтениеТекста(ИмяФайла);

ЧтениеJSON = Новый ЧтениеJSON;

ЧтениеJSON.УстановитьСтроку(ТекстJSON.Прочитать());

ТаблицаДанных = ПрочитатьJSON(ЧтениеJSON);

Какая максимальная размер временной таблицы в 1С?

Теоретически размер временной таблицы ограничивается только доступной памятью на сервере 1С:Предприятие. Однако на практике:

  • 🔹 В файловом варианте работы ограничение — около 2 ГБ на таблицу (зависит от настроек системы).
  • 🔹 В клиент-серверном варианте ограничение выше, но при превышении 100 000 строк возможны задержки.
  • 🔹 Для таблиц более 1 000 000 строк рекомендуется использовать постоянные таблицы базы данных.
⚠️ Внимание: При работе с большими временными таблицами следите за потреблением памяти на сервере. Используйте ДиагностикаПроизводительности.ЗамеритьПамять() для мониторинга.
Можно ли создать индекс на временной таблице в 1С?

Нет, в 1С:Предприятие нельзя явно создавать индексы на временных таблицах, как это делается в классических СУБД (например, CREATE INDEX в SQL). Однако:

  • 🔹 Платформа автоматически оптимизирует запросы к временным таблицам, если они небольшие.
  • 🔹 Для ускорения работы с большими таблицами можно отсортировать данные перед загрузкой (например, по ключевому полю).
  • 🔹 В некоторых случаях помогает разбиение таблицы на части по какому-либо критерию.
Как узнать, сколько временных таблиц создано в текущем сеансе?

Платформа не предоставляет прямого метода для получения списка всех временных таблиц в сеансе. Однако вы можете:

  • 🔹 Вести учет созданных таблиц в своей программе (например, в коллекции или регистре).
  • 🔹 Использовать профилировщик (ПрофилировщикЗапросов) для анализа используемых таблиц.
  • 🔹 В клиент-серверном варианте посмотреть журнал сервера 1С (если включена детальная запись).

Пример ведения учета:


Перем СписокВременныхТаблиц; // Коллекция для учета

Процедура СоздатьВременнуюТаблицу(ИмяТаблицы)

Если СписокВременныхТаблиц = Неопределено Тогда

СписокВременныхТаблиц = Новый Массив;

КонецЕсли;

СписокВременныхТаблиц.Добавить(ИмяТаблицы);

КонецПроцедуры