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