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