Работа с языком запросов в платформе 1С:Предприятие часто ставит разработчиков перед необходимостью жесткой типизации параметров. Одной из самых распространенных задач является необходимость передать значение перечисления (Enum) непосредственно в текст запроса, минуя стандартные параметры. Это особенно актуально при формировании динамических SQL-строк или при использовании запросов в консоли запросов, где контекст выполнения ограничен.

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

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

Синтаксические особенности языка запросов 1С

Язык запросов имеет строгую типизацию, которая отличается от встроенного языка. Когда вы формируете строку запроса программно, Для перечислений это делается с помощью специального оператора приведения.

Основной способ явного указания типа в тексте запроса — использование конструкции ЗНАЧЕНИЕ("Тип.ИмяПеречисления.Константа"). Обратите внимание, что весь путь к элементу перечисления должен быть заключен в двойные кавычки и начинаться с префикса типа. Это позволяет движку запросов заранее понять, какой тип данных ожидается в данном месте выборки или условия.

Использование такого синтаксиса гарантирует, что значение будет корректно обработано сервером 1С. Если вы попытаетесь передать перечисление как обычную строку без указания типа, система может выдать ошибку "Неверный тип аргумента" или, что хуже, silently проигнорировать условие фильтрации, вернув все записи из таблицы.

⚠️ Внимание: Синтаксис ЗНАЧЕНИЕ() чувствителен к регистру и полноте именования. Убедитесь, что имя перечисления указано полностью, включая пространство имен, если оно используется в вашей конфигурации.

Рассмотрим пример, где мы фильтруем документы по статусу. Вместо передачи переменной, мы вшиваем значение прямо в строку:

ТекстЗапроса = "ВЫБРАТЬ

| Документ.Ссылка

|ИЗ

| Документ.ЗаказКлиента КАК Документ

|ГДЕ

| Документ.Статус = ЗНАЧЕНИЕ(""Перечисление.СтатусыЗаказов.ВРаботе"")";

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

📊 Как вы чаще передаете перечисления в запрос?
Через параметры запроса
Через ЗНАЧЕНИЕ() в строке
Через ЗначениеВСтрокуВнутр
Не использую перечисления

Использование функции ЗначениеВСтрокуВнутр

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

Функция ЗначениеВСтрокуВнутр преобразует значение любого типа данных 1С в строковое представление, понятное языку запросов. Для перечислений она автоматически добавляет необходимый синтаксический префикс # или оборачивает значение в конструкцию ЗНАЧЕНИЕ(), в зависимости от версии платформы и контекста.

  • 🚀 Универсальность: Функция работает одинаково хорошо для чисел, строк, дат и сложных типов, таких как перечисления и планы видов характеристик.
  • 🛡️ Безопасность: Корректное экранирование специальных символов предотвращает ошибки синтаксиса при формировании динамических запросов.
  • 🔄 Читаемость: Код становится чище, так как логика формирования строки вынесена в отдельную функцию, а не размазана по конкатенации строк.

Пример использования функции в коде:

Статус = Перечисления.СтатусыЗаказов.ВРаботе;

ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ Документ.ЗаказКлиента ГДЕ Статус = " + ЗначениеВСтрокуВнутр(Статус);

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

💡

При использовании ЗначениеВСтрокуВнутр для булевых значений (Истина/Ложь) функция также корректно сформирует строку, что удобно для фильтрации признаков проведения документов.

Различия между типами Перечисление и Булево

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

Значения типа Булево (Истина, Ложь) в запросах часто могут использоваться без явного указания типа, если контекст однозначно подразумевает булевый тип поля. Однако для перечислений, имеющих множество констант, явное указание типа через ЗНАЧЕНИЕ() является обязательным требованием компилятора запросов.

Если поле в базе данных имеет тип Булево, вы можете писать условие так:

ГДЕ Проведен = ИСТИНА

Но если поле имеет тип ПеречислениеСсылка, конструкция изменится:

ГДЕ Статус = ЗНАЧЕНИЕ("Перечисление.Статусы.Новый")

