В системе 1С:Предприятие объект конфигурации «Перечисление» — один из базовых элементов, который часто остаётся в тени более «громких» сущностей вроде справочников или документов. Однако без грамотного использования перечислений невозможно создать удобную, поддерживаемую и логически стройную конфигурацию. Этот объект решает задачи, которые на первый взгляд кажутся тривиальными, но без него прикладные решения быстро превращаются в хаос из «магических чисел», жёстко прописанных строк и трудноотлаживаемого кода.
Если вы когда-нибудь сталкивались с кодом, где статусы заказа хранились в виде чисел 1, 2, 3 без пояснений, или видели условия вида Если Статус = "Оплачено" Тогда..., где вместо "Оплачено" могло быть опечаткой "Оплочено" — вы уже понимаете, почему перечисления критически важны. Они не просто упорядочивают данные, но и превращают абстрактные значения в самодокументируемый код, снижая риск ошибок на 80% по статистике типичных багов в 1С.
В этой статье разберём, зачем нужен объект «Перечисление», как он устроен изнутри, где применяется на практике (включая неочевидные сценарии), и почему его часто путают со справочниками. А ещё — типичные ошибки, которые допускают даже опытные разработчики, и как их избежать.
Что такое перечисление в 1С и зачем оно нужно
Перечисление — это объект конфигурации, который представляет собой фиксированный набор значений (элементов), каждому из которых присвоено уникальное имя и внутренний идентификатор. В отличие от справочников, где пользователь может добавлять новые элементы «на лету», состав перечисления жёстко задан на этапе разработки и не меняется в процессе работы программы.
Основные задачи, которые решает перечисление:
- 🔹 Замена «магических чисел» — вместо сравнения с
Статус = 3пишетсяСтатус = Перечисление.СтатусыЗаказа.Оплачено, что делает код понятным без комментариев. - 🔹 Централизованное управление значениями — если название статуса нужно изменить (например, с
"Оплачено"на"Оплачен"), это делается в одном месте — в конфигураторе, а не во всех модулях кода. - 🔹 Типизация данных — компилятор 1С проверяет, что в переменную типа
Перечисление.СтатусыЗаказанельзя записать значение из другого перечисления или произвольную строку. - 🔹 Локализация — имена элементов перечисления можно перевести на другие языки через механизм синхронизации конфигурации.
Простой пример: представьте, что в вашей базе есть документ ЗаказПокупателя, у которого есть реквизит Статус. Без перечисления статусы могли бы храниться как строки: "Новый", "В обработке", "Отгружен". А теперь представьте, что в коде где-то опечатка: Если Статус = "Отгруженн" Тогда.... Такую ошибку сложно отловить, а с перечислением она невозможна — компилятор просто не даст записать несуществующее значение.
Структура перечисления: из чего оно состоит
В конфигураторе перечисление выглядит как простой список элементов, но у него есть скрытые нюансы, которые важно понимать. Рассмотрим структуру на примере создания перечисления ВидыОплаты:
- Имя перечисления — уникальный идентификатор (например,
ВидыОплаты). По нему обращаются к перечислению в коде. - Синоним — отображаемое имя для пользователя (например,
"Виды оплаты"). - Элементы — фиксированный набор значений, каждому из которых присваивается:
- 📌 Имя (например,
Наличные,БезналичныйРасчет) - 📌 Синоним (например,
"Наличные","Безналичный расчёт") - 📌 Значение — внутренний числовой идентификатор (по умолчанию автонумерация с 0, но можно задать вручную).
- 📌 Имя (например,
- Комментарий — описание назначения перечисления (необязательно, но полезно для документации).
- 🔄 Сохранить совместимость с внешними системами (например, в API статусы передаются с фиксированными кодами).
- 🔄 Объединить несколько перечислений в одно, избегая конфликтов идентификаторов.
- 🔄 Зарезервировать диапазоны значений для будущих элементов.
- 📋 Контролировать переходы между статусами (например, из
Отгруженнельзя вернуться вНовый). - 📋 Автоматически Assign'ить задачи сотрудникам при смене статуса.
- 📋 Строить отчёты по количеству заказов в каждом статусе.
- 📊
Линейный - 📈
Столбчатый - 🍩
КруговаяДиаграмма - 👤
ФизическоеЛицо - 🏢
ЮридическоеЛицо - 🤝
ИП - 🔄 Если набор значений может пополняться пользователем (например,
СписокГорода). - 🔄 Если нужно хранить дополнительную информацию о каждом элементе (например, для
Контрагента— ИНН, адрес, телефон). - 🔄 Если требуется иерархия (например,
Номенклатурас группами"Электроника"→"Телефоны"). - 🔄 Если значения жёстко заданы бизнес-логикой (например,
ТипыДокументовдля бухгалтерских проводок). - 🔄 Если важна производительность (например, в высоконагруженных расчётах).
- 🔄 Если нужно гарантировать, что в коде не появится «левое» значение (например, опечатка в строке).
- 🔥 Данные в базе (если статусы хранились как числа в регистрах или документах).
- 🔥 Обмены данными с внешними системами (если они ориентировались на старые коды).
- 🔥 Отчёты и обработки, где использовались жёсткие сравнения.
- 🔍 Возможно, часть значений стоит вынести в отдельное перечисление.
- 🔍 Или нужно использовать справочник (если значения динамические).
Важный момент: значения элементов (те самые числа) можно задавать вручную. Это бывает полезно, если нужно:
Если вы вручную задаёте значения элементов перечисления, оставляйте «про запас» диапазоны чисел (например, 0–99 для одного типа статусов, 100–199 для другого). Это упростит добавление новых элементов без рефакторинга кода.
| Свойство | Пример | Назначение |
|---|---|---|
| Имя перечисления | СтатусыДокументов |
Идентификатор для обращения в коде |
| Синоним | "Статусы документов" |
Отображаемое имя для пользователя |
| Имя элемента | ОжидаетОплаты |
Идентификатор значения в коде |
| Синоним элемента | "Ожидает оплаты" |
Текст, который видит пользователь в интерфейсе |
| Значение элемента | 1 |
Внутренний числовой код (по умолчанию автоинкремент) |
Где применяются перечисления: от очевидного к неочевидному
На первый взгляд, перечисления нужны только для хранения статусов документов или типов операций. Но на практике их применяют гораздо шире. Вот несколько сценариев — от стандартных до креативных:
1. Статусы документов и бизнес-процессов
Классический пример: перечисление СтатусыЗаказа с элементами Новый, ВОбработке, Отгружен, Закрыт. Это позволяет:
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. Локализация перечислений
Если ваша конфигурация используется в нескольких странах, синонимы элементов перечисления можно локализовать. Для этого:
- Откройте перечисление в конфигураторе.
- В панели свойств перейдите на вкладку
Локализация. - Добавьте переводы для каждого языка (например, для
Оплаченона английском будет"Paid").
При смене языка интерфейса 1С автоматически подставит правильный синоним.
3. Динамическое создание перечислений (метаданные)
В редких случаях перечисления можно создавать или модифицировать программно через объект Метаданные. Это требует прав администратора и используется, например, при генерации конфигураций «на лету»:
ПеречислениеОбъект = Метаданные.Перечисления.Добавить();
ПеречислениеОбъект.Имя = "ДинамическоеПеречисление";
Элемент = ПеречислениеОбъект.Элементы.Добавить();
Элемент.Имя = "Элемент1";
Элемент.Синоним = "Первый элемент";
⚠️ Внимание: Динамическое изменение метаданных — опасная операция. Она может привести к несовместимости версий конфигурации и потере данных. Используйте этот приём только в крайних случаях, например, при миграциях или генерации тестовых конфигураций.
4. Перечисления в запросах
В языке запросов 1С перечисления можно использовать для фильтрации. Например, чтобы выбрать документы с определённым статусом:
Выбрать
Заказы.Ссылка Как Ссылка
Из
Документ.ЗаказПокупателя Как Заказы
Где
Заказы.Статус = &Статус
// Параметр запроса:
Запрос.УстановитьПараметр("Статус", Перечисление.СтатусыЗаказа.Оплачено);
5. Сериализация перечислений в JSON/XML
При обмене данными перечисления автоматически сериализуются в строки (их синонимы). Если нужно передать числовые коды, используйте свойство Значение:
// Для JSON
Данные = Новый Структура();
Данные.Вставить("СтатусКод", Статус.Значение); // Передаём число, а не строку
// Для XML
ЗаписьXML.ЗаписатьАтрибут("СтатусКод", Статус.Значение);
FAQ: Частые вопросы о перечислениях в 1С
Можно ли добавлять элементы в перечисление во время работы программы?
Нет, состав перечисления фиксирован и может изменяться только в конфигураторе. Если вам нужно динамически добавлять значения, используйте справочник.
Как узнать, какое числовое значение у элемента перечисления?
Используйте свойство Значение:
КодЭлемента = Перечисление.СтатусыЗаказа.Оплачено.Значение;
По умолчанию элементы нумеруются с 0, но вы можете задать произвольные значения в конфигураторе.
Что будет, если удалить элемент из перечисления, которое используется в базе?
Это приведёт к ошибкам при обращении к данным, где хранилось удалённое значение. Например, если в документе был статус ОжидаетОплаты, а вы его удалили, при открытии документа 1С выдаст ошибку "Значение не является значением перечисления".
Решение: вместо удаления помечайте элементы как устаревшие (например, добавляйте префикс "Удалён_" к имени) и обрабатывайте их в коде.
Можно ли использовать перечисления в мобильной платформе 1С?
Да, перечисления полностью поддерживаются в 1С:Предприятие 8 для мобильных устройств. Они сериализуются и передаются на клиент так же, как и в десктопной версии.
Как сделать, чтобы перечисление отображалось в форме как выпадающий список?
Добавьте в форму реквизит типа ПеречислениеСсылка.ИмяВашегоПеречисления и свяжите его с элементом управления ПолеВыбора. 1С автоматически отобразит его как выпадающий список с синонимами элементов.
Пример объявления реквизита формы:
&НаКлиенте
Перем СтатусЗаказа;
В свойствах элемента формы укажите тип: ПеречислениеСсылка.СтатусыЗаказа.