В мире разработки конфигураций платформы 1С:Предприятие запросы являются фундаментальным инструментом для выборки данных из информационной базы. Эффективность работы программы напрямую зависит от того, насколько грамотно построена логика получения информации. Часто возникает ситуация, когда жестко прописанные условия в тексте запроса становятся недостаточными, и требуется гибкость, зависящая от действий пользователя или состояния системы в конкретный момент времени.

Именно для решения таких задач используется механизм параметров запроса. Это переменные, значения которых подставляются в текст запроса в момент его выполнения. Понимание того, как добавить параметр в запрос 1С, является обязательным навыком для любого программиста, стремящегося писать оптимизированный и безопасный код. Неумение работать с параметрами часто приводит к написанию громоздких конструкций или, что хуже, к уязвимостям типа SQL-инъекций при использовании динамических строк.

В данной статье мы детально разберем синтаксис объявления параметров, способы их передачи из управляемого кода, особенности работы с типами данных и методы фильтрации результатов. Мы рассмотрим как стандартные сценарии использования, так и более сложные случаи, требующие внимания к деталям реализации платформы.

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

Текст запроса в 1С представляет собой строку, содержащую SQL-подобный синтаксис, адаптированный под объекты метаданных платформы. Чтобы система поняла, что в запросе ожидается внешнее значение, необходимо использовать специальный символ-маркер. Параметр обозначается знаком & (амперсанд), за которым сразу следует имя переменной.

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

В данном примере &ВидНоменклатуры является плейсхолдером. Сама по себе эта строка не может быть выполнена, пока в объект запроса не будет передано реальное значение. Если вы попытаетесь выполнить такой запрос без предварительной установки значения, платформа выдаст ошибку о том, что значение параметра не установлено. Это базовый механизм защиты от выполнения некорректных выборок.

Одной из частых ошибок новичков является попытка использовать параметры в местах, где это синтаксически запрещено. Например, нельзя использовать параметр вместо имени таблицы или поля в секции ВЫБРАТЬ или ИЗ. Параметры предназначены исключительно для подстановки значений в условиях фильтрации (ГДЕ, ИМЕЮЩИЕ), в списках значений (В (&СписокЗначений)) или в выражениях вычисляемых полей.

💡

При написании сложных запросов с множеством параметров используйте префиксы для имен, например, &Пар_ДатаНач, &Пар_Контрагент. Это улучшит читаемость кода и упростит отладку.

Установка значений параметров в коде 1С

После того как текст запроса сформирован, следующим этапом является создание объекта Запрос и наполнение его параметров значениями. В языке 1С существует несколько способов сделать это, и выбор конкретного метода зависит от контекста задачи и количества передаваемых переменных.

Самый распространенный и наглядный способ — использование метода УстановитьПараметр. Он принимает два аргумента: имя параметра (строкой, без символа амперсанда) и само значение. Этот метод позволяет явно контролировать процесс подготовки данных перед выполнением выборки.

ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование = &ИмяКонтрагента";

Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("ИмяКонтрагента", "ООО ""Ромашка""");

Результат = Запрос.Выполнить();

Второй способ, который часто встречается в практике, заключается в использовании структуры значений. Вы можете создать объект Структура, заполнить его поля, соответствующие именам параметров, и передать эту структуру методом ЗаполнитьПараметры. Это особенно удобно, когда параметры запроса формируются на основе полей формы или другого объекта данных.

  • 🔹 Метод УстановитьПараметр идеален для единичных значений или когда имена параметров динамически меняются.
  • 🔹 Метод ЗаполнитьПараметры удобен при массовой передаче данных из формы документа или отчета.
  • 🔹 Прямое присваивание через свойство Параметры (например, Запрос.Параметры.Имя = Значение) возможно, но менее гибко при программном формировании списка.

Важно учитывать типизацию. Платформа 1С строго следит за соответствием типа передаваемого значения типу поля в базе данных, хотя и выполняет неявные преобразования там, где это возможно. Однако передача строки в поле типа Число или даты может привести к ошибке выполнения или некорректному результату фильтрации.

☑️ Алгоритм передачи параметра

Выполнено: 0 / 4

Работа со списками значений и оператором В

Одним из самых мощных инструментов фильтрации в 1С является оператор В, позволяющий отбирать записи, соответствующие одному из значений списка. Параметр в этом случае должен содержать не скалярное значение, а коллекцию — обычно это объект СписокЗначений или Массив.

