В системе 1С:Предприятие объект «Перечисление»** — один из базовых элементов конфигурации, который часто вызывает вопросы у начинающих разработчиков. На первый взгляд он кажется простым списком значений, но на практике его грамотное использование влияет на удобство работы, производительность и даже безопасность базы. Почему вместо обычных строк или чисел стоит заводить отдельное перечисление? Когда его применение оправдано, а когда лучше обойтись без него?
Эта статья поможет разобраться в назначении перечислений, их внутренней механике и типичных сценариях применения — от простых справочников до сложных алгоритмов с проверкой прав доступа. Мы также рассмотрим скрытые нюансы работы с перечислениями в запросах и на клиенте, которые редко упоминаются в документации, но могут сэкономить часы отладки.
Что такое перечисление в 1С и чем оно отличается от справочника
Перечисление (Enumeration в англоязычной терминологии платформы) — это статический набор именованных значений, который создаётся на этапе конфигурирования и не изменяется пользователями в процессе работы. В отличие от справочников, где данные можно добавлять, редактировать или удалять, перечисление жёстко фиксировано в метаданных.
Основные отличия от справочников:
- 📌 Статичность: значения перечисления задаются разработчиком и не меняются в runtime (без изменения конфигурации).
- 🔍 Производительность: доступ к значениям перечисления происходит быстрее, чем к элементам справочника, так как они хранятся в памяти платформы.
- 🔒 Безопасность: невозможно случайно или намеренно испортить данные (в отличие от справочников, где пользователь может удалить критически важный элемент).
- 📊 Типизация: перечисление — это отдельный тип данных, что упрощает контроль типов в коде.
Пример из жизни: если в базе нужно хранить статусы заказов («Новый», «В обработке», «Отгружен», «Отменён»), то перечисление подойдёт идеально. А вот для списка города доставки, который может пополняться, уже потребуется справочник.
Внутренняя структура перечисления: как оно хранится в базе
С технической точки зрения перечисление в 1С:Предприятие 8 представляет собой набор пар «Идентификатор — Значение», где:
- Идентификатор — уникальное имя значения (например,
СтатусЗаказа.Новый). Используется в коде для обращения к элементу. - Значение — отображаемое пользователю название (например, «Новый заказ»). Может быть многоязычным.
В базе данных перечисления хранятся в системных таблицах платформы, а их значения кэшируются при запуске сеанса. Это означает, что:
- 🚀 Нет накладных расходов на чтение из базы при каждом обращении.
- ⚠️ Изменения в перечислении требуют обновления конфигурации и перезапуска пользовательских сеансов.
| Характеристика | Перечисление | Справочник |
|---|---|---|
| Изменяемость в runtime | ❌ Нет | ✅ Да |
| Хранение в базе | Системные таблицы | Отдельные таблицы |
| Производительность чтения | ⚡ Мгновенно (кэш) | 🐢 Зависит от индексов |
| Многоязычность | ✅ Да (синонимы) | ✅ Да (реквизиты) |
| Использование в запросах | ✅ Как параметр | ✅ Как таблица |
Если перечисление используется в часто выполняемых запросах, добавьте его в список Используемые перечисления в настройках виртуальных таблиц — это ускорит работу с ними.
Когда стоит использовать перечисление, а когда — нет
Несмотря на очевидные преимущества, перечисления подходят не для всех случаев. Вот чек-лист, когда их применение оправдано:
Закрытый список значений (не меняется годами)
Нужна гарантия целостности данных (нет риска "битых" ссылок)
Требуется высокая производительность (например, в циклах)
Значения используются в логике прав доступа
Нужно ограничить выбор пользователя фиксированными вариантами-->
А вот когда не стоит использовать перечисления:
- 📛 Список может расширяться (например, виды номенклатуры или контрагенты).
- 🔄 Значения зависят от внешних систем (например, статусы из API банка).
- 📈 Нужна история изменений (перечисления не версиируются).
⚠️ Внимание: Если вы используете перечисление в Планах обмена, убедитесь, что его значения синхронизированы во всех базах-участниках. Расхождение приведёт к ошибкам при обмене!
Практические примеры применения перечислений
Рассмотрим реальные кейсы, где перечисления незаменимы:
1. Статусы документов
Классический пример — жизненный цикл заказа. Перечисление СтатусыЗаказов может включать значения:
Перем Статус;
Статус = Перечисления.СтатусыЗаказов.Новый;
Если Условие Тогда
Статус = Перечисления.СтатусыЗаказов.Отгружен;
КонецЕсли;
Преимущества:
- 🔗 Целостность: нельзя указать несуществующий статус.
- 🔍 Удобство отладки: в коде видно все возможные варианты.
- 📊 Отчёты: легко группировать документы по статусу.
2. Типы операций в бухгалтерии
В конфигурациях типа 1С:Бухгалтерия перечисления используются для ВидовОпераций (например, «Поступление», «Списание», «Инвентаризация»). Это позволяет:
- 📋 Автоматизировать проводки в зависимости от типа.
- 🔒 Контролировать права (например, только бухгалтер может проводить операции списания).
3. Параметры отчётов
Если в отчёте нужно выбрать Периодичность («День», «Неделя», «Месяц»), перечисление упростит:
- 📅 Валидацию ввода (нельзя ввести произвольный текст).
- 🖱️ Интерфейс: пользователь выбирает из выпадающего списка.
Как добавить иконки к значениям перечисления?
В конфигураторе откройте свойства перечисления → вкладка Значения → для каждого значения укажите путь к картинке (формат 16x16 пикселей). Иконки будут отображаться в формах выбора.
Работа с перечислениями в запросах и на клиенте
Перечисления можно использовать в запросах 1С, но есть нюансы:
1. В языке запросов
Чтобы отфильтровать документы по статусу из перечисления, пишите так:
ВЫБРАТЬ
Заказы.Ссылка КАК Ссылка
ИЗ
Документ.ЗаказКлиента КАК Заказы
ГДЕ
Заказы.Статус = &Статус
Где &Статус — параметр типа ПеречислениеСсылка.СтатусыЗаказов.
2. На клиенте (в формах)
Для отображения перечисления в форме используйте элемент ПолеВыбора с типом ПеречислениеСсылка.ИмяВашегоПеречисления. Пример:
ЭлементыФормы.Статус.ТипЗначения = Новый Тип("ПеречислениеСсылка.СтатусыЗаказов");
⚠️ Внимание: Если в форме нужно показать несколько значений перечисления (например, чекбоксы), используйтеГруппаПереключателейс привязкой к перечислению. Но помните: в базе такое поле будет храниться какЧисло(побитовая маска), а не как ссылка на перечисление!
Типичные ошибки при работе с перечислениями
Даже опытные разработчики иногда допускают ошибки. Вот самые распространённые:
1. Сравнение по имени вместо значения
❌ Плохо:
Если Статус.Представление() = "Отгружен" Тогда
✅ Хорошо:
Если Статус = Перечисления.СтатусыЗаказов.Отгружен Тогда
Первый вариант зависит от языка интерфейса (представление может быть «Shipped» в английской версии).
2. Изменение перечисления в работающей базе
Если вы:
- 🔄 Добавили новое значение — пользователи увидят его после обновления.
- ❌ Удалили или переименовали значение — данные, ссылающиеся на него, станут некорректными!
Всегда проверяйте использование перечисления в базе перед его изменением. Для этого в конфигураторе используйте отчёт Где используется (ПКМ на перечислении → Все команды).
3. Хранение перечислений в регистрах
Если вы сохраняете значение перечисления в РегистрСведений, убедитесь, что:
- 🔗 Тип ресурса/измерения —
ПеречислениеСсылка.ИмяВашегоПеречисления. - 🔄 При изменении перечисления данные в регистре не портятся (может потребоваться миграция).
Как оптимизировать работу с перечислениями
Несколько советов для повышения производительности и удобства:
1. Кэширование часто используемых перечислений
Если перечисление используется в цикле или рекурсивной функции, заранее сохраните его значения в переменную:
Перем Статусы;
Статусы = Перечисления.СтатусыЗаказов;
Для Каждого Заказ Из Заказы Цикл
Если Заказ.Статус = Статусы.Отгружен Тогда
// ...
КонецЕсли;
КонецЦикла;
2. Использование в расчётах
Перечисления удобны для Вычисляемых полей. Например, в отчёте можно добавить колонку:
ВЫБРАТЬ
Заказы.Статус КАК Статус,
ВЫРАЗИТЬ(Заказы.Статус = &Отгружен КАК Число(1, 0)) КАК Отгружен
ИЗ
Документ.ЗаказКлиента КАК Заказы
3. Локализация
Для многоязычных баз настройте синонимы перечислений:
- В конфигураторе откройте перечисление → вкладка
Синонимы. - Добавьте переводы для каждого значения (например, «Новый» → «New»).
Чтобы быстро найти все перечисления в конфигурации, используйте поиск по метаданным (Ctrl+Shift+F) с фильтром Тип = Перечисление.)
FAQ: Частые вопросы о перечислениях в 1С
Можно ли динамически добавлять значения в перечисление без изменения конфигурации?
Нет, перечисление — статический объект метаданных. Если нужен динамический список, используйте справочник или регистр сведений с предопределёнными элементами.
Как получить все значения перечисления в массиве?
Используйте метод ЗначенияПеречисления():
МассивСтатусов = Перечисления.СтатусыЗаказов.ЗначенияПеречисления();
Вернёт массив со всеми значениями перечисления.
Почему при обмене данными теряются значения перечислений?
Это происходит, если:
- В базе-приёмнике нет такого перечисления.
- Идентификаторы значений (
UID) не совпадают. - В плане обмена не настроено сопоставление для этого перечисления.
Решение: синхронизируйте метаданные перед обменом.
Можно ли использовать перечисление как измерение в регистре накопления?
Да, но учитывайте:
- 📊 В отчётах по такому регистру будет удобная группировка по значениям перечисления.
- ⚠️ При изменении перечисления (удаление/переименование значений) данные в регистре могут стать некорректными.
Как узнать, какое значение перечисления выбрано в форме?
Если поле формы привязано к перечислению, его значение — это ПеречислениеСсылка. Чтобы получить идентификатор:
Сообщить(ЭлементыФормы.Статус.Значение.Идентификатор());
Для отображаемого имени:
Сообщить(ЭлементыФормы.Статус.Значение.Представление());