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

Если вы когда-нибудь сталкивались с кодом, где статусы заказа хранились в виде чисел 1, 2, 3 без пояснений, или видели условия вида Если Статус = "Оплачено" Тогда..., где вместо "Оплачено" могло быть опечаткой "Оплочено" — вы уже понимаете, почему перечисления критически важны. Они не просто упорядочивают данные, но и превращают абстрактные значения в самодокументируемый код, снижая риск ошибок на 80% по статистике типичных багов в 1С.

В этой статье разберём, зачем нужен объект «Перечисление», как он устроен изнутри, где применяется на практике (включая неочевидные сценарии), и почему его часто путают со справочниками. А ещё — типичные ошибки, которые допускают даже опытные разработчики, и как их избежать.

Что такое перечисление в 1С и зачем оно нужно

Перечисление — это объект конфигурации, который представляет собой фиксированный набор значений (элементов), каждому из которых присвоено уникальное имя и внутренний идентификатор. В отличие от справочников, где пользователь может добавлять новые элементы «на лету», состав перечисления жёстко задан на этапе разработки и не меняется в процессе работы программы.

Основные задачи, которые решает перечисление:

  • 🔹 Замена «магических чисел» — вместо сравнения с Статус = 3 пишется Статус = Перечисление.СтатусыЗаказа.Оплачено, что делает код понятным без комментариев.
  • 🔹 Централизованное управление значениями — если название статуса нужно изменить (например, с "Оплачено" на "Оплачен"), это делается в одном месте — в конфигураторе, а не во всех модулях кода.
  • 🔹 Типизация данных — компилятор 1С проверяет, что в переменную типа Перечисление.СтатусыЗаказа нельзя записать значение из другого перечисления или произвольную строку.
  • 🔹 Локализация — имена элементов перечисления можно перевести на другие языки через механизм синхронизации конфигурации.

Простой пример: представьте, что в вашей базе есть документ ЗаказПокупателя, у которого есть реквизит Статус. Без перечисления статусы могли бы храниться как строки: "Новый", "В обработке", "Отгружен". А теперь представьте, что в коде где-то опечатка: Если Статус = "Отгруженн" Тогда.... Такую ошибку сложно отловить, а с перечислением она невозможна — компилятор просто не даст записать несуществующее значение.

📊 Как вы обычно храните статусы в 1С?
В перечислениях
В справочниках
В виде чисел/строк
Не знаю, что такое перечисления

