К статье
Практический материал

Разработка и Конфигурация · 8 мин

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

Способы перебора значений перечисления в 1С: цикл по Перечисления.Метаданные, ПеречислениеМенеджер, запросы. Примеры кода, ошибки и ответы на вопросы.

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

Задача перебрать все значения перечисления возникает при формировании отчётов, заполнении списков выбора, проверке полноты данных и при выгрузке во внешние системы. В зависимости от контекста — толстый клиент, тонкий клиент, внешнее соединение — доступны разные подходы.

Ниже разобраны основные способы: цикл через метаданные, обращение через менеджер перечисления, перебор в запросе и перебор без знания имени перечисления на этапе разработки. Для каждого приведён рабочий код и указаны ограничения.

Перебор значений через метаданные

Универсальный способ — обратиться к коллекции ЗначенияПеречисления объекта метаданных. Каждый элемент этой коллекции хранит имя значения, синоним и индекс. Само значение перечисления получают по имени через менеджер.

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.СтавкиНДС.ЗначенияПеречисления Цикл

ЗначениеПеречисления = Перечисления.СтавкиНДС[ЗначениеМетаданных.Имя];

Сообщить(ЗначениеМетаданных.Имя + " — " + Строка(ЗначениеПеречисления));

КонецЦикла;

Такой код работает и на сервере, и на клиенте (в управляемых формах — в контексте &НаСервере или &НаКлиенте, поскольку перечисления доступны в обоих). Порядок перебора соответствует порядку значений, заданному в конфигураторе, что удобно для вывода в привычной последовательности.

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

Перебор через менеджер перечисления

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

Менеджер = Перечисления.СтавкиНДС;

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

ТекущееЗначение = Менеджер[ЗначениеМетаданных.Имя];

// работа с ТекущееЗначение

КонецЦикла;

Дополнительно у менеджера есть методы ПолучитьИндексПоИмени и обратное получение имени по значению через метаданные: ЗначениеМетаданных = Перечисления.СтавкиНДС.Ставка20.Метаданные() вернёт объект описания конкретного значения, откуда доступны имя и синоним.

Обратное преобразование — получить имя по значению — делается так: ИмяЗначения = ЗначениеПеречисления.Метаданные().Имя не сработает, так как метод вернёт метаданные всего перечисления. Правильно: перебрать коллекцию значений и сравнить, либо использовать Метаданные.Перечисления.Имя.ЗначенияПеречисления.Найти(Индекс).

Универсальный перебор без знания имени перечисления

Когда имя перечисления приходит как строка (например, из настроек обработки), используют индексацию по коллекции Метаданные.Перечисления и Перечисления:

ИмяПеречисления = "СтавкиНДС";

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления Цикл

Значение = Перечисления[ИмяПеречисления][ЗначениеМетаданных.Имя];

Сообщить(Строка(Значение));

КонецЦикла;

Перед обращением стоит проверить существование объекта: Метаданные.Перечисления.Найти(ИмяПеречисления) вернёт Неопределено, если перечисления с таким именем нет. Без проверки попытка обращения вызовет исключение и прервёт выполнение обработки.

Перебор значений в запросе

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

ВЫБРАТЬ

Ставки.Ссылка КАК Ставка,

Ставки.Порядок КАК Порядок

ИЗ

Перечисление.СтавкиНДС КАК Ставки

УПОРЯДОЧИТЬ ПО

Ставки.Порядок

Второй способ — явное перечисление значений через ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.Ставка20). Этот вариант подходит, когда нужны не все значения, а конкретные, например для фильтрации данных документов.

Виртуальная таблица перечисления удобна для отчётов на СКД: она позволяет вывести все значения, включая те, по которым нет данных, и соединить их с оборотами. Это стандартный приём для отчётов вида «показать нули по отсутствующим позициям».

bsl
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ Перечисление.СтавкиНДС КАК Т"); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Сообщить(Выборка.Ссылка); КонецЦикла;

Заполнение списка выбора и проверка результата

Частая практическая задача — заполнить список выбора элемента формы всеми значениями перечисления. На управляемой форме это делается на сервере:

Элементы.ПолеСтавки.СписокВыбора.Очистить();

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.СтавкиНДС.ЗначенияПеречисления Цикл

Элементы.ПолеСтавки.СписокВыбора.Добавить(

Перечисления.СтавкиНДС[ЗначениеМетаданных.Имя],

ЗначениеМетаданных.Синоним);

КонецЦикла;

После реализации проверьте результат: количество элементов в списке должно совпадать с числом значений в конфигураторе, порядок — с порядком в палитре свойств перечисления, представления — с синонимами. Если список пуст, чаще всего причина в том, что код выполнился не в том контексте или имя перечисления указано с ошибкой.

Контрольные точки

Как проверить результат

Количество перебранных значений
Норма

Совпадает с числом значений в конфигураторе

Тревожный признак

Меньше — проверьте имя перечисления и контекст выполнения

Порядок значений
Норма

Соответствует порядку в метаданных

Тревожный признак

Произвольный — возможно, использована сортировка в запросе без Порядок

Представления
Норма

Выводятся синонимы, понятные пользователю

Тревожный признак

Выводятся технические имена — используйте свойство Синоним

Типичные ошибки при переборе перечислений

Самая распространённая ошибка — попытка перебрать перечисление как справочник через Выбрать(). У менеджера перечисления нет такого метода, потому что значения не хранятся в базе данных как объекты. Вторая частая ошибка — обращение к значению по синониму вместо имени: Перечисления.СтавкиНДС["НДС 20%"] вызовет исключение, нужно использовать имя Ставка20.

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

Типичные ошибки
01
Вызов Выбрать() у менеджера перечисления — метод не существует, перебор делается через метаданные
02
Обращение по синониму вместо имени значения — исключение во время выполнения
03
Ожидание пустой ссылки в цикле — она не входит в коллекцию значений
04
Строковые имена без проверки Найти() — падение обработки после переименования объекта

Часто задаваемые вопросы

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

Используйте индекс: Индекс = Перечисления.ИмяПеречисления.Индекс(Значение), затем Метаданные.Перечисления.ИмяПеречисления.ЗначенияПеречисления[Индекс].Имя. Прямого свойства «Имя» у значения перечисления нет.

Можно ли перебрать перечисления на клиенте в управляемом приложении?

Да, перечисления и их метаданные доступны и в контексте &НаКлиенте. Обращение к Метаданные на клиенте работает, но при большом числе обращений логичнее выполнить перебор один раз на сервере и передать готовый список.

Как перебрать значения всех перечислений конфигурации сразу?

Вложенным циклом: сначала Для Каждого ПеречислениеМетаданные Из Метаданные.Перечисления, затем внутри цикл по ПеречислениеМетаданные.ЗначенияПеречисления. Значение получают через Перечисления[ПеречислениеМетаданные.Имя][ИмяЗначения].

Почему запрос к таблице Перечисление.Имя возвращает мало колонок?

Виртуальная таблица перечисления содержит только Ссылка и Порядок — это ограничение платформы. Синоним в запросе получают через ПРЕДСТАВЛЕНИЕ(Ссылка), а имя значения в запросе недоступно.

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

Напрямую: Если Документ.Ставка = Перечисления.СтавкиНДС.Ставка20 Тогда. В запросе используйте ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.Ставка20) в условии ГДЕ.

Итог

Что важно запомнить

Перебор значений перечисления выполняется через коллекцию ЗначенияПеречисления метаданных, а само значение получают по имени через менеджер. В запросах используйте виртуальную таблицу Перечисление.Имя. Пустая ссылка в перебор не входит, а строковые имена требуют проверки на существование.