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

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

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

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

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

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

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

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

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

Обращение к конкретному значению выполняется через точку: Перечисления.ВидыОпераций.Продажа. Через квадратные скобки можно обратиться по строковому имени: Перечисления.ВидыОпераций["Продажа"]. Именно второй вариант используется при переборе, потому что имена значений известны только в момент выполнения цикла.

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

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

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

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ВидыОпераций.ЗначенияПеречисления Цикл

ИмяЗначения = ЗначениеМетаданных.Имя;

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

ЗначениеПеречисления = Перечисления.ВидыОпераций[ИмяЗначения];

Сообщить(ИмяЗначения + " — " + СинонимЗначения);

КонецЦикла;

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

Порядок перебора соответствует порядку значений в конфигураторе. Если бизнес-логика зависит от порядка, не полагайтесь на него без необходимости: при рефакторинге конфигурации порядок могут изменить, и код начнёт работать иначе без явной ошибки.

1c
Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ВидыОпераций.ЗначенияПеречисления Цикл
    Значение = Перечисления.ВидыОпераций[ЗначениеМетаданных.Имя];
КонецЦикла;

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

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

МенеджерПеречисления = Перечисления.ВидыОпераций;

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ВидыОпераций.ЗначенияПеречисления Цикл

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

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

КонецЦикла;

Полезные свойства менеджера: ПустаяСсылка() возвращает пустое значение перечисления для сравнения, а обращение по несуществующему имени возвращает Неопределено, что удобно для проверки корректности строки-имени. Это позволяет безопасно преобразовывать строковые данные (например, из файла обмена) в значения перечисления.

ИмяИзФайла = "Продажа";

Значение = Перечисления.ВидыОпераций[ИмяИзФайла];

Если Значение = Неопределено Тогда

Сообщить("Значение """ + ИмяИзФайла + """ не найдено в перечислении");

КонецЕсли;

Заполнение списка выбора на форме

Типовая задача — дать пользователю выбор из значений перечисления в поле ввода или в отборе динамического списка. Для этого значения перебираются и добавляются в СписокЗначений.

СписокВыбора = Новый СписокЗначений;

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ВидыОпераций.ЗначенияПеречисления Цикл

СписокВыбора.Добавить(

Перечисления.ВидыОпераций[ЗначениеМетаданных.Имя],

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

КонецЦикла;

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

На управляемой форме такой список присваивается свойству СписокВыбора элемента формы либо используется в параметрах отбора. Учтите, что для поля, связанного с реквизитом типа «перечисление», платформа сама формирует список выбора — ручное заполнение нужно только для дополнительных полей, отборов и нетиповых интерфейсов.

Порядок действий при заполнении списка выбора
  1. 1
    Создайте объект СписокЗначений
  2. 2
    В цикле переберите Метаданные.Перечисления.Имя.ЗначенияПеречисления
  3. 3
    Получите значение по имени через менеджер перечисления
  4. 4
    Добавьте значение и синоним в список методом Добавить
  5. 5
    Присвойте список свойству СписокВыбора элемента формы
  6. 6
    Проверьте на форме, что все значения отображаются с читаемыми представлениями

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

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

Если нужно сопоставить данные со всеми значениями перечисления (например, построить отчёт, где каждое значение — строка, даже если данных по нему нет), применяют два подхода. Первый — сформировать временную таблицу значений в коде перебором и передать её в запрос параметром. Второй — перечислить нужные значения оператором В (...) или объединить через ОБЪЕДИНИТЬ ВСЕ.

ТаблицаЗначений = Новый ТаблицаЗначений;

ТаблицаЗначений.Колонки.Добавить("ВидОперации",

Новый ОписаниеТипов("ПеречислениеСсылка.ВидыОпераций"));

Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ВидыОпераций.ЗначенияПеречисления Цикл

Строка = ТаблицаЗначений.Добавить();

Строка.ВидОперации = Перечисления.ВидыОпераций[ЗначениеМетаданных.Имя];

КонецЦикла;

Запрос.УстановитьПараметр("ТаблицаВидов", ТаблицаЗначений);

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

Как проверить тип и принадлежность значения

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

Если ТипЗнч(Значение) = Тип("ПеречислениеСсылка.ВидыОпераций") Тогда

// значение принадлежит нужному перечислению

КонецЕсли;

Обратная задача — по значению узнать имя перечисления и имя самого значения. Для этого через метод Метаданные() значения получают объект метаданных, а индекс значения находят через менеджер:

МетаданныеЗначения = Значение.Метаданные();

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

ИндексЗначения = Перечисления[ИмяПеречисления].Индекс(Значение);

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

.ЗначенияПеречисления[ИндексЗначения].Имя;

Этот приём незаменим при сериализации данных в XML или JSON: в файле обмена значение перечисления корректно хранить по имени, а не по представлению, потому что синоним могут переформулировать, а имя остаётся стабильным идентификатором.

Сравнение способов перебора

Через метаданные

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

Через менеджер по имени

Быстрое получение значения по строке, безопасная проверка через Неопределено. Нужен для обмена данными, но сам по себе не перебирает коллекцию.

Через индекс значения

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

Типичные ошибки и ограничения

Самая распространённая ошибка — попытка использовать объект метаданных как значение перечисления. Выражение Реквизит = ЗначениеМетаданных внутри цикла приводит к ошибке присвоения типов, потому что элемент коллекции ЗначенияПеречисления — это описание значения, а не само значение.

Вторая частая проблема — обращение к перечислению по имени, которого нет в конфигурации, например после переименования. Код Перечисления.СтароеИмя вызовет исключение ещё при компиляции модуля, а вот Перечисления[СтроковаяПеременная] — только в момент выполнения. После рефакторинга проверяйте все места, где имена перечислений заданы строками.

Третья группа ошибок связана с контекстом выполнения. В клиентском коде управляемого приложения обращение к Перечисления и Метаданные доступно, но тяжёлые переборы лучше выполнять на сервере, особенно в тонком и веб-клиенте. Также помните, что перечисления недоступны для редактирования пользователем: если бизнес требует расширяемый список, вместо перечисления нужен справочник.

Типичные ошибки
01
Присвоение объекта метаданных в реквизит типа перечисление — ошибка несоответствия типов; значение нужно получать по имени через менеджер
02
Использование синонима как идентификатора при обмене — после переименования синонима обмен ломается; используйте имя значения
03
Отсутствие проверки на Неопределено при обращении по строке — пустые реквизиты и скрытые дефекты данных
04
Зависимость логики от порядка значений в конфигураторе — рефакторинг молча меняет поведение кода
05
Жёстко прописанный список значений в запросе — новые значения перечисления не попадают в отчёт

Проверка результата

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

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

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

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

Количество итераций цикла
Норма

Равно ЗначенияПеречисления.Количество()

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

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

Тип записанного значения
Норма

ТипЗнч возвращает ПеречислениеСсылка.Имя

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

Записана строка или Неопределено

Представления в списке выбора
Норма

Отображаются синонимы из конфигурации

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

Пустые подписи или технические имена

Итог

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

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

Частые вопросы

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

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

Как получить представление значения перечисления строкой?

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

Чем отличается имя значения от синонима?

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

Почему Перечисления.Имя["НесуществующееЗначение"] не выдаёт ошибку?

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

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

Напрямую нет: в языке запросов нет таблицы со значениями перечисления. Либо перечислите значения явно через ЗНАЧЕНИЕ(...) и ОБЪЕДИНИТЬ, либо сформируйте таблицу значений перебором в коде и передайте её параметром.

Работает ли перебор на тонком клиенте?

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