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