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

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

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

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

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

В базе данных перечисления представлены в виде ссылок, которые состоят из:

  • 🔹 Уникального идентификатора (UID) — внутреннего кода значения, который гарантирует уникальность даже при переносе между базами.
  • 🔹 Имени значения — текстового представления (например, "Оплачено" или "НаСогласовании").
  • 🔹 Представления — локализованного отображения для пользователя (может отличаться от имени на разных языках).

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

⚠️ Внимание: Если вы работаете с перечислениями в управляемых формах или отчётах, помните, что их значения могут кэшироваться. После изменения состава перечисления в конфигураторе обязательно обновляйте кэш метаданных (Конфигуратор → Администрирование → Обновить кэш метаданных), иначе в запросах могут использоваться устаревшие данные.

Способы указания значений перечисления в запросе

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

1. Прямое указание через точку (синтаксис "ИмяПеречисления.Значение")

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

Пример:

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

Документ.Статус = Перечисление.СтатусыДокументов.Оплачено

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

2. Использование функции ВЫБОР

Функция ВЫБОР позволяет динамически получать значения перечислений по их внутреннему идентификатору или имени. Это полезно, когда значение перечисления определяется в процессе выполнения кода (например, передаётся как параметр).

Пример с идентификатором:

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

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

ВЫБОР

ИЗ Перечисление.ВидыНоменклатуры КАК Вид

ПО УИД(&УИДВидаНоменклатуры)

КОНЕЦ

Где &УИДВидаНоменклатуры — параметр запроса, содержащий уникальный идентификатор значения перечисления. Этот способ гарантирует корректную работу даже при изменении имён значений в конфигураторе.

3. Сравнение по представлению (не рекомендуется)

Иногда разработчики пытаются сравнивать перечисления по их строковому представлению (например, ГДЕ Статус = "Оплачено"). Этот подход некорректен и может работать только в редких случаях, когда платформа неявно преобразует строку в ссылку. Однако такое поведение не гарантируется и зависит от версии .

Если вам действительно нужно сравнивать по текстовому значению (например, при миграции данных), используйте функцию ПРЕДСТАВЛЕНИЕ:

ВЫБРАТЬ

Документ.Номер КАК Номер

ИЗ

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

ГДЕ

ПРЕДСТАВЛЕНИЕ(Документ.Статус) = "Оплачено"

⚠️ Внимание: Сравнение по представлению работает медленнее, чем по ссылке, и может давать неожиданные результаты, если в конфигурации используются разные языки интерфейса. Например, на русском статусу соответствует "Оплачено", а на английском — "Paid".
📊 Какой способ указания перечислений вы используете чаще?
Прямое указание через точку
Функция ВЫБОР по УИД
Сравнение по представлению
Другой вариант

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

Часто значения перечислений передаются в запрос через параметры. В этом случае нужно правильно формировать параметр, чтобы платформа могла его корректно интерпретировать. Рассмотрим два основных сценария: передача значения перечисления из кода и передача по УИД.

1. Передача значения перечисления как параметра

Если значение перечисления формируется в коде (например, в модуле отчёта), его можно передать в запрос напрямую. Главное — убедиться, что параметр имеет правильный тип.

Пример на встроенном языке:

СтатусДляЗапроса = Перечисления.СтатусыДокументов.Оплачено;

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

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

"ВЫБРАТЬ

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

ИЗ

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

ГДЕ

Документ.Статус = &Статус";

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

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

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

2. Передача УИД значения перечисления

Если вы работаете с УИД (например, получаете его из внешней системы или храните в регистре), используйте функцию ВЫБОР, как показано ранее. Альтернативный способ — преобразовать УИД в значение перечисления на стороне до передачи в запрос.

Пример:

УИДСтатуса = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8");

СтатусДляЗапроса = Перечисления.СтатусыДокументов.НайтиПоУИД(УИДСтатуса);

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

Метод НайтиПоУИД вернёт значение перечисления по его уникальному идентификатору или Неопределено, если такое значение не найдено. Это безопаснее, чем работа с "голыми" УИД в запросе.

☑️ Подготовка параметров для перечислений

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

Типичные ошибки при работе с перечислениями в запросах

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

1. Ошибка "Недопустимое сравнение значений разных типов"

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

ГДЕ Статус = "Оплачено"  // Ошибка!

Исправление: всегда используйте полное имя перечисления:

