В языке запросов 1С:Предприятие параметры играют ключевую роль при работе с базами данных. Они позволяют динамически передавать значения в SQL-подобные конструкции, делая запросы гибкими и многократно используемыми. Без понимания механизма параметров разработчики сталкиваются с проблемами: от ошибок выполнения до утечек памяти при некорректной обработке больших массивов данных.
Эта статья раскроет суть параметров в запросах 1С 8.3 и 1С 8.2, покажет их отличие от переменных, объяснит синтаксис объявления и использования. Мы разберём типичные сценарии применения — от простой фильтрации до сложных динамических отчётов, а также предупредим о подводных камнях, с которыми сталкиваются даже опытные программисты.
Параметры vs переменные: в чём разница?
Многие новички путают параметры запроса с обычными переменными в коде 1С. Разница принципиальна:
- 🔹 Переменные — это объекты языка 1С, которые существуют в контексте модуля (например,
Перем МояПеременная;). Их можно менять в процессе выполнения программы. - 🔹 Параметры запроса — это специальные "заменители" значений, которые подставляются в текст запроса перед его выполнением. Они объявлены только в контексте конкретного запроса и недоступны за его пределами.
Ключевое отличие: параметры не могут быть изменены после передачи в запрос, тогда как переменные можно модифицировать в любом месте кода. Например, если вы передали в запрос параметр ДатаНачала = '2026-01-01', то внутри текста запроса это значение станет константой.
Ещё одно важное свойство параметров — они типизированы. При объявлении нужно указать тип данных (Дата, Число, Строка и т.д.), что помогает 1С оптимизировать выполнение запроса и избегать ошибок несоответствия типов.
Синтаксис объявления параметров в запросе
Параметры объявляются в начале текста запроса после ключевого слова ПАРАМЕТРЫ (или PARAMETERS в англоязычной нотации). Общий формат:
ПАРАМЕТРЫ
ИмяПараметра1 ТипДанных1,
ИмяПараметра2 ТипДанных2;
Примеры корректных объявлений:
- 📅
ПАРАМЕТРЫ ДатаНачала Дата;— параметр для фильтрации по дате. - 💰
ПАРАМЕТРЫ МинимальнаяСумма Число(10, 2);— числовой параметр с указанием точности. - 📝
ПАРАМЕТРЫ Поставщик СправочникСсылка.Контрагенты;— ссылка на элемент справочника.
Обратите внимание: после объявления параметров обязательно ставится точка с запятой. Тип данных должен соответствовать тому, что ожидает запрос. Например, если вы фильтруете по полю типа Булево, то параметр тоже должен быть булевым:
ПАРАМЕТРЫ ТолькоАктивные Булево;
Используйте осмысленные имена параметров (например, ДатаОтчета вместо П1). Это упрощает поддержку кода и снижает риск ошибок при изменении логики.
Как передавать значения в параметры?
Объявление параметров — только половина дела. Чтобы они заработали, нужно передать им конкретные значения. Это делается с помощью метода УстановитьПараметр() объекта Запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ПАРАМЕТРЫ
| ДатаНачала Дата;
|ВЫБРАТЬ
| Документ.Дата КАК ДатаДокумента
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Документ
|ГДЕ
| Документ.Дата >= &ДатаНачала";
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));
Важные нюансы:
- 🔗 Имя параметра в методе
УстановитьПараметр()должно точно совпадать с именем в тексте запроса (регистр не важен). - 📌 В самом тексте запроса параметр обозначается символом
&(например,&ДатаНачала). - ⚠️ Если параметр не установлен, 1С вызовет ошибку при выполнении запроса.
Для передачи нескольких параметров используйте многократный вызов УстановитьПараметр():
Запрос.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаОкончания", КонецМесяца(ТекущаяДата()));
Что будет, если передать значение неверного типа?
Если передать в параметр значение несовместимого типа (например, строку вместо даты), 1С сгенерирует ошибку на этапе выполнения запроса. Например, при попытке сравнить дату с строкой появится сообщение: "Ошибка при вызове метода контекста (Выполнить): Тип не совпадает с ожидаемым (Дата)".
Типичные ошибки при работе с параметрами
Даже опытные разработчики иногда допускают ошибки при использовании параметров. Вот наиболее распространённые:
| Ошибка | Причина | Как исправить |
|---|---|---|
| Не объявлен параметр в тексте запроса | В коде используется &Параметр, но в секции ПАРАМЕТРЫ его нет |
Добавить объявление параметра с правильным типом |
| Несоответствие типов | Параметр объявлен как Число, а передаётся Строка |
Привести значение к нужному типу перед передачей |
| Опечатка в имени параметра | В УстановитьПараметр() указано "ДатаНачало", а в запросе &ДатаНачала |
Проверить совпадение имён (регистр не важен) |
Пропущена точка с запятой после ПАРАМЕТРЫ |
Синтаксическая ошибка в тексте запроса | Добавить ; после объявления параметров |
Особенно коварна ошибка с неявным приведением типов. Например, если параметр объявлен как Число, а вы передаёте строку "100", то в некоторых случаях 1С автоматически преобразует её в число. Однако это не гарантируется и может привести к трудноуловимым багам. Всегда следите за соответствием типов!
⚠️ Внимание: При работе с параметрами типаСправочникСсылкаилиДокументСсылкаубедитесь, что передаваемая ссылка существует в базе. Иначе запрос вернёт пустой результат без ошибок.
Практические примеры использования параметров
Рассмотрим реальные сценарии, где параметры незаменимы.
Пример 1: Фильтрация документов по периоду
Типичная задача — выборка документов за определённый интервал дат. Параметры позволяют сделать запрос универсальным:
ПАРАМЕТРЫ
ДатаНачала Дата,
ДатаОкончания Дата;
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата,
Документ.СуммаДокумента КАК Сумма
ИЗ
Документ.ПоступлениеТоваровУслуг КАК Документ
ГДЕ
Документ.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
В коде:
Запрос.УстановитьПараметр("ДатаНачала", НачалоКвартала(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаОкончания", КонецКвартала(ТекущаяДата()));
Пример 2: Динамический отбор по справочнику
Допустим, нужно получить список номенклатуры определённого вида. Параметр типа СправочникСсылка поможет избежать жёсткой привязки к конкретному элементу:
ПАРАМЕТРЫ
ВидНоменклатуры СправочникСсылка.ВидыНоменклатуры;
ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование,
Номенклатура.Артикул КАК Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.ВидНоменклатуры = &ВидНоменклатуры
Передаём значение:
ВидыНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товары");
Запрос.УстановитьПараметр("ВидНоменклатуры", ВидыНоменклатуры);
Пример 3: Условная логика с параметрами
Параметры можно использовать в выражениях ВЫРАЗИТЬ или ГДЕ для реализации сложной логики. Например, выборка клиентов с учётом флага "Только VIP":
ПАРАМЕТРЫ
ТолькоVIP Булево;
ВЫБРАТЬ
Клиент.Наименование КАК Клиент,
Клиент.Категория КАК Категория
ИЗ
Справочник.Контрагенты КАК Клиент
ГДЕ
(&ТолькоVIP И Клиент.Категория = ЗНАЧЕНИЕ(Перечисление.КатегорииКлиентов.VIP))
ИЛИ НЕ &ТолькоVIP
Объявлены все используемые параметры в секции ПАРАМЕТРЫ|Типы параметров соответствуют типам полей в запросе|Все параметры инициализированы методом УстановитьПараметр()|В тексте запроса параметры указаны с символом &-->
Оптимизация запросов с параметрами
Неправильное использование параметров может привести к перекомпиляции плана выполнения запроса при каждом вызове, что замедляет работу. Следуйте этим рекомендациям для оптимизации:
- 🚀 Избегайте динамического формирования текста запроса. Лучше использовать параметры, чем конкатенацию строк (например, через
СтрЗаменить()). - 📊 Для часто используемых запросов создавайте предопределённые данные (например, справочник с типичными фильтрами) и передавайте их как параметры.
- 🔍 Используйте индексы. Если параметр участвует в условии
ГДЕ, убедитесь, что соответствующее поле проиндексировано в базе.
Пример неэффективного подхода (динамический SQL):
ТекстЗапроса = "ВЫБРАТЬ * ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= '" + Формат(ДатаНачала, "ДЛФ=DT") + "'";
Это приводит к тому, что 1С каждый раз заново анализирует запрос. Правильный вариант — с параметром:
Запрос.Текст =
"ПАРАМЕТРЫ ДатаНачала Дата;
ВЫБРАТЬ * ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= &ДатаНачала";
⚠️ Внимание: При работе с большими базами (100 000+ записей) избегайте передачи в параметры массивов или таблиц значений через ЗНАЧЕНИЕ(). Это может привести к значительному увеличению времени выполнения. Вместо этого используйте временные таблицы.
Параметры в отчётах и внешних обработках
В отчётах 1С (например, в СКД — системе компоновки данных) параметры играют особую роль. Они позволяют:
- 📈 Создавать интерактивные формы с полями ввода для пользователя.
- 🔄 Переиспользовать одну схему компоновки для разных сценариев (например, отчёт по продажам и по закупкам).
- 👥 Ограничивать доступ к данным в зависимости от ролей пользователей.
Пример объявления параметра в схеме компоновки данных:
&НаКлиенте
Процедура КомандаСформировать(Команда)
Отчет = Отчеты.Продажи.Создать();
Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначение("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Отчет.Скомпоновать();
КонецПроцедуры
В самой схеме компоновки параметр объявляется в разделе Параметры с указанием типа и доступных значений (например, список справочников или перечисление).
Для внешних обработок параметры позволяют сделать решение универсальным. Например, обработка выгрузки данных в Excel может принимать параметры:
- 📌 Формат файла (
XLSXилиCSV). - 📂 Путь сохранения.
- 🔍 Фильтры данных (период, организация и т.д.).
Использование параметров в отчётах и обработках сокращает количество дублирующего кода и упрощает поддержку системы. Один универсальный отчёт с параметрами может заменить десятки специализированных.
FAQ: Частые вопросы о параметрах в запросах 1С
Можно ли использовать параметры в подзапросах?
Да, параметры доступны во всех частях запроса, включая подзапросы. Например:
ПАРАМЕТРЫ ДатаОтсечки Дата;
ВЫБРАТЬ
Клиент.Наименование
ИЗ
Справочник.Контрагенты КАК Клиент
ГДЕ
EXISTS(
ВЫБРАТЬ 1
ИЗ Документ.ЗаказПокупателя КАК Заказ
ГДЕ Заказ.Клиент = Клиент.Ссылка
И Заказ.Дата >= &ДатаОтсечки
)
Как передать в параметр массив значений?
Прямо передать массив нельзя, но можно:
- Использовать временную таблицу (рекомендуется для больших массивов).
- Передать массив как строку и разобрать её в запросе с помощью
ЗНАЧЕНИЕ()иРАЗДЕЛИТЬ()(неэффективно для больших данных).
Пример с временной таблицей:
// Создаём временную таблицу
ВТ_Фильтр = Новый ТаблицаЗначений;
ВТ_Фильтр.Колонки.Добавить("Значение", Новый ОписаниеТипов("Строка"));
// Заполняем данными
Для Каждого Элемент Из МассивЗначений Цикл
Строка = ВТ_Фильтр.Добавить();
Строка.Значение = Элемент;
КонецЦикла;
// Передаём во временную таблицу запроса
Запрос.МенеджерВременныхТаблиц.ДобавитьВременнуюТаблицу(ВТ_Фильтр, "Фильтр");
Что быстрее: параметры или жёстко прописанные значения?
Параметры практически не влияют на производительность, если они правильно типизированы. 1С оптимизирует план выполнения запроса с учётом параметров. Жёстко прописанные значения могут дать выигрыш только в редких случаях (например, при работе с константными выражениями, которые 1С может вычислить на этапе компиляции).
Главное преимущество параметров — гибкость и поддерживаемость кода.
Можно ли использовать параметры в пакетных запросах?
Да, параметры работают и в пакетных запросах (когда несколько запросов выполняются в одной транзакции). Объявляйте параметры в начале пакета, и они будут доступны во всех вложенных запросах:
Запрос.Текст =
"ПАРАМЕТРЫ ДатаОтчета Дата;
// Первый запрос
ВЫБРАТЬ ... ГДЕ Дата = &ДатаОтчета;
// Второй запрос
ВЫБРАТЬ ... ГДЕ Период = МЕСЯЦ(&ДатаОтчета);";
Как отлаживать запросы с параметрами?
Используйте эти приёмы:
- Выводите итоговый текст запроса с подставленными параметрами через
Запрос.ТекстЗапросаСПараметрами. - Проверяйте типы передаваемых значений с помощью
ТипЗнч(). - Для сложных запросов используйте Консоль запросов в режиме отладки (
Отладка → Консоль запросов).
Пример вывода текста с параметрами:
Сообщить(Запрос.ТекстЗапросаСПараметрами);