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

Эта статья раскроет суть параметров в запросах 1С 8.3 и 1С 8.2, покажет их отличие от переменных, объяснит синтаксис объявления и использования. Мы разберём типичные сценарии применения — от простой фильтрации до сложных динамических отчётов, а также предупредим о подводных камнях, с которыми сталкиваются даже опытные программисты.

Параметры vs переменные: в чём разница?

Многие новички путают параметры запроса с обычными переменными в коде . Разница принципиальна:

  • 🔹 Переменные — это объекты языка , которые существуют в контексте модуля (например, Перем МояПеременная;). Их можно менять в процессе выполнения программы.
  • 🔹 Параметры запроса — это специальные "заменители" значений, которые подставляются в текст запроса перед его выполнением. Они объявлены только в контексте конкретного запроса и недоступны за его пределами.

Ключевое отличие: параметры не могут быть изменены после передачи в запрос, тогда как переменные можно модифицировать в любом месте кода. Например, если вы передали в запрос параметр ДатаНачала = '2026-01-01', то внутри текста запроса это значение станет константой.

Ещё одно важное свойство параметров — они типизированы. При объявлении нужно указать тип данных (Дата, Число, Строка и т.д.), что помогает оптимизировать выполнение запроса и избегать ошибок несоответствия типов.

📊 Как часто вы используете параметры в запросах 1С?
Постоянно, в каждом отчёте
Иногда, для динамической фильтрации
Рядом, но предпочитаю переменные
Никогда не использовал

Синтаксис объявления параметров в запросе

Параметры объявляются в начале текста запроса после ключевого слова ПАРАМЕТРЫ (или PARAMETERS в англоязычной нотации). Общий формат:

ПАРАМЕТРЫ

ИмяПараметра1 ТипДанных1,

ИмяПараметра2 ТипДанных2;

Примеры корректных объявлений:

  • 📅 ПАРАМЕТРЫ ДатаНачала Дата; — параметр для фильтрации по дате.
  • 💰 ПАРАМЕТРЫ МинимальнаяСумма Число(10, 2); — числовой параметр с указанием точности.
  • 📝 ПАРАМЕТРЫ Поставщик СправочникСсылка.Контрагенты; — ссылка на элемент справочника.

Обратите внимание: после объявления параметров обязательно ставится точка с запятой. Тип данных должен соответствовать тому, что ожидает запрос. Например, если вы фильтруете по полю типа Булево, то параметр тоже должен быть булевым:

ПАРАМЕТРЫ ТолькоАктивные Булево;
💡

Используйте осмысленные имена параметров (например, ДатаОтчета вместо П1). Это упрощает поддержку кода и снижает риск ошибок при изменении логики.

Как передавать значения в параметры?

Объявление параметров — только половина дела. Чтобы они заработали, нужно передать им конкретные значения. Это делается с помощью метода УстановитьПараметр() объекта Запрос:

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

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

"ПАРАМЕТРЫ

| ДатаНачала Дата;

|ВЫБРАТЬ

| Документ.Дата КАК ДатаДокумента

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

|ГДЕ

| Документ.Дата >= &ДатаНачала";

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

Важные нюансы:

  • 🔗 Имя параметра в методе УстановитьПараметр() должно точно совпадать с именем в тексте запроса (регистр не важен).
  • 📌 В самом тексте запроса параметр обозначается символом & (например, &ДатаНачала).
  • ⚠️ Если параметр не установлен, вызовет ошибку при выполнении запроса.

Для передачи нескольких параметров используйте многократный вызов УстановитьПараметр():

Запрос.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата()));

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

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

Если передать в параметр значение несовместимого типа (например, строку вместо даты), сгенерирует ошибку на этапе выполнения запроса. Например, при попытке сравнить дату с строкой появится сообщение: "Ошибка при вызове метода контекста (Выполнить): Тип не совпадает с ожидаемым (Дата)".

Типичные ошибки при работе с параметрами

Даже опытные разработчики иногда допускают ошибки при использовании параметров. Вот наиболее распространённые:

