Разработка и Конфигурация · 9 мин
Как в запрос 1С добавить таблицу значений
Как передать таблицу значений в запрос 1С через параметр, создать временную таблицу и соединить её с данными базы. Примеры кода, ошибки и проверка результата.
Встроенный язык запросов 1С не умеет напрямую читать таблицу значений — она не хранится в базе данных. Чтобы использовать её данные в запросе, таблицу передают через параметр и преобразуют во временную таблицу конструкцией ПОМЕСТИТЬ. После этого с ней можно работать как с обычной таблицей: соединять с регистрами и справочниками, фильтровать, группировать.
Такой приём нужен в типовых задачах: отобрать документы по списку, сформированному вне запроса; подставить в отчёт данные, рассчитанные алгоритмом; сопоставить загруженный из Excel прайс с номенклатурой базы. Без временной таблицы пришлось бы перебирать строки в цикле и выполнять десятки отдельных запросов, что заметно медленнее.
Ниже разобран полный рабочий сценарий: подготовка таблицы значений, передача её в запрос, создание временной таблицы, соединение с данными базы, а также типичные ошибки и ограничения метода.
Когда таблицу значений нужно передавать в запрос
Механизм оправдан, когда источник данных — не база. Например, вы загрузили файл с артикулами поставщика и хотите одним запросом найти соответствия в справочнике «Номенклатура». Или алгоритм рассчитал список контрагентов с особыми условиями, и по этому списку нужно выбрать документы.
Вторая типичная ситуация — оптимизация. Если по коллекции из нескольких тысяч элементов выполнять запрос в цикле, каждый проход — это обращение к СУБД. Передача всей коллекции одной таблицей сокращает работу до одного запроса с соединением.
Если же данные уже лежат в базе в виде регистра или справочника, таблица значений не нужна — пишите обычный запрос напрямую к этим таблицам. Промежуточная материализация только добавит расход памяти.
Как выбрать подход
Подготовка таблицы значений перед передачей
Таблица значений должна иметь явно описанные колонки с типами. Если колонки создавались через Таблица.Колонки.Добавить() без указания типа, платформа попытается вывести тип по содержимому, и при пустой таблице или смешанных значениях запрос завершится ошибкой.
Рекомендуется задавать типы через ОписаниеТипов. Для ссылочных полей указывайте конкретный тип ссылки, а не составной «любая ссылка» — это упрощает соединение и позволяет обращаться к реквизитам через точку.
ТаблицаАртикулов = Новый ТаблицаЗначений;
ТаблицаАртикулов.Колонки.Добавить("Артикул",
Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
ТаблицаАртикулов.Колонки.Добавить("Цена",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
// заполнение строк
НоваяСтрока = ТаблицаАртикулов.Добавить();
НоваяСтрока.Артикул = "П-100245";
НоваяСтрока.Цена = 1250.50;
Проверьте, что в таблице нет строк с незаполненными ключевыми полями, если по ним планируется соединение: пустые значения дадут лишние строки с NULL или неожиданные совпадения.
Передача таблицы в запрос и создание временной таблицы
Таблица передаётся через метод УстановитьПараметр, а в тексте запроса на неё ссылаются как на источник данных: ИЗ &ТаблицаАртикулов КАК ТаблицаАртикулов. Результат первого пакета помещают во временную таблицу.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаАртикулов.Артикул КАК Артикул,
| ТаблицаАртикулов.Цена КАК Цена
|ПОМЕСТИТЬ ВТ_Артикулы
|ИЗ
| &ТаблицаАртикулов КАК ТаблицаАртикулов
|;
|
|ВЫБРАТЬ
| ВТ_Артикулы.Артикул КАК Артикул,
| ВТ_Артикулы.Цена КАК ЦенаИзФайла,
| Номенклатура.Ссылка КАК Номенклатура
|ИЗ
| ВТ_Артикулы КАК ВТ_Артикулы
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ_Артикулы.Артикул = Номенклатура.Артикул";
Запрос.УстановитьПараметр("ТаблицаАртикулов", ТаблицаАртикулов);
Результат = Запрос.Выполнить().Выгрузить();
Первый пакет запроса материализует таблицу значений во временную таблицу ВТ_Артикулы. Второй пакет соединяет её со справочником. Левое соединение сохранит строки из файла, даже если артикул в базе не найден — поле «Номенклатура» в таких строках будет NULL, что удобно для контроля незагруженных позиций.
Соединение временной таблицы с данными базы
Отбор по списку значений
Если нужна только фильтрация, соединение заменяют условием на вхождение: ГДЕ Документ.Номенклатура В (ВЫБРАТЬ Т.Ссылка ИЗ ВТ_Таблица КАК Т). Это эквивалент внутреннего соединения без умножения строк.
Соединение по нескольким полям
Ключ соединения может быть составным — например, организация плюс договор. Перечислите все условия через И в секции ПО. Следите за совпадением типов: соединение строки с числом не вызовет ошибку, но совпадений не найдёт.
Обращение к реквизитам ссылок из временной таблицы
Если колонка таблицы значений содержит ссылки, во втором пакете можно обращаться к их реквизитам через точку: ВТ.Контрагент.ИНН. Это работает, только если тип колонки — конкретный ссылочный тип, а не составной.
Для больших таблиц добавьте во временную таблицу индекс: после ПОМЕСТИТЬ ВТ_Артикулы укажите ИНДЕКСИРОВАТЬ ПО Артикул. На объёмах от нескольких тысяч строк это заметно ускоряет соединение.
Ограничения и производительность
Передаваемая таблица целиком сериализуется и материализуется на сервере СУБД как временная таблица. Десятки тысяч строк — обычно рабочий объём, но сотни тысяч строк с широким набором колонок могут привести к заметному расходу памяти и времени на передачу.
Если объём большой, рассмотрите альтернативы: загрузку данных в промежуточный регистр сведений, разбиение таблицы на порции с объединением результатов, либо перенос логики в СКД с набором данных-объектом.
Учитывайте, что временная таблица живёт в рамках одного выполнения запроса (или менеджера временных таблиц). Между отдельными вызовами Выполнить() без общего менеджера она не сохраняется.
Типичные ошибки и их диагностика
Самая частая ошибка — «Поле не найдено» или «Неверные параметры в операции сравнения». Причины: несовпадение имён колонок с полями в запросе, не задан тип колонки, либо тип значения в строках не соответствует описанию.
Вторая группа ошибок — пустой результат при корректном запросе. Обычно это несовпадение данных: лишние пробелы в артикулах, разный регистр букв при сравнении в файловой базе, несоответствие типов в условии соединения.
Как проверить результат
Совпадает с ожиданием по логике соединения (при левом соединении — не меньше строк исходной таблицы)
Строк больше исходной таблицы при внутреннем соединении — дубли в ключе
Ключевые поля заполнены, NULL только там, где соответствия реально нет
Все поля базы NULL — условие соединения не сработало
Запрос выполняется за приемлемое для операции время
Резкий рост времени при увеличении таблицы — нет индекса по полю соединения
Часто задаваемые вопросы
Можно ли передать таблицу значений в запрос без создания временной таблицы?
Нет, параметр-таблицу можно использовать только как источник в конструкции ИЗ &Таблица, а результат нужно куда-то поместить — во временную таблицу или сразу вывести как итоговый результат. На практике почти всегда делают ПОМЕСТИТЬ во временную таблицу и работают с ней дальше.
Чем передача таблицы отличается от условия В (&Массив)?
Массив подходит для отбора по одному простому полю и небольшого списка значений. Таблица значений нужна, когда передаётся несколько связанных колонок (например, артикул и цена одновременно), когда список очень большой или когда по данным таблицы требуется соединение, а не только фильтр.
Работает ли этот механизм в СКД?
Да, но иначе. В СКД таблицу значений подключают как набор данных типа «Объект» с указанием имени параметра, а саму таблицу передают через свойство объекта настроек компоновщика. Внутри запроса СКД набор-объект описывается той же конструкцией ИЗ &Таблица.
Почему запрос с таблицей значений работает в толстом клиенте, но падает на сервере?
Таблица значений сериализуется при передаче между клиентом и сервером. Проверьте, что в колонках нет несериализуемых типов и что код, формирующий таблицу, доступен в контексте сервера. Также убедитесь, что директива компиляции процедуры соответствует месту вызова.
Можно ли использовать одну временную таблицу в нескольких запросах?
Да, если всем запросам назначить общий МенеджерВременныхТаблиц. Тогда временная таблица, созданная первым запросом, доступна последующим. После работы менеджер следует закрыть, чтобы освободить ресурсы СУБД.
Что важно запомнить
Таблица значений попадает в запрос через параметр и конструкцию ИЗ &Таблица ПОМЕСТИТЬ ВТ. Опишите колонки с типами, совместите имена колонок и полей запроса, при больших объёмах добавьте индекс и проверьте результат на дубли и NULL в полях соединения.