При использовании списка значений важно правильно сформировать коллекцию. Если список окажется пустым, поведение запроса может быть неожиданным: в некоторых версиях платформы или конфигурациях запрос вернет все записи, в других — ни одной. Явная проверка на пустоту списка перед выполнением запроса является хорошей практикой программирования.

СписокГородов = Новый СписокЗначений;

СписокГородов.Добавить("Москва");

СписокГородов.Добавить("Санкт-Петербург");

СписокГородов.Добавить("Казань");

ТекстЗапроса = "ВЫБРАТЬ Город ИЗ Справочник.Филиалы ГДЕ Город В (&СписокГородов)";

Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("СписокГородов", СписокГородов);

Существует нюанс при работе со списками структур. Если вы передаете список структур, а в запросе используете точечную нотацию (например, Где Элемент.Город В (&СписокГородов)), система автоматически извлечет нужное свойство из каждой структуры списка. Это позволяет избежать лишних циклов в коде и перекладывает задачу фильтрации на движок запросов, что значительно повышает производительность.

⚠️ Внимание: При передаче большого списка значений (тысячи элементов) убедитесь, что длина сгенерированного SQL-запроса не превышает лимиты СУБД. Для очень больших списков лучше использовать временные таблицы.

Использование временных таблиц как параметров

В сложных сценариях, особенно при работе с большими объемами данных или многоступенчатой фильтрацией, обычные переменные могут быть недостаточно эффективны. Здесь на помощь приходят временные таблицы. Они позволяют загрузить набор данных в память сервера 1С и использовать этот набор как параметр в последующих запросах.

Механизм работы заключается в следующем: сначала выполняется запрос, результат которого помещается во временную таблицу. Затем имя этой временной таблицы используется в качестве параметра в основном запросе. Синтаксически это выглядит как использование имени таблицы, созданной командой ПОМЕСТИТЬ.

Преимущество такого подхода заключается в возможности предварительной обработки данных: сортировки, уникализации, соединения с другими таблицами перед основной выборкой. Кроме того, временные таблицы индексируются автоматически, что ускоряет работу оператора В при большом количестве записей.

Характеристика Обычный параметр (СписокЗначений) Временная таблица
Объем данных Оптимально до нескольких тысяч Десятки и сотни тысяч записей
Типы данных Простые типы или структуры Любые типы, включая составные
Производительность Снижается при росте списка Высокая за счет индексации
Сложность кода Низкая Средняя (требует управления таблицами)

Для создания временной таблицы используется конструкция ПОМЕСТИТЬ ИмяТаблицы ИЗ... После этого в тексте основного запроса можно обращаться к ИмяТаблицы как к обычной таблице или использовать её в операторе В. Не забудьте удалить временные таблицы после использования, если они создаются в долгоживущих сеансах, чтобы не занимать оперативную память.

Как управлять жизненным циклом временных таблиц?

Временные таблицы существуют в рамках одного сеанса пользователя. Они автоматически удаляются при завершении сеанса. Однако в рамках одного запроса или серии запросов их нужно удалять явно командой УДАЛИТЬ ВРЕМЕННЫЕ ТАБЛИЦЫ, если они больше не нужны, чтобы освободить ресурсы сервера.

Типизация параметров и неявные преобразования

Платформа 1С:Предприятие обладает развитой системой типов, и запросы не являются исключением. При установке параметра критически важно понимать, какой тип данных ожидает поле базы данных. Хотя движок запросов пытается выполнять неявные преобразования, reliance на эту функцию может привести к скрытым ошибкам.

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

Особое внимание следует уделить составным типам. Если поле может хранить как Число, так и Строку, передача параметра должна соответствовать типу конкретного значения в выбираемой записи. В случаях несовпадения типов запись просто не попадет в выборку, что может быть интерпретировано разработчиком как ошибка логики фильтрации, хотя технически запрос выполнен корректно.

  • 🔸 Даты: Всегда передавайте тип Дата. Избегайте передачи строк вида "01.01.2023", преобразуя их заранее.
  • 🔸 Булево: Используйте значения Истина или Ложь. Числа 1 и 0 могут работать не во всех контекстах.
  • 🔸 Null: Для проверки на пустое значение используйте специальный тип Неопределено в параметре и конструкцию ЕСТЬ NULL в запросе.

