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