ГДЕ Статус = Перечисление.СтатусыДокументов.Оплачено

2. Ошибка "Неизвестное имя 'Перечисление'"

Если вы забыли указать слово Перечисление перед именем, платформа не сможет найти объект:

ГДЕ Статус = СтатусыДокументов.Оплачено  // Ошибка!

Исправление: добавьте Перечисление.:

ГДЕ Статус = Перечисление.СтатусыДокументов.Оплачено

3. Ошибка при работе с параметрами

Если параметр запроса имеет неверный тип (например, строка вместо перечисления), запрос не выполнится. Например:

Запрос.УстановитьПараметр("Статус", "Оплачено");  // Ошибка!

Исправление: преобразуйте строку в значение перечисления:

СтатусДляЗапроса = Перечисления.СтатусыДокументов.Оплачено;

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

Ошибка Причина Исправление
Недопустимое сравнение значений разных типов Сравнение перечисления со строкой/числом Использовать полное имя перечисления
Неизвестное имя 'ИмяПеречисления' Отсутствует слово Перечисление Добавить Перечисление.ИмяПеречисления
Неверный тип параметра Параметр имеет тип строка вместо перечисления Преобразовать строку в значение перечисления
Значение перечисления не найдено Неверный УИД или имя значения Проверить состав перечисления в конфигураторе
💡

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

Особенности работы с перечислениями в разных версиях 1С

Синтаксис работы с перечислениями в запросах практически не менялся с версии 8.2, однако есть нюансы, которые стоит учитывать при работе со старыми или новыми релизами платформы.

1С 8.2 и 8.3 (до 8.3.10)

В этих версиях поддерживаются все описанные выше методы, но есть ограничения:

  • 🔸 Функция ВЫБОР ... ПО УИД работает медленнее, чем в новых версиях.
  • 🔸 При сравнении по представлению (ПРЕДСТАВЛЕНИЕ) возможны проблемы с кодировками.
  • 🔸 Нет поддержки конструкции ЗНАЧЕНИЕ(Перечисление.Имя.Значение) в параметрах.

1С 8.3.10 и новее

Начиная с версии 8.3.10, платформа стала строже относиться к типам данных в запросах. Например:

  • 🔸 Запрещено неявное преобразование строк в перечисления (раньше это иногда работало).
  • 🔸 Улучшена производительность функции ВЫБОР при работе с УИД.
  • 🔸 Добавлена поддержка конструкции ЗНАЧЕНИЕ для перечислений в параметрах.

Пример использования ЗНАЧЕНИЕ:

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

"ВЫБРАТЬ

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

ГДЕ

Справочник.Контрагенты.ВидКонтрагента = &Вид";

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

⚠️ Внимание: В версиях 1С:Предприятие 8.3.18+ при работе с перечислениями в запросах может возникать предупреждение о неоптимальном плане выполнения, если используется функция ПРЕДСТАВЛЕНИЕ. В таких случаях рекомендуется переписать запрос с использованием ссылок.

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

Рассмотрим несколько реальных примеров запросов, где используются перечисления. Эти примеры можно адаптировать под свои задачи.

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

Задача: получить список заказов покупателей со статусом "Оплачено" или "Отгружено".

ВЫБРАТЬ

Заказ.Ссылка КАК Ссылка,

Заказ.Дата КАК Дата,

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

ИЗ

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

ГДЕ

Заказ.Статус В (&Статусы)

УПОРЯДОЧИТЬ ПО

Заказ.Дата УБЫВ

В коде:

СтатусыДляЗапроса = Новый Массив;

СтатусыДляЗапроса.Добавить(Перечисления.СтатусыДокументов.Оплачено);

СтатусыДляЗапроса.Добавить(Перечисления.СтатусыДокументов.Отгружено);

Запрос.УстановитьПараметр("Статусы", СтатусыДляЗапроса);

Пример 2: Группировка по перечислению

Задача: получить количество номенклатуры по видам (перечисление ВидыНоменклатуры).

ВЫБРАТЬ

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

ПРЕДСТАВЛЕНИЕ(Номенклатура.ВидНоменклатуры) КАК ВидПредставление,

КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Номенклатура.Ссылка) КАК Количество

ИЗ

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

ГРУППИРОВАТЬ ПО

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

ПРЕДСТАВЛЕНИЕ(Номенклатура.ВидНоменклатуры)

