Разработка и Конфигурация · 10 мин
Как добавить таблицу в запрос 1С
Как добавить таблицу значений в запрос 1С через параметр, поместить её во временную таблицу, соединить с данными базы и избежать типичных ошибок при работе.
В языке запросов 1С нельзя напрямую вставить произвольный набор строк, подготовленный в коде. Чтобы использовать такие данные в выборке, таблицу значений передают в запрос как параметр, а затем помещают во временную таблицу через конструкцию ПОМЕСТИТЬ. Это стандартный и самый производительный способ соединить «внешние» данные с данными информационной базы.
Типовые сценарии, где это нужно: фильтрация документов по списку ссылок, загруженному из файла; сопоставление номенклатуры с данными из Excel; расчёт по таблице, собранной алгоритмом в коде; передача результата одного запроса в другой без повторного обращения к базе. Во всех этих случаях механизм одинаковый — отличается только содержимое передаваемой таблицы.
Ниже разобран полный цикл: подготовка таблицы значений в коде, передача её параметром, помещение во временную таблицу, соединение с реальными таблицами базы, а также ограничения и ошибки, которые чаще всего мешают получить результат.
Какой механизм использовать и почему
В языке запросов 1С источником данных может быть либо таблица базы данных, либо параметр-таблица, переданный из кода. Прямой вставки строк в текст запроса не существует — язык не поддерживает конструкторы значений наподобие VALUES в чистом SQL. Поэтому единственный корректный путь — параметр типа «ТаблицаЗначений».
Переданную таблицу почти всегда сначала помещают во временную таблицу (ПОМЕСТИТЬ ВТ_Данные). Это даёт два преимущества: временную таблицу можно использовать в нескольких последующих запросах пакета, и платформа может построить по ней индекс, что ускоряет соединения. Если обратиться к параметру напрямую в соединении, запрос тоже сработает, но гибкость и производительность будут ниже.
Шаг 1. Подготовьте таблицу значений в коде
Создайте объект ТаблицаЗначений и явно опишите колонки с типами. Типизация критична: если колонка не типизирована или содержит значения разных типов, запрос может не сработать или соединение будет работать некорректно.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Номенклатура = СсылкаНаТовар;
НоваяСтрока.Количество = 10;
Имена колонок в таблице значений станут именами полей в запросе — используйте осмысленные названия без пробелов и спецсимволов. Для ссылочных колонок всегда указывайте конкретный тип ссылки, а не составной, если он не нужен: это упрощает соединение и снижает риск ошибок приведения типов.
Шаг 2. Передайте таблицу параметром и поместите во временную таблицу
Таблица передаётся методом УстановитьПараметр, а в тексте запроса к ней обращаются через амперсанд: &ТЗ. Первый запрос пакета выбирает данные из параметра и помещает их во временную таблицу.
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТЗ", ТЗ);
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Номенклатура КАК Номенклатура,
| ТЗ.Количество КАК Количество
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| &ТЗ КАК ТЗ
|;
|
|ВЫБРАТЬ
| ВТ.Номенклатура КАК Номенклатура,
| ВТ.Количество КАК Количество,
| ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
| ВТ_Данные КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
| ПО ВТ.Номенклатура = Остатки.Номенклатура";
Результат = Запрос.Выполнить().Выгрузить();
Обратите внимание: менеджер временных таблиц нужно создать явно, если временная таблица используется более чем в одном запросе пакета или должна жить между вызовами. Без менеджера временная таблица не сохранится.
- 1Создайте ТаблицаЗначений и типизируйте колонки через ОписаниеТипов
- 2Заполните таблицу строками в коде
- 3Создайте Запрос и назначьте МенеджерВременныхТаблиц
- 4Передайте таблицу: Запрос.УстановитьПараметр("ТЗ", ТЗ)
- 5Напишите запрос: ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЗ КАК ТЗ
- 6Соедините временную таблицу с таблицами базы
- 7Выполните запрос и проверьте число строк результата
Шаг 3. Соедините временную таблицу с данными базы
Чаще всего используется ЛЕВОЕ СОЕДИНЕНИЕ: временная таблица слева, таблица базы справа. Тогда в результат попадут все строки переданной таблицы, даже если в базе соответствий нет — поля из базы будут NULL, что удобно обрабатывать функцией ЕСТЬNULL.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ применяйте, когда нужны только совпадающие записи — например, отобрать остатки строго по списку номенклатуры из файла. Учтите: если в переданной таблице есть дубли ключевых полей, соединение размножит строки результата. Перед соединением дубли лучше свернуть:
ТЗ.Свернуть("Номенклатура", "Количество");
Условия по полям временной таблицы (секция ГДЕ) работают так же, как с обычными таблицами. Можно фильтровать, группировать и сортировать — временная таблица полноценный источник данных внутри пакета запросов.
Сравнение вариантов
Универсальный способ: индексирование, использование в нескольких запросах, высокая производительность. Требует менеджера временных таблиц.
Подходит для разового простого запроса. Меньше кода, но нет индекса по таблице и повторного использования.
Подходит, если нужно только отфильтровать по списку ссылок без дополнительных полей. Не подходит, когда к каждой строке привязаны свои числа или строки.
Проверка результата и контрольные точки
После выполнения запроса сверьте количество строк результата с количеством строк исходной таблицы. При левом соединении строк не должно стать меньше; если стало больше — в данных есть дубли ключей. Для отладки удобно выполнить отдельный запрос ВЫБРАТЬ * ИЗ ВТ_Данные и убедиться, что временная таблица наполнилась ожидаемо.
Как проверить результат
Равно числу строк исходной ТЗ (при левом соединении)
Меньше — потеряны строки; больше — дубли ключей
Заполнены ссылками нужного типа
NULL или пустые ссылки — проблема типизации колонки
Суммы и количества совпадают с исходными
Округление или NULL — неверный тип колонки
Типичные ошибки и ограничения
Первая частая ошибка — обращение к параметру &ТЗ в соединении без помещения во временную таблицу при сложном пакете: запрос может работать медленно, потому что платформа не строит индекс по параметру. Вторая — неявная типизация: колонка, заполненная значениями разных типов, приводит к ошибке выполнения или тихой потере строк.
Третья ошибка — забыть назначить МенеджерВременныхТаблиц. Тогда при попытке использовать временную таблицу во втором запросе возникает ошибка «Таблица не найдена». Ещё одна ловушка — передача очень больших таблиц (сотни тысяч строк): данные целиком передаются на сервер, что может быть медленно и потреблять много памяти. В таких случаях рассмотрите пакетную обработку порциями.
Альтернативы и смежные приёмы
Если нужно только отфильтровать выборку по списку ссылок, передавать таблицу не обязательно — достаточно параметра со списком значений и условия ГДЕ Ссылка В (&Список). Это проще и быстрее, чем полноценная временная таблица.
Если данные уже находятся в результате другого запроса, не выгружайте их в таблицу значений и не передавайте обратно — поместите результат первого запроса во временную таблицу через тот же менеджер и используйте её во втором запросе. Так данные не покидают сервер и не тратится время на сериализацию.
Для обмена с внешними источниками (Excel, CSV) сначала загрузите файл в таблицу значений штатными средствами или через ПостроительЗапроса, а дальше действуйте по описанной выше схеме — механизм не меняется.
Что важно запомнить
Таблица значений попадает в запрос только через параметр: УстановитьПараметр + ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ ИЗ &ТЗ. Типизируйте колонки, сворачивайте дубли, назначайте менеджер временных таблиц и проверяйте число строк результата после соединения.
Частые вопросы
Можно ли передать в запрос табличную часть документа?
Да. Вызовите у табличной части метод Выгрузить() — получите таблицу значений, которую передаёте параметром обычным способом. При необходимости ограничьте набор колонок через Выгрузить(Новый Структура(...)) или сверните данные перед передачей.
Почему запрос выдаёт ошибку «Неверные параметры в операции сравнения»?
Обычно причина в несовпадении типов: поле временной таблицы сравнивается с полем другого типа или колонка таблицы значений содержит значения разных типов. Проверьте описание типов колонки и приведите значения к одному типу до передачи.
Нужно ли уничтожать временную таблицу после использования?
Не обязательно: она удалится вместе с менеджером временных таблиц. Но в длинных пакетах запросов явная команда УНИЧТОЖИТЬ ВТ_Данные освобождает память сервера и считается хорошей практикой, особенно при больших объёмах.
Можно ли передать в запрос дерево значений?
Напрямую нет — параметром передаётся только таблица значений. Преобразуйте дерево в таблицу, добавив при необходимости колонку с идентификатором родителя, чтобы сохранить иерархию, и передавайте её.
Что быстрее: соединение с временной таблицей или условие В (&Список)?
Для простой фильтрации по одному полю условие В со списком обычно не медленнее и проще. Временная таблица выигрывает, когда к каждой строке привязано несколько полей или её нужно использовать в нескольких запросах пакета.
Работает ли передача таблицы в запрос в тонком клиенте?
Да, механизм одинаковый. Но учитывайте, что таблица значений будет передана с клиента на сервер при вызове серверной процедуры, поэтому большие таблицы лучше формировать и обрабатывать целиком на сервере.