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