Разработка и Конфигурация · 13 мин
Как сравнить перечисления в 1С: практическое руководство
Как сравнить значения перечислений в 1С: операторы сравнения, методы Индекс и XMLСтрока, проверка на пустое значение, типичные ошибки и примеры кода.
Перечисления в 1С — один из самых часто используемых типов данных: статусы документов, виды операций, варианты налогообложения, состояния заказов. Почти в любом модуле рано или поздно возникает задача сравнить значение перечисления с эталоном: проверить, равен ли статус документа значению «Проведен», или определить, входит ли вид операции в допустимый список. Ошибки в таких сравнениях приводят к трудноуловимым дефектам: условие молча не срабатывает, а логика обработки идёт не по той ветке.
Главная особенность перечислений в 1С — они сравниваются по ссылке, а не по строковому представлению. Это значит, что сравнение значения перечисления со строкой «Проведен» всегда даст «Ложь», даже если визуально значения совпадают. Понимание этого принципа избавляет от большинства ошибок, которые допускают начинающие разработчики.
В статье разобраны все рабочие способы сравнения перечислений: прямое сравнение значений, проверка через индекс, сравнение по имени, работа с пустыми ссылками, а также сравнение значений из разных информационных баз — например, при обмене данными или интеграции.
Как устроены перечисления и почему это важно для сравнения
Перечисление в 1С — это предопределённый список значений, заданный в конфигураторе на этапе разработки. Каждое значение имеет имя (идентификатор, например «Проведен»), синоним (отображаемое представление, например «Проведён») и внутренний порядковый номер — индекс, начинающийся с нуля. Пользователь не может добавить новое значение перечисления в режиме предприятия: состав фиксирован конфигурацией.
При сравнении платформа сопоставляет не текстовые представления, а сами значения внутреннего типа «ПеречислениеСсылка». Поэтому код Если Статус = "Проведен" Тогда синтаксически корректен, но логически неверен: строка никогда не равна ссылке на значение перечисления. Такое условие не вызовет ошибки выполнения — оно просто всегда вернёт «Ложь», что делает дефект особенно коварным.
Обратиться к конкретному значению перечисления в коде можно через менеджер: Перечисления.СтатусыДокументов.Проведен. Имя указывается точно так, как оно задано в конфигураторе, с учётом регистра букв не обязательно — язык 1С регистронезависим, но опечатка в имени приведёт к ошибке компиляции, что на самом деле удобно: ошибка выявляется сразу.
Прямое сравнение значений операторами = и <>
Основной и рекомендуемый способ — прямое сравнение с конкретным значением перечисления через оператор равенства:
Если Документ.Статус = Перечисления.СтатусыДокументов.Проведен Тогда
// логика для проведённого документа
ИначеЕсли Документ.Статус = Перечисления.СтатусыДокументов.Отменен Тогда
// логика для отменённого документа
КонецЕсли;
Для проверки неравенства используется оператор <>: Если Статус <> Перечисления.СтатусыДокументов.Черновик Тогда. Такое сравнение выполняется быстро, читается легко и проверяется компилятором: если имя значения написано с ошибкой, модуль просто не сохранится.
Когда значений для проверки несколько, перечислять их через «Или» громоздко. Удобнее собрать допустимые значения в массив и проверить вхождение:
ДопустимыеСтатусы = Новый Массив;
ДопустимыеСтатусы.Добавить(Перечисления.СтатусыДокументов.Проведен);
ДопустимыеСтатусы.Добавить(Перечисления.СтатусыДокументов.Отправлен);
Если ДопустимыеСтатусы.Найти(Документ.Статус) <> Неопределено Тогда
// статус входит в допустимый список
КонецЕсли;
- 1Откройте конфигуратор и найдите нужное перечисление в дереве конфигурации, чтобы узнать точные имена значений.
- 2В коде обратитесь к значению через менеджер: Перечисления.ИмяПеречисления.ИмяЗначения.
- 3Сравните переменную с этим значением оператором = или <>.
- 4Для нескольких допустимых значений используйте массив с методом Найти().
- 5Проверьте результат в отладчике: остановитесь на условии и посмотрите фактическое значение переменной.
Проверка на пустое значение перечисления
Реквизит типа «перечисление» может быть не заполнен — тогда он содержит пустую ссылку. Это частый источник ошибок: разработчик сравнивает статус с конкретным значением, забывая, что у нового объекта реквизит может быть просто пустым, и логика обработки пустых значений не предусмотрена.
Проверить пустое значение можно двумя способами. Первый — явное сравнение с пустой ссылкой: Если Статус = Перечисления.СтатусыДокументов.ПустаяСсылка() Тогда. Второй — универсальная функция ЗначениеЗаполнено(Статус), которая возвращает «Ложь» для пустых ссылок любых типов, а также для пустых строк, нулевых дат и числа 0.
Выбор между способами зависит от контекста. Если переменная гарантированно имеет тип перечисления, оба варианта равнозначны. Если тип переменной может варьироваться (составной тип реквизита), ЗначениеЗаполнено() безопаснее и читабельнее. Обратный вариант — проверка «значение не заполнено» — записывается как Если НЕ ЗначениеЗаполнено(Статус) Тогда.
Сравнение по имени и представлению: когда это нужно
Иногда значение перечисления приходит извне в виде строки: из файла обмена, веб-сервиса, формы ввода или запроса пользователя. В этом случае прямое сравнение невозможно — строку нужно сначала преобразовать в значение перечисления. Для этого платформа предоставляет индексное обращение по имени:
ИмяЗначения = "Проведен"; // пришло извне
Попытка
ЗначениеСтатуса = Перечисления.СтатусыДокументов[ИмяЗначения];
Исключение
// значение с таким именем не найдено
КонецПопытки;
Если имени в перечислении нет, обращение по индексу вызывает исключение, поэтому оборачивание в Попытка/Исключение обязательно. Альтернатива — перебор всех значений через метаданные с сравнением имён, но это медленнее и оправдано только при сложной логике поиска.
Для обратной задачи — получить строковое представление значения — используются разные подходы в зависимости от цели. Функция XMLСтрока(ЗначениеСтатуса) вернёт имя значения («Проведен») — это подходит для обмена и сериализации. Функция Строка(ЗначениеСтатуса) или строковое преобразование вернёт синоним — представление для пользователя, которое может отличаться от имени и меняться при доработке конфигурации. Сравнивать перечисления по синонимам нельзя: синоним — это оформление, а не идентификатор.
Сравнение через индекс значения
Метод Индекс() менеджера перечисления возвращает порядковый номер значения в списке: ИндексЗначения = Перечисления.СтатусыДокументов.Индекс(Статус). Нумерация начинается с нуля и соответствует порядку значений в конфигураторе. Обратное преобразование — метод Получить(ИндексЗначения).
Сравнение по индексу встречается в старом коде и в алгоритмах, где важен порядок значений: например, «статус не ниже согласования» можно записать как Если Перечисления.Статусы.Индекс(Статус) >= Перечисления.Статусы.Индекс(Перечисления.Статусы.Согласован) Тогда. Такой приём работает, только если порядок значений в конфигураторе отражает бизнес-логику — и ломается при перестановке значений.
Поэтому сравнение по индексу следует считать устаревшей практикой для обычных проверок равенства. Прямое сравнение значений надёжнее: оно не зависит от порядка в списке и самодокументируется. Индексы оправданы только там, где сам порядок несёт смысл, либо при работе с внешними системами, передающими числовые коды.
Способы сравнения перечислений
Основной способ. Быстро, проверяется компилятором, не зависит от порядка значений. Подходит почти всегда.
Когда допустимых значений несколько. Наглядно и легко расширяется, но чуть медленнее прямого сравнения.
Нужно при обмене с внешними системами, где значение приходит строкой. Требует обработки исключений.
Оправдано, только если порядок значений несёт бизнес-смысл. Хрупко: перестановка значений в конфигураторе ломает логику.
Сравнение перечислений в запросах
В языке запросов 1С значения перечислений указываются через ключевое слово ЗНАЧЕНИЕ: ГДЕ Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокументов.Проведен). Обратите внимание на синтаксис: в запросе используется единственное число «Перечисление», а не «Перечисления» как во встроенном языке.
Проверка на пустое значение в запросе выполняется сравнением с пустой ссылкой: ГДЕ Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокументов.ПустаяСсылка). Для проверки вхождения в список используется оператор В: ГДЕ Статус В (&СписокСтатусов), где параметр — массив или список значений, переданный в запрос.
Типичная ошибка — передавать в параметр запроса строку вместо значения перечисления. Запрос выполнится без ошибки, но не вернёт ни одной строки, потому что сравнение ссылки со строкой всегда ложно. Если запрос неожиданно пуст, первым делом проверьте типы параметров через отладчик или консоль запросов.
Сравнение значений из разных баз и при обмене
При интеграции двух информационных баз значения перечислений нельзя сравнивать напрямую — это объекты разных систем. Стандартный подход: передавать имя значения через XMLСтрока() на отправляющей стороне и восстанавливать значение через индексное обращение Перечисления.ВидОперации[ИмяЗначения] на принимающей. Такой механизм используется, в частности, в планах обмена и универсальных форматах.
Важное условие: имена значений в обеих конфигурациях должны совпадать. Если в одной базе значение называется «Проведен», а в другой «ПроведёнДокумент», прямое сопоставление по имени не сработает — потребуется таблица соответствий. При проектировании обмена заранее зафиксируйте сопоставление значений и предусмотрите обработку неизвестных имён: значение по умолчанию или запись в журнал ошибок.
Для перечислений, состав которых может расширяться, полезна защитная логика: если входящее имя не найдено, не прерывать обмен аварийно, а зафиксировать проблему и продолжить. Иначе добавление одного значения в конфигурацию-источник остановит всю интеграцию.
Как проверить корректность сравнения
Переменная имеет тип ПеречислениеСсылка, сравнение даёт ожидаемый результат
Тип переменной — Строка или Неопределено, условие всегда ложно
Возвращаются строки с нужным значением
Пустой результат при заведомо существующих данных — проверьте тип параметра
Значение восстановлено по имени, неизвестные имена пишутся в журнал
Обмен падает с исключением при новом значении перечисления
FAQ: частые вопросы о сравнении перечислений
Можно ли сравнивать перечисления операторами больше/меньше?
Нет, для значений перечислений операции упорядочивания напрямую не применяются. Если нужен порядок («статус выше согласования»), сравнивайте индексы значений через метод Индекс(), но помните, что такая логика зависит от порядка значений в конфигураторе.
Как узнать имя значения перечисления в коде?
Используйте функцию XMLСтрока(Значение) — она вернёт имя значения как оно задано в конфигураторе. Функция Строка() вернёт синоним (представление для пользователя), который для программной логики использовать не следует.
Чем отличается проверка ПустаяСсылка() от ЗначениеЗаполнено()?
Сравнение с ПустаяСсылка() работает только для конкретного типа перечисления. ЗначениеЗаполнено() универсальна: возвращает «Ложь» для пустых ссылок любых типов, пустых строк, нулей и пустых дат. Для составных типов реквизитов удобнее ЗначениеЗаполнено().
Почему запрос с отбором по перечислению возвращает пустой результат?
Чаще всего в параметр передана строка вместо значения перечисления — сравнение ссылки со строкой всегда ложно, но ошибки не возникает. Проверьте тип параметра в отладчике. Также убедитесь, что в условии используется ЗНАЧЕНИЕ(Перечисление.Имя.Значение) с правильным именем.
Как сравнить перечисление, если его имя заранее неизвестно?
Обратитесь к менеджеру через индексацию строкой: Перечисления[ИмяПеречисления][ИмяЗначения]. Оба обращения могут вызвать исключение при неверных именах, поэтому оборачивайте код в Попытка/Исключение и обрабатывайте ситуацию отсутствия значения.
Безопасно ли сравнивать перечисления по синониму для интерфейсных задач?
Нет. Синоним — это отображаемый текст, который может быть изменён при доработке конфигурации или локализации. Для логики используйте сравнение значений или имён, а синоним применяйте только для вывода сообщений пользователю.
Что важно запомнить
Сравнивайте перечисления напрямую операторами = и <> со значением вида Перечисления.Имя.Значение — это быстрый и надёжный способ. Никогда не сравнивайте со строкой или синонимом. Для пустых значений используйте ПустаяСсылка() или ЗначениеЗаполнено(), для списков допустимых значений — массив с Найти(), в запросах — ЗНАЧЕНИЕ(). При обмене между базами сопоставляйте значения по имени через XMLСтрока().