При работе с платформой 1С:Предприятие 8 начинающие и даже опытные разработчики часто сталкиваются с нюансами отображения и получения данных из перечислений. Казалось бы, простая задача — перебрать значения — превращается в путаницу между «Синонимом», «Именем» и «Ссылкой». В этой статье мы разберем, как устроены перечисления «под капотом», почему Сообщить() выдает не то, что мы видим в конфигураторе, и как правильно получать программные идентификаторы значений.
Для начала проанализируем ситуацию: у нас есть перечисление ВременаГода с элементами Зима, Лето, Осень, Весна. В синонимах указано, например, «Зима (синоним)». Рассмотрим три способа обращения к ним, которые часто вызывают вопросы.
Способ №1: Использование менеджера перечисления
Когда мы пишем Перечисления.ВременаГода, мы обращаемся к объекту типа ПеречислениеМенеджер. Цикл Для каждого по менеджеру перечисления возвращает объекты типа ПеречислениеСсылка.
ВременаГода = Перечисления.ВременаГода;
Для каждого ВремяГода из ВременаГода Цикл
Сообщить(ВремяГода); // Выведет Синоним
КонецЦикла;
Почему Сообщить() выводит синоним? В 1С для ссылочных типов (справочники, документы, перечисления) функция Сообщить() автоматически вызывает строковое представление объекта. Для перечислений представлением по умолчанию всегда является его Синоним. Если мы хотим увидеть в отладчике тип, он будет отображен как ПеречислениеСсылка.ВременаГода, но программно получить эту строку простым преобразованием нельзя.
Способ №2: Прямое обращение к метаданным
Здесь мы работаем не с данными базы, а с описанием конфигурации.
ВременаГодаМета = Метаданные.Перечисления.ВременаГода;
Для каждого ЗначениеМета из ВременаГодаМета.ЗначенияПеречисления Цикл
Сообщить(ЗначениеМета.Имя); // Выведет "Зима"
Сообщить(ЗначениеМета.Синоним); // Выведет "Зима (синоним)"
КонецЦикла;
В данном случае итератор ЗначениеМета имеет тип ОбъектМетаданных: Значение перечисления. У этого объекта есть явные свойства Имя (идентификатор в конфигураторе) и Синоним. Это надежный, но ресурсоемкий способ, так как обращение к метаданным «тяжелее» для системы, чем работа со ссылками.
Часто разработчику нужно получить именно «Имя» (например, "Зима"), имея на руках только ссылку. Разберем самый эффективный способ, который позволяет избежать медленного обращения к метаданным.
Для получения строкового идентификатора значения перечисления идеально подходит функция XMLСтрока(). Она возвращает именно внутреннее имя значения, которое задано в поле «Имя» в конфигураторе.
Для каждого ВремяГода из Перечисления.ВременаГода Цикл
ИмяЗначения = XMLСтрока(ВремяГода);
Сообщить("Программное имя: " + ИмяЗначения); // Выведет "Зима"
КонецЦикла;
Этот метод работает значительно быстрее, чем поиск по индексу в коллекции метаданных, и является «золотым стандартом», когда нужно, например, сохранить значение перечисления в текстовый файл или передать через API.
Проанализируем вопрос о том, как получить тип данных итератора, чтобы он выглядел как в отладчике (например, ПеречислениеСсылка.ВременаГода). В языке 1С функция ТипЗнч() возвращает объект типа Тип.
ТипОбъекта = ТипЗнч(ВремяГода);
Сообщить(ТипОбъекта); // Выведет "Времена года" (локализованное представление типа)
Важно понимать разницу между представлением и именем. Платформа скрывает детали реализации объектной модели, поэтому прямой функции «Дай мне имя типа как в конфигураторе» для переменной не существует. Чтобы получить строковое название типа, обычно используют функцию Метаданные.НайтиПоТипу(ТипЗнч(ВашаПеременная)).ПолноеИмя().
Выясним причину, по которой возникают ошибки при попытке обращения к свойствам. Рассмотрим подробнее объектную модель:
Перечисления.Имя) — это «инструментальный ящик» для управления всем набором значений. Он позволяет получить ссылку по индексу или имени.ПеречислениеСсылка.Имя) — это конкретное выбранное значение (например, «Лето»). У ссылки в 1С нет свойств Имя или Синоним, доступных через точку. Именно поэтому код ВремяГода.Имя в первом способе выдаст ошибку.Для перехода от метаданных к значению (ссылке) можно использовать индекс, так как порядок в коллекции метаданных и в менеджере совпадает:
Индекс = 0;
ИмяЗначения = Метаданные.Перечисления.ВременаГода.ЗначенияПеречисления[Индекс].Имя;
СсылкаНаЗначение = Перечисления.ВременаГода[ИмяЗначения];
При проектировании перечислений в своих конфигурациях рекомендуем придерживаться стандартов разработки 1С:
СтатусыЗаказов), если это набор состояний.ВидыДоговоров).С точки зрения производительности, обход коллекции через Перечисления.Имя является наиболее легким. Обращение к Метаданные стоит оставить для задач построения универсальных интерфейсов, где нужно программно анализировать структуру конфигурации (например, выводить комментарии к значениям, которые недоступны через ссылку).
Подводя итог: если вам нужно просто вывести список значений для пользователя — используйте цикл по Перечисления. Если нужно получить внутреннее имя для программной логики — используйте XMLСтрока(). А если требуется полная информация об объекте (комментарии, дополнительные свойства метаданных) — обращайтесь к коллекции Метаданные.