К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как передать параметр в запрос 1С

Как передать параметр в запрос 1С через УстановитьПараметр: типы значений, списки, даты, таблицы значений, типичные ошибки и проверка результата с примерами кода.

Параметры в запросе 1С — это значения, которые подставляются в текст запроса во время выполнения: отбор по контрагенту, граница периода, список номенклатуры. Вместо конкатенации строк с текстом запроса всегда используется механизм параметров: он безопаснее, проще для отладки и позволяет платформе корректно приводить типы.

Передача параметра выполняется методом УстановитьПараметр() объекта Запрос. В тексте запроса параметр обозначается символом амперсанда перед именем: &Контрагент, &ДатаНачала. Один и тот же параметр можно использовать в тексте несколько раз — значение устанавливается один раз.

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

Базовый синтаксис: как объявить и передать параметр

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Родитель = &Группа

| И НЕ Номенклатура.ПометкаУдаления";

Запрос.УстановитьПараметр("Группа", ГруппаНоменклатуры);

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

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

// обработка строки

КонецЦикла;

Имя параметра в УстановитьПараметр пишется без амперсанда — только имя. Если в тексте параметр указан как &Группа, то метод вызывается как УстановитьПараметр("Группа", Значение). Регистр имени значения не имеет.

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

Передача значений разных типов

Метод УстановитьПараметр принимает значения большинства встроенных типов: строки, числа, даты, булево, ссылки на объекты базы. Платформа сама приводит значение к типу поля, с которым идёт сравнение, но лучше передавать совместимые типы явно.

Ссылки и примитивные типы

Ссылка передаётся как есть — переменная типа СправочникСсылка или ДокументСсылка. Дата передаётся как значение типа Дата; если нужна граница конца дня, используйте КонецДня(Дата) или объект Граница, иначе документы за последние секунды дня могут не попасть в выборку.

Запрос.УстановитьПараметр("Контрагент", КонтрагентСсылка);

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(Период.ДатаНачала));

Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(Период.ДатаОкончания));

Запрос.УстановитьПараметр("МинимальнаяСумма", 10000);

Пустые значения и NULL

Чтобы отобрать записи с незаполненным значением, передайте пустую ссылку (Справочники.Номенклатура.ПустаяСсылка()) или используйте конструкцию ЗНАЧЕНИЕ(...) прямо в тексте. Значение Неопределено в запрос передать нельзя — оно не имеет аналога в языке запросов, а NULL сравнивается только через ЕСТЬ NULL.

Передача списков и массивов для условия В (IN)

Когда нужно отобрать данные по нескольким значениям сразу — например, по списку складов или видов документов — параметру присваивается массив или СписокЗначений, а в тексте запроса используется оператор В (&Список). Скобки вокруг имени параметра обязательны.

МассивСкладов = Новый Массив;

МассивСкладов.Добавить(СкладОсновной);

МассивСкладов.Добавить(СкладРезервный);

Запрос.Текст =

"ВЫБРАТЬ

| Остатки.Номенклатура КАК Номенклатура,

| Остатки.КоличествоОстаток КАК Остаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад В (&Склады)) КАК Остатки";

Запрос.УстановитьПараметр("Склады", МассивСкладов);

Все элементы массива должны иметь один тип или типы, приводимые к общему (например, ссылки разных видов документов в составном поле). Пустой массив приведёт к тому, что условие В (&Склады) не пропустит ни одной записи — результат будет пустым, и это частая причина «пропавших» данных.

Типичные ошибки
01
Передача пустого массива в условие В (&Список) — запрос возвращает ноль строк, и это выглядит как потеря данных
02
Установка параметра после вызова Выполнить() — значение не попадает в запрос
03
Имя с амперсандом в УстановитьПараметр("&Склад", ...) — платформа ищет параметр с другим именем
04
Сравнение даты без учёта времени: документы за конец дня выпадают из выборки

Параметры виртуальных таблиц регистров

Виртуальные таблицы — Остатки, Обороты, СрезПоследних, СрезПервых — принимают параметры прямо в круглых скобках после имени таблицы. Именно здесь параметры запроса дают основной выигрыш в производительности: отбор применяется на уровне СУБД до соединения таблиц.

Запрос.Текст =

"ВЫБРАТЬ

| Срез.Номенклатура КАК Номенклатура,

| Срез.Цена КАК Цена

|ИЗ

| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, ТипЦен = &ТипЦен) КАК Срез";

Запрос.УстановитьПараметр("ДатаСреза", ТекущаяДатаСеанса());

Запрос.УстановитьПараметр("ТипЦен", ТипЦенЗакупка);

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

Если запрос к виртуальной таблице работает медленно, первым делом проверьте, что отборы по измерениям стоят в круглых скобках виртуальной таблицы, а не в секции ГДЕ. Это самая частая причина деградации производительности.
ПЗ
Практическое замечание

Передача таблицы значений как параметра