Ошибка Причина Как исправить
Не объявлен параметр в тексте запроса В коде используется &Параметр, но в секции ПАРАМЕТРЫ его нет Добавить объявление параметра с правильным типом
Несоответствие типов Параметр объявлен как Число, а передаётся Строка Привести значение к нужному типу перед передачей
Опечатка в имени параметра В УстановитьПараметр() указано "ДатаНачало", а в запросе &ДатаНачала Проверить совпадение имён (регистр не важен)
Пропущена точка с запятой после ПАРАМЕТРЫ Синтаксическая ошибка в тексте запроса Добавить ; после объявления параметров

Особенно коварна ошибка с неявным приведением типов. Например, если параметр объявлен как Число, а вы передаёте строку "100", то в некоторых случаях автоматически преобразует её в число. Однако это не гарантируется и может привести к трудноуловимым багам. Всегда следите за соответствием типов!

⚠️ Внимание: При работе с параметрами типа СправочникСсылка или ДокументСсылка убедитесь, что передаваемая ссылка существует в базе. Иначе запрос вернёт пустой результат без ошибок.

Практические примеры использования параметров

Рассмотрим реальные сценарии, где параметры незаменимы.

Пример 1: Фильтрация документов по периоду

Типичная задача — выборка документов за определённый интервал дат. Параметры позволяют сделать запрос универсальным:

ПАРАМЕТРЫ

ДатаНачала Дата,

ДатаОкончания Дата;

ВЫБРАТЬ

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

Документ.Дата КАК Дата,

Документ.СуммаДокумента КАК Сумма

ИЗ

Документ.ПоступлениеТоваровУслуг КАК Документ

ГДЕ

Документ.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

В коде:

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

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

Пример 2: Динамический отбор по справочнику

Допустим, нужно получить список номенклатуры определённого вида. Параметр типа СправочникСсылка поможет избежать жёсткой привязки к конкретному элементу:

ПАРАМЕТРЫ

ВидНоменклатуры СправочникСсылка.ВидыНоменклатуры;

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

Номенклатура.ВидНоменклатуры = &ВидНоменклатуры

Передаём значение:

ВидыНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товары");

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

Пример 3: Условная логика с параметрами

Параметры можно использовать в выражениях ВЫРАЗИТЬ или ГДЕ для реализации сложной логики. Например, выборка клиентов с учётом флага "Только VIP":

ПАРАМЕТРЫ

ТолькоVIP Булево;

ВЫБРАТЬ

Клиент.Наименование КАК Клиент,

Клиент.Категория КАК Категория

ИЗ

Справочник.Контрагенты КАК Клиент

ГДЕ

(&ТолькоVIP И Клиент.Категория = ЗНАЧЕНИЕ(Перечисление.КатегорииКлиентов.VIP))

ИЛИ НЕ &ТолькоVIP

Объявлены все используемые параметры в секции ПАРАМЕТРЫ|Типы параметров соответствуют типам полей в запросе|Все параметры инициализированы методом УстановитьПараметр()|В тексте запроса параметры указаны с символом &-->

Оптимизация запросов с параметрами

Неправильное использование параметров может привести к перекомпиляции плана выполнения запроса при каждом вызове, что замедляет работу. Следуйте этим рекомендациям для оптимизации:

  • 🚀 Избегайте динамического формирования текста запроса. Лучше использовать параметры, чем конкатенацию строк (например, через СтрЗаменить()).
  • 📊 Для часто используемых запросов создавайте предопределённые данные (например, справочник с типичными фильтрами) и передавайте их как параметры.
  • 🔍 Используйте индексы. Если параметр участвует в условии ГДЕ, убедитесь, что соответствующее поле проиндексировано в базе.

Пример неэффективного подхода (динамический SQL):

ТекстЗапроса = "ВЫБРАТЬ * ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= '" + Формат(ДатаНачала, "ДЛФ=DT") + "'";

Это приводит к тому, что каждый раз заново анализирует запрос. Правильный вариант — с параметром:

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

"ПАРАМЕТРЫ ДатаНачала Дата;

ВЫБРАТЬ * ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= &ДатаНачала";

⚠️ Внимание: При работе с большими базами (100 000+ записей) избегайте передачи в параметры массивов или таблиц значений через ЗНАЧЕНИЕ(). Это может привести к значительному увеличению времени выполнения. Вместо этого используйте временные таблицы.

Параметры в отчётах и внешних обработках

