Как правильно передать таблицу значений в запрос в 1С 8.3: подробная инструкция

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Почему нельзя просто передать таблицу значений в параметр?

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

Шаг 1. Обязательная типизация колонок таблицы значений

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

Разберем пример правильного создания таблицы значений с типизацией (также вы можете использовать инструменты для создания кода новой таблицы значений):


// Создаем описание типов для колонок
МассивТиповНоменклатура = Новый Массив;
МассивТиповНоменклатура.Добавить(Тип("СправочникСсылка.Номенклатура"));
ОписаниеТиповНоменклатура = Новый ОписаниеТипов(МассивТиповНоменклатура);

МассивТиповЧисло = Новый Массив;
МассивТиповЧисло.Добавить(Тип("Число"));
ОписаниеТиповЧисло = Новый ОписаниеТипов(МассивТиповЧисло, Новый КвалификаторыЧисла(15, 3));

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

// Заполняем таблицу данными (для примера)
НоваяСтрока = ТаблицаДанных.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("00001");
НоваяСтрока.Количество = 10;

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

Шаг 2. Использование Менеджера Временных Таблиц

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

Проанализируем алгоритм подключения менеджера:

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

Шаг 3. Текст запроса для помещения таблицы во временную таблицу

Теперь мы готовы написать текст запроса. Первым делом мы должны выбрать данные из нашего параметра и поместить их во временную таблицу с помощью инструкции ПОМЕСТИТЬ. Посмотрим на практический пример:


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

// Передаем нашу таблицу в параметры запроса
Запрос.УстановитьПараметр("ВнешняяТаблица", ТаблицаДанных);

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

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

Обратите внимание на использование символа ; (точка с запятой). В 1С это разделитель пакетов запроса. В первом пакете мы создаем временную таблицу ВТ_Данные, во втором — используем её для соединения с реальными данными информационной базы.

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

Если ваша таблица значений содержит тысячи строк, соединение с ней может работать медленно. Выясним причину: без индекса SQL-сервер вынужден выполнять полный перебор временной таблицы при каждом сопоставлении строк. Чтобы ускорить процесс, проанализируем необходимость индексации.

Добавим инструкцию ИНДЕКСИРОВАТЬ ПО в наш запрос:


Запрос.Текст = 
"ВЫБРАТЬ
|	ТЗ.Номенклатура КАК Номенклатура,
|	ТЗ.Количество КАК Количество
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
|	&ВнешняяТаблица КАК ТЗ
|ИНДЕКСИРОВАТЬ ПО
|	Номенклатура";

Важное правило: индексировать следует только те поля, по которым в дальнейшем будет происходить СОЕДИНЕНИЕ или ГДЕ. Избыточная индексация может, наоборот, замедлить создание временной таблицы.

Типичные ошибки при работе с ТЗ в запросах

Заключение

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

← На главную