Как получить значение перечисления в 1С по его синониму или текстовому названию

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разберем проблему, с которой часто сталкиваются разработчики при интеграции 1С с внешними системами (веб-сайтами, маркетплейсами или сторонними сервисами). При загрузке данных сторонний сервис может передавать не системное имя значения перечисления, а его пользовательское представление или синоним (например, «Оплачено» вместо системного имени ОплаченоНаличкой).

Выясним причину ошибки «Поле объекта не обнаружено»

При попытке получить значение перечисления с помощью синонима в конструкции:

ДокументОбъект.Статус = Перечисления.СтатусыОплаты[стр.Статус];

возникает ошибка «Поле объекта не обнаружено».

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

Способ 1. Использование объекта Соответствие для сопоставления

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

Посмотрим на пример реализации:


// Создаем соответствие синонимов и системных имен
КартаСтатусов = Новый Соответствие;
КартаСтатусов.Вставить("Оплачено", "ОплаченоНаличкой");
КартаСтатусов.Вставить("Отменено", "Отменен");

ИмяЗначения = КартаСтатусов[стр.Статус];

Если ИмяЗначения <> Неопределено Тогда
    ДокументОбъект.Статус = Перечисления.СтатусыОплаты[ИмяЗначения];
Иначе
    // Обработка ситуации, когда получен неизвестный статус
    ЗаписьЖурналаРегистрации("Загрузка с сайта", УровеньЖурналаРегистрации.Предупреждение, , , "Неизвестный статус: " + стр.Статус);
КонецЕсли;

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

Способ 2. Программный обход метаданных перечисления

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

С помощью коллекции Метаданные.Перечисления.<ИмяПеречисления>.ЗначенияПеречисления проанализируем синонимы и имена всех элементов:


ИскомоеЗначение = Неопределено;
ВходнаяСтрока = СокрЛП(стр.Статус);

Для Каждого ЭлементМетаданных Из Метаданные.Перечисления.СтатусыОплаты.ЗначенияПеречисления Цикл
    Если ЭлементМетаданных.Синоним = ВходнаяСтрока Или ЭлементМетаданных.Имя = ВходнаяСтрока Тогда
        ИскомоеЗначение = Перечисления.СтатусыОплаты[ЭлементМетаданных.Имя];
        Прервать;
    КонецЕсли;
КонецЦикла;

Если ЗначениеЗаполнено(ИскомоеЗначение) Тогда
    ДокументОбъект.Статус = ИскомоеЗначение;
КонецЕсли;

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

Способ 3. Использование регистра сведений для гибкой настройки сопоставления

Если синонимы на стороннем сайте меняются без участия программиста 1С, оптимальным архитектурным решением будет вынести сопоставление в интерфейс пользователя.

Для этого выполним следующие шаги:

  1. Создадим регистр сведений (например, СопоставлениеСтатусовСайта).
  2. Добавим измерение ТекстСайта (тип Строка) и ресурс ЗначениеСтатуса (тип ПеречислениеСсылка.СтатусыОплаты).
  3. Пользователь или администратор сможет самостоятельно связывать строковые обозначения с сайта со значениями перечислений 1С через форму регистра.

Реализация получения значения из регистра сведений через запрос:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Сопоставление.ЗначениеСтатуса КАК Статус
    |ИЗ
    |	РегистрСведений.СопоставлениеСтатусовСайта КАК Сопоставление
    |ГДЕ
    |	Сопоставление.ТекстСайта = &ТекстСайта";

Запрос.УстановитьПараметр("ТекстСайта", СокрЛП(стр.Статус));
РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    ДокументОбъект.Статус = Выборка.Статус;
КонецЕсли;

Ограничения и особенности платформы

При работе со значениями перечислений следует учитывать ряд технических особенностей платформы 1С:

  1. Неуникальность синонимов: платформа 1С не контролирует уникальность синонимов значений перечисления. Разным значениям одного и того же перечисления в конфигураторе может быть задан одинаковый синоним, что приведет к неоднозначности при поиске по строке.
  2. Зависимость от языка сеанса: синонимы могут отличаться в зависимости от языка интерфейса пользователя, под которым запущен сеанс 1С.
  3. Прямой перебор менеджера: объект Перечисления.СтатусыОплаты не поддерживает прямой обход конструкцией Для Каждого. Перебор элементов возможен только через объективную модель метаданных.

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

← На главную