Пример 3: Использование перечисления в вычисляемом поле

Задача: добавить в результат запроса поле с текстовой расшифровкой статуса.

ВЫБРАТЬ

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

ВЫБОР

КОГДА Документ.Статус = Перечисление.СтатусыДокументов.Оплачено

ТОГДА "Документ оплачен"

КОГДА Документ.Статус = Перечисление.СтатусыДокументов.Отгружено

ТОГДА "Документ отгружен"

ИНАЧЕ "Другой статус"

КОНЕЦ КАК СтатусТекст

ИЗ

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

Как ускорить запрос с перечислениями?

Если в запросе используется функция ПРЕДСТАВЛЕНИЕ(Перечисление), попробуйте заменить её на прямую выборку из виртуальной таблицы Перечисление.Имя.СписокЗначений. Например:

ВЫБРАТЬ

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

СтатусыСписок.Представление КАК СтатусТекст

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Перечисление.СтатусыДокументов.СписокЗначений КАК СтатусыСписок

ПО Документ.Статус = СтатусыСписок.Ссылка

Это снизит нагрузку на сервер, особенно при большом количестве записей.

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

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

1. Избегайте функции ПРЕДСТАВЛЕНИЕ в условиях

Функция ПРЕДСТАВЛЕНИЕ вычисляет строковое значение на лету, что замедляет выполнение запроса. Вместо:

ГДЕ ПРЕДСТАВЛЕНИЕ(Документ.Статус) = "Оплачено"

Используйте:

ГДЕ Документ.Статус = Перечисление.СтатусыДокументов.Оплачено

2. Используйте виртуальные таблицы для перечислений

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

ВЫБРАТЬ

Статусы.Ссылка КАК Статус,

Статусы.Представление КАК Наименование

ИЗ

Перечисление.СтатусыДокументов.СписокЗначений КАК Статусы

3. Кэшируйте часто используемые перечисления

Если в коде часто обращаетесь к одним и тем же значениям перечислений, закэшируйте их в переменные:

СтатусОплачено = Перечисления.СтатусыДокументов.Оплачено;

СтатусОтгружено = Перечисления.СтатусыДокументов.Отгружено;

Это ускорит выполнение кода, особенно в циклах.

💡

Самый быстрый способ работы с перечислениями в запросах — использование прямых ссылок (например, Перечисление.Имя.Значение). Функции вроде ПРЕДСТАВЛЕНИЕ или ВЫБОР замедляют выполнение, поэтому применяйте их только при необходимости.

FAQ: Частые вопросы по работе с перечислениями в 1С

Как получить все значения перечисления в запросе?

Используйте виртуальную таблицу Перечисление.ИмяПеречисления.СписокЗначений:

ВЫБРАТЬ

Значение КАК Ссылка,

Представление КАК Наименование

ИЗ

Перечисление.СтатусыДокументов.СписокЗначений

Этот запрос вернёт все возможные значения перечисления с их текстовыми представлениями.

Можно ли сравнивать перечисления из разных конфигураций?

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

Как узнать УИД значения перечисления?

УИД можно получить в конфигураторе или через встроенный язык:

Сообщить(Перечисления.СтатусыДокументов.Оплачено.УникальныйИдентификатор());

Или в запросе:

ВЫБРАТЬ

Значение КАК Ссылка,

Значение.УникальныйИдентификатор() КАК УИД

ИЗ

Перечисление.СтатусыДокументов.СписокЗначений КАК Значение

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

Возможные причины:

  1. В базе есть документы со статусом Неопределено (проверьте условие ГДЕ Статус ЕСТЬ NULL).
  2. Имя значения перечисления изменилось в конфигураторе, но в базе остались старые данные.
  3. Вы сравниваете по представлению, а в базе используется другой язык интерфейса.

Решение: используйте УИД для надёжного сравнения или проверьте состав перечисления в конфигураторе.

Как добавить новое значение в перечисление без потери данных?

Добавление нового значения в перечисление безопасно — оно не повлияет на существующие данные. Однако:

  • 🔹 Удаление или переименование значений может привести к потере ссылочной целостности.
  • 🔹 После изменения перечисления обновите кэш метаданных (Конфигуратор → Администрирование → Обновить кэш метаданных).
  • 🔹 Если перечисление используется в регистрах или документах, проверьте, не появились ли записи с некорректными статусами.