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