Характеристика Тип Булево Тип Перечисление
Количество значений 2 (Истина, Ложь) Неограничено
Синтаксис в запросе ИСТИНА / ЛОЖЬ ЗНАЧЕНИЕ("Путь.К.Элементу")
Чувствительность к регистру Нет (обычно) Да, критично
Использование в параметрах Прямая передача Требует явного типа

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

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

Консоль запросов — мощный инструмент отладки, но в ней отсутствует контекст выполнения кода встроенного языка. Это означает, что вы не можете использовать переменные или функции типа ЗначениеВСтрокуВнутр непосредственно в окне ввода запроса.

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

Алгоритм действий в консоли:

  1. Откройте дерево метаданных в конфигураторе.
  2. Найдите нужное перечисление и конкретную константу.
  3. Скопируйте полное имя (например, Перечисления.ВидыОпераций.Поступление).
  4. Вставьте его в запрос, обернув в конструкцию ЗНАЧЕНИЕ("..").
Как узнать полное имя перечисления?

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

Частая проблема в консоли — ошибка "Не найдено определение типа". Это почти всегда означает опечатку в пути к перечислению или использование синонима вместо технического имени объекта.

Оптимизация и производительность запросов

Вопрос производительности при использовании жестко заданных перечислений в строке запроса часто остается за кадром. Однако, с точки зрения оптимизации, вставка значения через ЗНАЧЕНИЕ() прямо в текст запроса может быть даже предпочтительнее использования параметров в некоторых сценариях.

Когда вы используете параметры, сервер 1С должен выполнить дополнительное действие по подстановке значений перед компиляцией плана выполнения. При использовании литералов (в том числе перечислений) план выполнения формируется сразу, что может незначительно ускорить старт выполнения запроса.

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

⚠️ Внимание: Избегайте конкатенации строк с перечислениями в циклах. Это приводит к множественной компиляции одинаковых запросов с разными значениями, что нагружает сервер. Лучше использовать один запрос с параметром или оператором В.
💡

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

Типичные ошибки и способы их решения

Даже опытные разработчики иногда допускают ошибки при работе с типизацией в запросах. Анализ наиболее частых проблем поможет вам избежать потери времени на отладку.

Самая распространенная ошибка — попытка передать имя перечисления как обычную строку в одинарных кавычках. Система воспринимает это как текстовое значение, и сравнение с полем типа "ПеречислениеСсылка" возвращает пустой результат, так как типы не совпадают.

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

  • Ошибка: ГДЕ Статус = "ВРаботе" — сравнение строки с перечислением.
  • Ошибка: ГДЕ Статус = ЗНАЧЕНИЕ("ВРаботе") — неизвестный тип без пути.
  • Верно: ГДЕ Статус = ЗНАЧЕНИЕ("Перечисление.СтатусыЗаказов.ВРаботе").

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

☑️ Проверка запроса с перечислением

Выполнено: 0 / 4
Можно ли использовать синонимы перечислений в запросе?

Нет, в конструкции ЗНАЧЕНИЕ() необходимо использовать только технические имена объектов метаданных, определенные в конфигураторе. Синонимы, удобные для пользователей, языком запросов не распознаются в этом контексте.

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

Пустое значение перечисления (незаполненное) в запросе обычно обрабатывается как NULL. Для проверки на заполненность используйте оператор ЕСТЬ NULL или НЕ ЕСТЬ NULL, а не сравнение с конкретной константой.

Работает ли этот синтаксис в СКД (Системе Компоновки Данных)?

Да, в настройках отборов СКД также можно использовать выражения. Однако в макетах СКД чаще используют параметры. Если вы пишете текст запроса внутри макета СКД вручную, синтаксис ЗНАЧЕНИЕ() работает аналогично обычным запросам.

Как передать перечень значений (несколько констант)?

Для передачи списка значений используйте оператор В. Пример: ГДЕ Статус В (ЗНАЧЕНИЕ(".."), ЗНАЧЕНИЕ("..")). Это эффективнее, чем множество условий ИЛИ.

Влияет ли версия платформы на синтаксис?

Базовый синтаксис ЗНАЧЕНИЕ() стабилен уже много лет. Однако в самых новых версиях 1С могут появляться дополнительные возможности работы с типами. Всегда сверяйтесь с синтаксис-помощником вашей конкретной версии платформы.