Структура перечисления: из чего оно состоит

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

  1. Имя перечисления — уникальный идентификатор (например, ВидыОплаты). По нему обращаются к перечислению в коде.
  2. Синоним — отображаемое имя для пользователя (например, "Виды оплаты").
  3. Элементы — фиксированный набор значений, каждому из которых присваивается:
    • 📌 Имя (например, Наличные, БезналичныйРасчет)
    • 📌 Синоним (например, "Наличные", "Безналичный расчёт")
    • 📌 Значение — внутренний числовой идентификатор (по умолчанию автонумерация с 0, но можно задать вручную).
  4. Комментарий — описание назначения перечисления (необязательно, но полезно для документации).
  5. Важный момент: значения элементов (те самые числа) можно задавать вручную. Это бывает полезно, если нужно:

    • 🔄 Сохранить совместимость с внешними системами (например, в API статусы передаются с фиксированными кодами).
    • 🔄 Объединить несколько перечислений в одно, избегая конфликтов идентификаторов.
    • 🔄 Зарезервировать диапазоны значений для будущих элементов.
    💡

    Если вы вручную задаёте значения элементов перечисления, оставляйте «про запас» диапазоны чисел (например, 0–99 для одного типа статусов, 100–199 для другого). Это упростит добавление новых элементов без рефакторинга кода.

    Свойство Пример Назначение
    Имя перечисления СтатусыДокументов Идентификатор для обращения в коде
    Синоним "Статусы документов" Отображаемое имя для пользователя
    Имя элемента ОжидаетОплаты Идентификатор значения в коде
    Синоним элемента "Ожидает оплаты" Текст, который видит пользователь в интерфейсе
    Значение элемента 1 Внутренний числовой код (по умолчанию автоинкремент)

    Где применяются перечисления: от очевидного к неочевидному

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

    1. Статусы документов и бизнес-процессов

    Классический пример: перечисление СтатусыЗаказа с элементами Новый, ВОбработке, Отгружен, Закрыт. Это позволяет:

    • 📋 Контролировать переходы между статусами (например, из Отгружен нельзя вернуться в Новый).
    • 📋 Автоматически Assign'ить задачи сотрудникам при смене статуса.
    • 📋 Строить отчёты по количеству заказов в каждом статусе.

    2. Типы операций в регистрах

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

    Перечисление.ТипыДвиженийТоваров.Приход
    

    Перечисление.ТипыДвиженийТоваров.Расход

    Перечисление.ТипыДвиженийТоваров.Корректировка

    Это упрощает фильтрацию движений и проверку корректности операций.

    3. Параметры интеграции с внешними системами

    При обмене данными с сайтами, банками или госсистемами (например, Диадок, СБИС) перечисления помогают маппить внутренние статусы 1С на внешние коды. Например:

    Если СтатусЗаказа = Перечисление.СтатусыЗаказа.Оплачено Тогда
    

    СтатусДляAPI = "PAID"; // Код для внешней системы

    КонецЕсли;

    4. Настройки пользовательского интерфейса

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

    • 📊 Линейный
    • 📈 Столбчатый
    • 🍩 КруговаяДиаграмма

    5. Логические флаги с расширенной семантикой

    Вместо булевых полей (Истина/Ложь) иногда удобнее использовать перечисления. Например, для поля ТипКлиента:

    • 👤 ФизическоеЛицо
    • 🏢 ЮридическоеЛицо
    • 🤝 ИП

    Это даёт больше информации, чем просто ЮрЛицо = Истина.

    💡

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

    Перечисления vs справочники: когда что использовать

    Новички в 1С часто путают перечисления со справочниками. Главное отличие — справочники предназначены для динамических данных (например, список контрагентов или номенклатуры), а перечисления — для статических. Но есть и более тонкие нюансы:

    Критерий Перечисление Справочник
    Изменяемость данных Фиксированный набор значений (меняется только в конфигураторе) Пользователь может добавлять/удалять элементы
    Производительность Быстрее (значения хранятся в метаданных) Медленнее (данные читаются из базы)
    Локализация Поддерживается (синонимы переводятся) Требует ручного перевода или механизма многоязычности
    Иерархия Нет (все элементы одного уровня) Есть (можно создавать группы и подчиненные элементы)
    Дополнительные реквизиты Нет Есть (можно добавлять произвольные поля)

    Когда стоит выбрать справочник вместо перечисления:

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

    Когда перечисление предпочтительнее:

    • 🔄 Если значения жёстко заданы бизнес-логикой (например, ТипыДокументов для бухгалтерских проводок).
    • 🔄 Если важна производительность (например, в высоконагруженных расчётах).
    • 🔄 Если нужно гарантировать, что в коде не появится «левое» значение (например, опечатка в строке).
    Когда справочник всё-таки лучше перечисления?

    Если вы сомневаетесь, задайте себе вопросы:

    1. Будут ли пользователи добавлять новые значения? → Если да, нужен справочник.

    2. Нужно ли хранить дополнительные данные о каждом элементе? → Если да, нужен справочник.

    3. Важно ли, чтобы значения были фиксированы и контролировались на этапе разработки? → Если да, подойдёт перечисление.

    Как работать с перечислениями в коде 1С

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

    1. Обращение к элементам перечисления

    Чтобы получить значение элемента перечисления, используйте точечную нотацию:

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

    Или через функцию ЗначениеЗаполнено() для проверки:

    Если ЗначениеЗаполнено(Перечисление.СтатусыЗаказа.Оплачено) Тогда
    

    // Код

    КонецЕсли;

    2. Сравнение значений

    Перечисления можно сравнивать напрямую:

    Если ТекущийСтатус = Перечисление.СтатусыЗаказа.Отгружен Тогда
    

    Сообщить("Заказ отгружен!");

    КонецЕсли;

    Или через функцию ЗначениеВПеречислении(), если нужно проверить принадлежность к перечислению:

    Если ЗначениеВПеречислении(Перечисление.СтатусыЗаказа, ТекущийСтатус) Тогда
    

    // ТекущийСтатус — это элемент перечисления СтатусыЗаказа

    КонецЕсли;

    3. Получение списка всех элементов

    Чтобы перебрать все элементы перечисления, используйте метод ЗначенияПеречисления():

    Для Каждого Элемент Из Перечисление.СтатусыЗаказа.ЗначенияПеречисления() Цикл
    

    Сообщить(Элемент.Представление()); // Выведет синонимы: "Новый", "Оплачено" и т.д.

    КонецЦикла;

    4. Преобразование в строку и обратно

    Чтобы получить строковое представление элемента (его синоним), используйте метод Представление():

    СтрокаСтатуса = Перечисление.СтатусыЗаказа.Оплачено.Представление(); // "Оплачено"

    Обратное преобразование (из строки в элемент перечисления) делается через ПолноеИмяЗначения() или НайтиПоНаименованию():

    Элемент = Перечисление.СтатусыЗаказа.НайтиПоНаименованию("Оплачено");

    Используйте точечную нотацию для доступа к элементам|Проверяйте принадлежность к перечислению через ЗначениеВПеречислении()|Для перебора элементов используйте ЗначенияПеречисления()|Преобразуйте в строку через Представление(), а обратно — через НайтиПоНаименованию()-->

    5. Работа с значениями (числовыми кодами)

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

    КодСтатуса = Перечисление.СтатусыЗаказа.Оплачено.Значение; // Например, 2

    Обратное преобразование (из числа в элемент) делается через ПолноеИмяЗначения():

    Элемент = Перечисление.СтатусыЗаказа.ПолноеИмяЗначения(2); // Вернёт "Оплачено"
    ⚠️ Внимание: Если вы вручную задаёте числовые значения элементов перечисления, следите, чтобы они не пересекались. Например, если в перечислении СтатусыЗаказа элемент Оплачено имеет значение 2, а в перечислении ТипыДокументов элемент Счёт тоже имеет значение 2, это может привести к ошибкам при преобразованиях.

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

    Даже опытные разработчики 1С иногда допускают ошибки при работе с перечислениями. Вот наиболее распространённые из них и как их избежать:

    1. Жёсткое сравнение с числовыми кодами

    Плохой пример:

    Если Статус = 2 Тогда // Магическое число!
    

    // Код

    КонецЕсли;

    Правильно:

    Если Статус = Перечисление.СтатусыЗаказа.Оплачено Тогда
    

    // Код

    КонецЕсли;

    Почему плохо: если значение элемента Оплачено поменяется (например, с 2 на 3), код сломается.

    2. Использование строк вместо перечислений

    Плохой пример:

    Если Статус = "Оплачено" Тогда // Опечатка "Оплочено" не будет поймана компилятором
    

    // Код

    КонецЕсли;

    Правильно:

    Если Статус = Перечисление.СтатусыЗаказа.Оплачено Тогда
    

    // Код

    КонецЕсли;

    3. Изменение значений элементов в работающей базе

    Если вы вручную поменяете числовые значения элементов перечисления в конфигураторе (например, с 2 на 4), это может сломать:

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

    1. Сделайте резервную копию.

    2. Напишите обработку для конвертации старых значений в новые.

    3. Проверьте все интеграции и отчёты на совместимость.

    4. Слишком большие перечисления

    Если в перечислении больше 20–30 элементов, это признак того, что:

    • 🔍 Возможно, часть значений стоит вынести в отдельное перечисление.
    • 🔍 Или нужно использовать справочник (если значения динамические).

