Как программно добавить внешнюю временную таблицу в схему запроса в 1С

Программист IT и автоматизация бизнеса
← На главную

Работа с объектом СхемаЗапроса в 1С:Предприятие 8.3 открывает широкие возможности для динамического построения сложных запросов. Однако при попытке добавить в схему источник, который является внешней временной таблицей (передаваемой как параметр через &ТаблицаЗначений), разработчики часто сталкиваются с трудностями. Система может выдавать ошибку о том, что таблица не найдена, поскольку стандартный метод добавления источника ожидает увидеть имя таблицы из метаданных конфигурации. Для интерактивной отладки и анализа динамических запросов подойдёт консоль запросов с поддержкой схемы запроса.

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

Разбор проблемы: почему обычное добавление источника не работает

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


СхемаЗапроса = Новый СхемаЗапроса;
ОператорСхемы = СхемаЗапроса.ПакетЗапросов[0].Операторы[0];
// ОШИБКА: Система ищет таблицу в метаданных по имени строки
ОператорСхемы.Источники.Добавить("&ТаблицаПравилПервогоУровня", "ТаблицаПравилПервогоУровня"); 

Проблема заключается в том, что метод Добавить() коллекции Источники при получении строки в качестве первого параметра пытается разрешить её как путь к объекту метаданных (например, Справочник.Номенклатура). Поскольку таблицы с именем &ТаблицаПравилПервогоУровня в конфигурации не существует, возникает исключение.

Правильное решение через ОписаниеВременнойТаблицыСхемыЗапроса

Для того чтобы система поняла, что источником является именно внешнее описание таблицы, необходимо использовать специальный объект. Выясним причину успеха: использование типа ОписаниеВременнойТаблицыСхемыЗапроса позволяет явно указать схеме, что мы описываем структуру таблицы, которая будет предоставлена в момент выполнения запроса.

Рассмотрим правильный алгоритм действий:

  1. Создаем объект СхемаЗапроса.
  2. Обращаемся к первому оператору первого пакета запросов.
  3. Добавляем источник, используя конструкцию Тип("ОписаниеВременнойТаблицыСхемыЗапроса").
  4. Указываем псевдоним и поля.
  5. Устанавливаем свойство ТаблицаДляПомещения для сохранения результата во временную таблицу.

Посмотрим на пример корректного кода:


СхемаЗапроса = Новый СхемаЗапроса;
// Первый пакет запроса - здесь мы описываем выборку из параметра
Пакет1 = СхемаЗапроса.ПакетЗапросов[0];
ОператорСхемы = Пакет1.Операторы[0];

// Добавляем описание внешней временной таблицы
Источник = ОператорСхемы.Источники.Добавить(Тип("ОписаниеВременнойТаблицыСхемыЗапроса"), "&ТаблицаПравилПервогоУровня");
Источник.Псевдоним = "ТаблицаПравилПервогоУровня";

// Добавляем поля, которые мы планируем выбирать
ОператорСхемы.ВыбираемыеПоля.Добавить("ТаблицаПравилПервогоУровня.Родитель", 0);
ОператорСхемы.ВыбираемыеПоля.Добавить("ТаблицаПравилПервогоУровня.Правило", 1);

// Указываем имя временной таблицы, куда будут помещены данные
Пакет1.ТаблицаДляПомещения = "ТаблицаПравилПервогоУровня";

Работа с колонками и типами данных

Проанализируем ситуацию глубже. Хотя приведенный выше код работоспособен, СхемаЗапроса может не знать о составе полей таблицы &ТаблицаПравилПервогоУровня до компиляции. Чтобы сделать код более надежным и избежать ошибок «Поле не найдено» при программной настройке полей, рекомендуется явно описывать колонки источника.

Рассмотрим, как это сделать программно через объект ОписаниеВременнойТаблицыСхемыЗапроса:


// Получаем объект описания из созданного источника
ОписаниеТаблицы = Источник.Источник; 

// Добавляем колонки с указанием их типов (необязательно, но полезно для типизации)
НоваяКолонка = ОписаниеТаблицы.Колонки.Добавить("Родитель");
НоваяКолонка = ОписаниеТаблицы.Колонки.Добавить("Правило");

Важный момент: если в имени таблицы-параметра используется амперсанд (&), его необходимо указывать при добавлении источника. Если же вы работаете с временной таблицей, которая уже была создана в МенеджерВременныхТаблиц ранее, амперсанд не используется, но тип источника остается тем же — ОписаниеВременнойТаблицыСхемыЗапроса.

Создание второго пакета и использование временной таблицы

Теперь, когда мы поместили данные во временную таблицу в первом пакете, разберем по шагам, как обратиться к ней во втором пакете. Обратите внимание: во втором и последующих пакетах эта таблица уже считается «известной» схеме, и её не нужно описывать через ОписаниеВременнойТаблицыСхемыЗапроса.


// Добавляем новый пакет запроса (выборка из созданной ВТ)
Пакет2 = СхемаЗапроса.ПакетЗапросов.Добавить(Тип("ЗапросВыбораСхемыЗапроса"));
Оператор2 = Пакет2.Операторы[0];

// Здесь мы уже можем обращаться к ней просто по имени, как к обычной таблице БД
Источник2 = Оператор2.Источники.Добавить("ТаблицаПравилПервогоУровня");

Оператор2.ВыбираемыеПоля.Добавить("ТаблицаПравилПервогоУровня.Родитель");
Оператор2.ВыбираемыеПоля.Добавить("ТаблицаПравилПервогоУровня.Правило");

// Получаем итоговый текст запроса
ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();

Особенности именования и ограничения

При программной работе со схемой следует помнить о нескольких критически важных моментах:

Резюме

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

← На главную