В отчётах (например, в СКД — системе компоновки данных) параметры играют особую роль. Они позволяют:

  • 📈 Создавать интерактивные формы с полями ввода для пользователя.
  • 🔄 Переиспользовать одну схему компоновки для разных сценариев (например, отчёт по продажам и по закупкам).
  • 👥 Ограничивать доступ к данным в зависимости от ролей пользователей.

Пример объявления параметра в схеме компоновки данных:

&НаКлиенте

Процедура КомандаСформировать(Команда)

Отчет = Отчеты.Продажи.Создать();

Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначение("ДатаНачала", НачалоМесяца(ТекущаяДата()));

Отчет.Скомпоновать();

КонецПроцедуры

В самой схеме компоновки параметр объявляется в разделе Параметры с указанием типа и доступных значений (например, список справочников или перечисление).

Для внешних обработок параметры позволяют сделать решение универсальным. Например, обработка выгрузки данных в Excel может принимать параметры:

  • 📌 Формат файла (XLSX или CSV).
  • 📂 Путь сохранения.
  • 🔍 Фильтры данных (период, организация и т.д.).
💡

Использование параметров в отчётах и обработках сокращает количество дублирующего кода и упрощает поддержку системы. Один универсальный отчёт с параметрами может заменить десятки специализированных.

FAQ: Частые вопросы о параметрах в запросах 1С

Можно ли использовать параметры в подзапросах?

Да, параметры доступны во всех частях запроса, включая подзапросы. Например:

ПАРАМЕТРЫ ДатаОтсечки Дата;

ВЫБРАТЬ

Клиент.Наименование

ИЗ

Справочник.Контрагенты КАК Клиент

ГДЕ

EXISTS(

ВЫБРАТЬ 1

ИЗ Документ.ЗаказПокупателя КАК Заказ

ГДЕ Заказ.Клиент = Клиент.Ссылка

И Заказ.Дата >= &ДатаОтсечки

)

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

Прямо передать массив нельзя, но можно:

  1. Использовать временную таблицу (рекомендуется для больших массивов).
  2. Передать массив как строку и разобрать её в запросе с помощью ЗНАЧЕНИЕ() и РАЗДЕЛИТЬ() (неэффективно для больших данных).

Пример с временной таблицей:

// Создаём временную таблицу

ВТ_Фильтр = Новый ТаблицаЗначений;

ВТ_Фильтр.Колонки.Добавить("Значение", Новый ОписаниеТипов("Строка"));

// Заполняем данными

Для Каждого Элемент Из МассивЗначений Цикл

Строка = ВТ_Фильтр.Добавить();

Строка.Значение = Элемент;

КонецЦикла;

// Передаём во временную таблицу запроса

Запрос.МенеджерВременныхТаблиц.ДобавитьВременнуюТаблицу(ВТ_Фильтр, "Фильтр");

Что быстрее: параметры или жёстко прописанные значения?

Параметры практически не влияют на производительность, если они правильно типизированы. оптимизирует план выполнения запроса с учётом параметров. Жёстко прописанные значения могут дать выигрыш только в редких случаях (например, при работе с константными выражениями, которые может вычислить на этапе компиляции).

Главное преимущество параметров — гибкость и поддерживаемость кода.

Можно ли использовать параметры в пакетных запросах?

Да, параметры работают и в пакетных запросах (когда несколько запросов выполняются в одной транзакции). Объявляйте параметры в начале пакета, и они будут доступны во всех вложенных запросах:

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

"ПАРАМЕТРЫ ДатаОтчета Дата;

// Первый запрос

ВЫБРАТЬ ... ГДЕ Дата = &ДатаОтчета;

// Второй запрос

ВЫБРАТЬ ... ГДЕ Период = МЕСЯЦ(&ДатаОтчета);";

Как отлаживать запросы с параметрами?

Используйте эти приёмы:

  1. Выводите итоговый текст запроса с подставленными параметрами через Запрос.ТекстЗапросаСПараметрами.
  2. Проверяйте типы передаваемых значений с помощью ТипЗнч().
  3. Для сложных запросов используйте Консоль запросов в режиме отладки (Отладка → Консоль запросов).

Пример вывода текста с параметрами:

Сообщить(Запрос.ТекстЗапросаСПараметрами);