Когда отбор строится по паре «номенклатура + характеристика» или по произвольному набору строк, удобно передать в запрос целую таблицу значений. Таблица помещается во временную таблицу через конструкцию ПОМЕСТИТЬ, а затем соединяется с основными данными.

Запрос = Новый Запрос;

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

Запрос.Текст =

"ВЫБРАТЬ

| ТЗ.Номенклатура КАК Номенклатура,

| ТЗ.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ

| &ТаблицаТоваров КАК ТЗ

|;

|ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| Товары.Количество КАК Количество

|ИЗ

| ВТ_Товары КАК Товары";

Запрос.УстановитьПараметр("ТаблицаТоваров", ТаблицаЗначенийТоваров);

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

Ограничения: колонки таблицы значений должны иметь явно заданные типы (создавайте их через Новый ОписаниеТипов), иначе платформа может не определить тип поля во временной таблице. Пакет из нескольких запросов разделяется точкой с запятой, а для временных таблиц нужен МенеджерВременныхТаблиц, если к ним обращаются несколько запросов подряд.

Порядок действий
  1. 1
    Создайте объект: Запрос = Новый Запрос
  2. 2
    Присвойте Запрос.Текст с плейсхолдерами &Имя
  3. 3
    Вызовите Запрос.УстановитьПараметр для каждого параметра
  4. 4
    Выполните запрос: Выполнить() или Выгрузить()
  5. 5
    Проверьте результат: Результат.Пустой() и число строк в выборке

Проверка результата и отладка параметров

После выполнения запроса первым делом проверяйте Результат.Пустой() — это отделяет ситуацию «нет данных» от ошибок обхода выборки. Если результат пуст, хотя данные в базе есть, почти всегда дело в значении параметра: несовпадение типа, пустая ссылка, неверная граница даты.

Быстрый способ отладки — вывести значения параметров в сообщение перед выполнением или временно заменить параметр на литерал ЗНАЧЕНИЕ(...) в консоли запросов. Консоль запросов (внешняя обработка или встроенная в режиме предприятия у некоторых конфигураций) показывает фактические значения параметров и позволяет выполнить запрос пошагово.

Контрольные точки

Как проверить результат

Статус результата
Норма

Результат.Пустой() = Ложь, выборка обходит строки

Тревожный признак

Пустой результат при наличии данных в базе

Значения параметров
Норма

Тип значения совпадает с типом поля сравнения

Тревожный признак

В параметре Неопределено или ссылка другого вида

Границы периода
Норма

Конец периода задан как КонецДня() или Граница

Тревожный признак

Документы за последний день не попадают в выборку

Отдельный случай — запросы в динамических списках и СКД. Там параметры задаются не кодом, а через свойства компоновки: КомпоновщикНастроек.Настройки.ПараметрыДанных. Принцип тот же, но значение привязывается к элементу настроек, а не к объекту Запрос.

Итог

Что важно запомнить

Параметр объявляется в тексте как &Имя, значение задаётся через УстановитьПараметр до выполнения запроса. Списки передаются массивом с оператором В (&Список), таблицы — через ПОМЕСТИТЬ во временную таблицу. Пустой результат чаще всего означает ошибку в значении параметра, а не отсутствие данных.

Часто задаваемые вопросы

Можно ли передать параметр прямо в строку текста запроса конкатенацией?

Технически строку можно собрать через подстановку, но делать так не следует: теряется контроль типов, появляется риск ошибок с кавычками и форматом дат, а код становится трудно отлаживать. Механизм параметров решает все эти задачи штатно.

Что будет, если установить параметр, которого нет в тексте запроса?

Ничего страшного: лишний параметр игнорируется при выполнении. Ошибка возникает только в обратной ситуации — когда параметр есть в тексте, но значение ему не установлено.

Как передать в запрос значение NULL?

Напрямую через УстановитьПараметр передать NULL нельзя. Используйте в тексте запроса литерал NULL и оператор ЕСТЬ NULL, либо передавайте пустую ссылку соответствующего типа, если нужно сравнение с незаполненным значением.

Почему условие В (&Список) не находит записи, хотя массив заполнен?

Проверьте типы элементов массива: они должны совпадать с типом сравниваемого поля. Частая причина — в массив попали строки вместо ссылок или ссылки другого вида объектов. Также убедитесь, что имя параметра в УстановитьПараметр указано без амперсанда.

Как передать параметр в запрос динамического списка?

Через настройки компоновки: найдите параметр в КомпоновщикНастроек.Настройки.ПараметрыДанных, установите Использование = Истина и присвойте Значение. Для списка на форме это делается в обработчике ПриСозданииНаСервере или ПриОткрытии.

Нужен ли МенеджерВременныхТаблиц для одного запроса с ПОМЕСТИТЬ?

Для одного пакетного запроса менеджер не обязателен — временные таблицы живут внутри выполнения. Менеджер нужен, когда временная таблица создаётся одним запросом, а читается другим, или когда к ней обращаются повторно.