В работе с конфигурациями 1С часто возникает необходимость получить не просто пользовательское представление значений перечислений (их синонимы), но и их внутренние, программные имена. Эти имена используются в коде для однозначной идентификации значений и являются ключевыми при работе с метаданными. Рассмотрим, как мы можем получить полный список программных имен и синонимов всех значений конкретного перечисления.
Для решения этой задачи нам потребуется обратиться к коллекции метаданных конфигурации. Все перечисления и их значения хранятся в глобальном объекте Метаданные, который предоставляет доступ ко всем объектам и структурам конфигурации. Мы можем итерировать по коллекции ЗначенияПеречисления конкретного перечисления, чтобы получить доступ к каждому значению.
Метаданные, который является точкой входа для работы с метаданными конфигурации.Перечисления.Метаданные.Перечисления.ГруппыОС.Метаданные.Перечисления есть свойство ЗначенияПеречисления. Это свойство представляет собой коллекцию всех значений, которые были определены для данного перечисления в конфигураторе.Для Каждого ... Цикл, мы получаем объект, представляющий каждое отдельное значение перечисления. У этого объекта есть два ключевых свойства, которые нас интересуют:
Имя: Это программное имя значения перечисления, которое является уникальным идентификатором и используется в коде 1С.Синоним: Это пользовательское представление значения, которое отображается в интерфейсе 1С и может быть переведено на разные языки.Давайте рассмотрим пример кода, который демонстрирует этот подход в Консоли запросов или в любом серверном или клиентском модуле:
// Предположим, нам нужно получить значения перечисления "ГруппыОС".
// Замените "ГруппыОС" на имя вашего перечисления, как оно указано в конфигураторе.
// Например, это может быть "ВидыНоменклатуры", "СостоянияЗаказов" и т.д.
//
// Создадим временную таблицу, чтобы собрать результаты, если нам нужно будет их использовать дальше,
// а не просто вывести в сообщения.
ТаблицаЗначенийПеречисления = Новый ТаблицаЗначений;
ТаблицаЗначенийПеречисления.Колонки.Добавить("ПрограммноеИмя", Новый ОписаниеТипов("Строка"));
ТаблицаЗначенийПеречисления.Колонки.Добавить("СинонимЗначения", Новый ОписаниеТипов("Строка"));
// Выполняем итерацию по коллекции значений перечисления
Для Каждого ЭлементИз Метаданные.Перечисления.ГруппыОС.ЗначенияПеречисления Цикл
// Добавляем новую строку в таблицу
НоваяСтрока = ТаблицаЗначенийПеречисления.Добавить();
НоваяСтрока.ПрограммноеИмя = Элемент.Имя;
НоваяСтрока.СинонимЗначения = Элемент.Синоним;
// Выводим информацию в окно сообщений для наглядности
Сообщить("Имя: " + Элемент.Имя + ", Синоним: " + Элемент.Синоним);
КонецЦикла;
// Теперь ТаблицаЗначенийПеречисления содержит полный список программных имен и синонимов.
// Мы можем, например, показать ее пользователю или выгрузить в файл.
// Сообщить("Всего значений найдено: " + ТаблицаЗначенийПеречисления.Количество());
В результате выполнения этого кода в окно сообщений будут выведены пары "Имя - Синоним" для каждого значения перечисления, а также собранные данные будут доступны в переменной ТаблицаЗначенийПеречисления. Этот способ является наиболее прямым и универсальным для получения нужной информации.
Нередко в коде мы уже имеем дело со ссылкой на конкретное значение перечисления (например, это значение реквизита документа или справочника, имеющего тип ПеречислениеСсылка.ИмяПеречисления). В такой ситуации нам может потребоваться получить его программное имя. Для этого мы можем воспользоваться следующим алгоритмом:
Метаданные() от ссылки на значение перечисления. Например: МояСсылкаНаПеречисление.Метаданные().Индекс(), мы определим порядковый номер (индекс) нужного нам значения в коллекции ЗначенияПеречисления. Например: ИндексЗначения = МояСсылкаНаПеречисление.Метаданные().Индекс(МояСсылкаНаПеречисление). Этот метод принимает саму ссылку на значение перечисления и возвращает ее позицию.ЗначенияПеречисления объекта метаданных и получить свойство Имя по этому индексу. Например: ПрограммноеИмя = МояСсылкаНаПеречисление.Метаданные().ЗначенияПеречисления[ИндексЗначения].Имя.Этот подход позволяет динамически получать программные имена, когда у нас есть только ссылка на значение перечисления.
// Предположим, у нас есть ссылка на значение перечисления,
// например, Перечисления.ГруппыОС.ОсновныеСредства.
// Или это может быть значение из реквизита объекта: МойДокумент.ГруппаОС.
СсылкаНаЗначение = Перечисления.ГруппыОС.ОсновныеСредства; // Для примера
// 1. Получаем объект метаданных перечисления
МетаданныеПеречисления = СсылкаНаЗначение.Метаданные();
// 2. Получаем индекс значения в коллекции ЗначенияПеречисления
ИндексЗначения = МетаданныеПеречисления.Индекс(СсылкаНаЗначение);
// 3. Получаем программное имя по индексу
Если ИндексЗначения <> Неопределено Тогда
ПрограммноеИмя = МетаданныеПеречисления.ЗначенияПеречисления[ИндексЗначения].Имя;
Сообщить("Программное имя значения '" + СсылкаНаЗначение + "': " + ПрограммноеИмя);
Иначе
Сообщить("Не удалось определить индекс значения.");
КонецЕсли;
Во многих современных конфигурациях 1С, таких как 1С:ERP, 1С:Бухгалтерия 3.0, 1С:Управление торговлей 11 и других, используется Библиотека стандартных подсистем (БСП). В БСП предусмотрена удобная стандартизированная функция для получения строкового имени значения перечисления по его ссылке. Эта функция называется ИмяЗначенияПеречисления и находится в общем модуле ОбщегоНазначения.
Использование этой функции из БСП является предпочтительным, если ваша конфигурация её содержит, поскольку это стандартизированный и оптимизированный подход, который уже протестирован и поддерживается разработчиками 1С.
// Предположим, у нас есть ссылка на значение перечисления.
// Например: ТекущееСостояние = Перечисления.СостоянияДокументов.Проведен;
// Или получаем из реквизита объекта: ТекущееСостояние = МойДокумент.Состояние;
СсылкаНаЗначение = Перечисления.ГруппыОС.Земля; // Для примера
// Проверяем наличие модуля ОбщегоНазначения и функции ИмяЗначенияПеречисления
// Это важно, так как не во всех конфигурациях может быть БСП или эта функция.
Если ОбщегоНазначения.ОбщийМодульСуществует("ОбщегоНазначения") И ОбщегоНазначения.ФункцияСуществует("ИмяЗначенияПеречисления") Тогда
ПрограммноеИмяБСП = ОбщегоНазначения.ИмяЗначенияПеречисления(СсылкаНаЗначение);
Сообщить("Программное имя через БСП для '" + СсылкаНаЗначение + "': " + ПрограммноеИмяБСП);
Иначе
Сообщить("Модуль ОбщегоНазначения или функция ИмяЗначенияПеречисления не найдены.");
Сообщить("В этом случае используйте прямой доступ к метаданным, как показано выше.");
КонецЕсли;
Помимо получения имен и синонимов, существуют и другие полезные сценарии работы с перечислениями, которые могут пригодиться в разработке.
После того как мы получили коллекцию имен и синонимов значений перечисления, как было описано в основном способе, мы можем поместить эти данные в объект ТаблицаЗначений. Затем ТаблицуЗначений можно легко выгрузить в различные форматы, например, CSV или Excel, для использования вне системы 1С или для дальнейшей обработки.
ТаблицаЗначенийПеречисления = Новый ТаблицаЗначений;
ТаблицаЗначенийПеречисления.Колонки.Добавить("ПрограммноеИмя", Новый ОписаниеТипов("Строка"));
ТаблицаЗначенийПеречисления.Колонки.Добавить("СинонимЗначения", Новый ОписаниеТипов("Строка"));
Для Каждого ЭлементИз Метаданные.Перечисления.ГруппыОС.ЗначенияПеречисления Цикл
НоваяСтрока = ТаблицаЗначенийПеречисления.Добавить();
НоваяСтрока.ПрограммноеИмя = Элемент.Имя;
НоваяСтрока.СинонимЗначения = Элемент.Синоним;
КонецЦикла;
// Теперь ТаблицаЗначенийПеречисления содержит все данные.
// Мы можем использовать ее для вывода в отчет, сохранения в файл и т.д.
// Например, для вывода в табличный документ:
// ТабДокумент = Новый ТабличныйДокумент;
// ТаблицаЗначенийПеречисления.Вывести(ТабДокумент);
// ТабДокумент.Показать();
//
// Для сохранения в CSV:
// ТаблицаЗначенийПеречисления.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.CSV);
Иногда возникает обратная задача: получить ссылку на значение перечисления, зная только его строковое имя или синоним. Это можно сделать, перебирая коллекцию ЗначенияПеречисления и сравнивая свойства Имя или Синоним с искомой строкой.
Функция ПолучитьЗначениеПеречисленияПоИмени(ИмяПеречисленияМетаданных, ИскомоеИмя)
// Проверяем существование перечисления с таким именем
МетаданныеПеречисления = Метаданные.Перечисления[ИмяПеречисленияМетаданных];
Если МетаданныеПеречисления = Неопределено Тогда
Сообщить("Перечисление '" + ИмяПеречисленияМетаданных + "' не найдено.");
Возврат Неопределено;
КонецЕсли;
// Перебираем все значения перечисления
Для Каждого ЭлементИз МетаданныеПеречисления.ЗначенияПеречисления Цикл
Если Элемент.Имя = ИскомоеИмя Тогда
// Если нашли по имени, возвращаем ссылку на это значение
// Мы используем синтаксис Перечисления.<ИмяПеречисленияМетаданных>.<ИмяЗначения>
Возврат Перечисления[ИмяПеречисленияМетаданных][ИскомоеИмя];
КонецЕсли;
КонецЦикла;
Сообщить("Значение с именем '" + ИскомоеИмя + "' не найдено в перечислении '" + ИмяПеречисленияМетаданных + "'.");
Возврат Неопределено;
КонецФункции
// Пример использования функции
// Попытаемся получить ссылку на значение "ОсновныеСредства" из перечисления "ГруппыОС"
ЗначениеПоИмени = ПолучитьЗначениеПеречисленияПоИмени("ГруппыОС", "ОсновныеСредства");
Если ЗначениеПоИмени <> Неопределено Тогда
Сообщить("Найдено значение по имени: " + ЗначениеПоИмени);
КонецЕсли;
Функция ПолучитьЗначениеПеречисленияПоСинониму(ИмяПеречисленияМетаданных, ИскомыйСиноним)
МетаданныеПеречисления = Метаданные.Перечисления[ИмяПеречисленияМетаданных];
Если МетаданныеПеречисления = Неопределено Тогда
Сообщить("Перечисление '" + ИмяПеречисленияМетаданных + "' не найдено.");
Возврат Неопределено;
КонецЕсли;
Для Каждого ЭлементИз МетаданныеПеречисления.ЗначенияПеречисления Цикл
Если Элемент.Синоним = ИскомыйСиноним Тогда
// Если нашли по синониму, возвращаем ссылку на это значение
Возврат Перечисления[ИмяПеречисленияМетаданных][Элемент.Имя];
КонецЕсли;
КонецЦикла;
Сообщить("Значение с синонимом '" + ИскомыйСиноним + "' не найдено в перечислении '" + ИмяПеречисленияМетаданных + "'.");
Возврат Неопределено;
КонецФункции
// Пример использования функции для поиска по синониму
// ЗначениеПоСинониму = ПолучитьЗначениеПеречисленияПоСинониму("ГруппыОС", "Земля");
// Если ЗначениеПоСинониму <> Неопределено Тогда
// Сообщить("Найдено значение по синониму: " + ЗначениеПоСинониму);
// КонецЕсли;
В некоторых случаях может быть полезно программно открывать формы списка или выбора значений перечисления для интерактивного взаимодействия с пользователем. Это достигается через методы менеджера перечисления, такие как Выбрать(), ПолучитьФормуСписка() или ПолучитьФормуВыбора().
// Открытие формы выбора значений перечисления "ГруппыОС"
// Функция Выбрать() возвращает выбранное пользователем значение или Неопределено, если выбор отменен.
ВыбранноеЗначение = Перечисления.ГруппыОС.Выбрать("Выберите группу ОС");
Если ВыбранноеЗначение <> Неопределено Тогда
Сообщить("Пользователь выбрал: " + ВыбранноеЗначение + " (Имя: " + ВыбранноеЗначение.Метаданные().Имя + ")");
Иначе
Сообщить("Выбор отменен.");
КонецЕсли;
// Открытие формы списка значений перечисления (если такая форма определена)
// Этот подход используется, когда для перечисления есть своя форма списка.
// Обычно для перечислений используются формы выбора, а не списка, но возможность есть.
Попытка
ФормаСписка = Перечисления.ГруппыОС.ПолучитьФормуСписка();
Если ФормаСписка <> Неопределено Тогда
ФормаСписка.Открыть();
Сообщить("Форма списка перечисления 'ГруппыОС' открыта.");
Иначе
Сообщить("Форма списка для перечисления 'ГруппыОС' не найдена.");
КонецЕсли;
Исключение
Сообщить("Ошибка при открытии формы списка: " + ОписаниеОшибки());
КонецПопытки;
Необходимо помнить, что перечисления в 1С являются частью метаданных конфигурации, а не обычными данными, которые хранятся в таблицах базы данных. Это означает несколько важных моментов, которые мы должны учитывать при работе с ними:
Вы не сможете "скопировать" или "перенести" значения перечисления между конфигурациями так же, как записи справочника или документа с помощью стандартных механизмов обмена данными (например, XML-обмен). Если требуется перенести набор значений перечисления в другую конфигурацию, их необходимо создавать в конфигураторе вручную в целевой конфигурации или программно генерировать код на основе полученных имен, чтобы затем выполнить его в режиме "Предприятия" или в конфигураторе.
Любые изменения в составе значений перечисления (добавление новых значений, удаление существующих, изменение их программных имен или синонимов) требуют сохранения конфигурации и последующего обновления конфигурации базы данных. Эти изменения являются частью структуры программы и влияют на целостность данных, поэтому не могут быть выполнены в режиме "Предприятия" без остановки работы пользователей. Если конфигурацию необходимо обновить в нескольких базах, эту задачу можно выполнять регулярно по расписанию через программу для пакетного обновления баз 1С без личного участия администратора.
Понимание этих фундаментальных принципов работы с перечислениями помогает эффективно использовать их в разработке и избегать распространенных ошибок. Используя описанные подходы, мы можем уверенно работать с перечислениями, получая необходимые программные имена и синонимы для различных задач.