Пример плохого дизайна: перечисление ВсеГородаРоссии с 1000+ элементов. Здесь однозначно нужен справочник.

5. Неучтённые значения при обмене данными

При интеграции с внешними системами иногда забывают, что в перечислении 1С может не быть значения, пришедшего извне. Например, из API пришёл статус "PARTIALLY_PAID", а в 1С нет такого элемента. Это приведёт к ошибке.

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

Попытка

Статус = Перечисление.СтатусыЗаказа.НайтиПоНаименованию(СтатусИзAPI);

Исключение

Статус = Перечисление.СтатусыЗаказа.Неопределён; // Запасной вариант

КонецПопытки;

Продвинутые приёмы работы с перечислениями

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

1. Перечисления как флаги (битовые маски)

Иногда перечисления используют для хранения флагов (например, прав доступа). Для этого значения элементов задают как степени двойки:

Перечисление.ПраваДоступа.Чтение      // Значение = 1 (2^0)

Перечисление.ПраваДоступа.Запись // Значение = 2 (2^1)

Перечисление.ПраваДоступа.Удаление // Значение = 4 (2^2)

Тогда права можно комбинировать через побитовое ИЛИ:

Права = Перечисление.ПраваДоступа.Чтение | Перечисление.ПраваДоступа.Запись; // 1 | 2 = 3