Использование оператора ЕСТЬ NULL требует отдельного пояснения. В отличие от обычного сравнения на равенство, проверка на NULL (или Неопределено в терминах 1С) имеет свой синтаксис. Если ваш параметр может принимать значение Неопределено, убедитесь, что условие в запросе написано как ГДЕ Поле = &Параметр ИЛИ (&Параметр ЕСТЬ NULL), если логика подразумевает игнорирование фильтра при пустом параметре.

💡

Строгая типизация параметров запроса — залог стабильной работы системы. Всегда приводите значения к типу поля базы данных перед установкой параметра.

Оптимизация и типичные ошибки при работе с параметрами

Неправильное использование параметров может стать "бутылочным горлышком" производительности вашей конфигурации. Самая распространенная ошибка — использование функций от полей в условии ГДЕ вместе с параметрами. Например, конструкция ГДЕ ГОД(ДатаДокумента) = &Год запрещает использование индекса по полю ДатаДокумента, что заставляет СУБД перебирать все записи таблицы.

Вместо этого следует использовать диапазон дат. Передайте в параметрах дату начала и дату конца года, а в запросе напишите ГДЕ ДатаДокумента >= &НачалоГода И ДатаДокумента < &КонецГода. Такой подход позволяет движку базы данных использовать индексы по дате, ускоряя выборку в сотни раз.

⚠️ Внимание: Избегайте конкатенации строк для формирования условий запроса. Никогда не пишите ТекстЗапроса = ".. ГДЕ Имя = '" + Имя + "'". Это открывает уязвимость для SQL-инъекций и лишает вас преимуществ параметризированных запросов, таких как кэширование плана выполнения.

Еще одна частая проблема связана с областью видимости параметров в консоли запросов. При отладке в консоли запросов параметры необходимо объявлять в специальной панели параметров, иначе текст запроса с символом & вызовет синтаксическую ошибку. В коде же эта проблема решается автоматическим созданием коллекции параметров объектом Запрос.

Также стоит упомянуть о лимитах. Хотя они редко достигаются в типовых задачах, существует ограничение на количество параметров в одном запросе (зависит от версии платформы и СУБД). Если вы динамически генерируете запрос с сотнями условий ИЛИ Поле = &Пар1 ИЛИ Поле = &Пар2.., вы можете упереться в этот лимит. В таких случаях снова выручают временные таблицы с оператором В.

📊 С каким типом параметров вам приходится работать чаще всего?
Строковые значения
Даты и периоды
Списки значений (массивы)
Ссылки на объекты
Булевы флаги

Часто задаваемые вопросы (FAQ)

Можно ли использовать параметр в секции ВЫБРАТЬ для динамического выбора полей?

Нет, напрямую подставить имя поля через параметр &ИмяПоля в секцию ВЫБРАТЬ нельзя. Параметры в запросах 1С предназначены только для подстановки значений, а не идентификаторов метаданных. Для динамического выбора полей необходимо формировать текст запроса программно, используя конкатенацию строк, но соблюдая меры безопасности.

Что делать, если параметр не передается в запрос из формы?

Проверьте имя параметра: оно должно совпадать с именем в тексте запроса (без учета регистра и символа &). Убедитесь, что вы вызываете метод Выполнить() после установки параметра. Если используется СКД (Система Компоновки Данных), проверьте настройки компоновки, возможно, параметр не связан с полем формы.

Как передать в запрос текущую дату пользователя?

Используйте встроенную функцию ТекущаяДата() в коде 1С перед выполнением запроса. Пример: Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата()). Не используйте функцию ТЕКУЩАЯДАТА() внутри текста запроса, если вам нужно зафиксировать момент времени на весь период выполнения сложных вычислений.

Почему запрос с параметром работает медленнее, чем с жестко заданным значением?

Это может происходить из-за того, что оптимизатор СУБД не знает точное значение параметра при построении плана выполнения и выбирает универсальный, но менее эффективный план. В таких случаях помогает использование директив ОПТИМИЗАЦИЯ ПО или принудительное использование индексов, хотя в 1С это требуется редко.

Можно ли передавать в параметр объект ЗаписьНабораДанных?

Нет, в параметр запроса нельзя передать напрямую объект ЗаписьНабораДанных. Необходимо предварительно выгрузить данные из набора в СписокЗначений, Массив или Временную таблицу, и уже эту коллекцию использовать как параметр.