А проверять через побитовое И:

Если Права И Перечисление.ПраваДоступа.Запись <> 0 Тогда

// Есть право на запись

КонецЕсли;

2. Локализация перечислений

Если ваша конфигурация используется в нескольких странах, синонимы элементов перечисления можно локализовать. Для этого:

  1. Откройте перечисление в конфигураторе.
  2. В панели свойств перейдите на вкладку Локализация.
  3. Добавьте переводы для каждого языка (например, для Оплачено на английском будет "Paid").

При смене языка интерфейса 1С автоматически подставит правильный синоним.

3. Динамическое создание перечислений (метаданные)

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

ПеречислениеОбъект = Метаданные.Перечисления.Добавить();

ПеречислениеОбъект.Имя = "ДинамическоеПеречисление";

Элемент = ПеречислениеОбъект.Элементы.Добавить();

Элемент.Имя = "Элемент1";

Элемент.Синоним = "Первый элемент";

⚠️ Внимание: Динамическое изменение метаданных — опасная операция. Она может привести к несовместимости версий конфигурации и потере данных. Используйте этот приём только в крайних случаях, например, при миграциях или генерации тестовых конфигураций.

4. Перечисления в запросах

В языке запросов 1С перечисления можно использовать для фильтрации. Например, чтобы выбрать документы с определённым статусом:

Выбрать

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

Из

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

Где

Заказы.Статус = &Статус

// Параметр запроса:

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

5. Сериализация перечислений в JSON/XML

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

// Для JSON

Данные = Новый Структура();

Данные.Вставить("СтатусКод", Статус.Значение); // Передаём число, а не строку

// Для XML

ЗаписьXML.ЗаписатьАтрибут("СтатусКод", Статус.Значение);

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

Можно ли добавлять элементы в перечисление во время работы программы?

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

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

Используйте свойство Значение:

КодЭлемента = Перечисление.СтатусыЗаказа.Оплачено.Значение;

По умолчанию элементы нумеруются с 0, но вы можете задать произвольные значения в конфигураторе.

Что будет, если удалить элемент из перечисления, которое используется в базе?

Это приведёт к ошибкам при обращении к данным, где хранилось удалённое значение. Например, если в документе был статус ОжидаетОплаты, а вы его удалили, при открытии документа 1С выдаст ошибку "Значение не является значением перечисления".

Решение: вместо удаления помечайте элементы как устаревшие (например, добавляйте префикс "Удалён_" к имени) и обрабатывайте их в коде.

Можно ли использовать перечисления в мобильной платформе 1С?

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

Как сделать, чтобы перечисление отображалось в форме как выпадающий список?

Добавьте в форму реквизит типа ПеречислениеСсылка.ИмяВашегоПеречисления и свяжите его с элементом управления ПолеВыбора. 1С автоматически отобразит его как выпадающий список с синонимами элементов.

Пример объявления реквизита формы:

&НаКлиенте

Перем СтатусЗаказа;

В свойствах элемента формы укажите тип: ПеречислениеСсылка.СтатусыЗаказа.