Как получить _IDRREF и Уникальный Идентификатор значения перечисления в 1С

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

При интеграции 1С:Предприятия со сторонними информационными системами (веб-сайтами, мобильными приложениями, внешними базами данных или BI-системами) разработчики часто сталкиваются с необходимостью сопоставления данных. Особый интерес вызывают перечисления. Физически в таблицах СУБД ссылки на перечисления хранятся в виде бинарных данных — 16-байтовых идентификаторов (_IDRRef). В этой статье мы подробно разберем, как устроены перечисления «под капотом» базы данных, и рассмотрим все практические способы получения их уникальных идентификаторов.

Физическое устройство перечислений в СУБД (MS SQL, PostgreSQL и др.)

Среди начинающих разработчиков существует популярное заблуждение, будто значения перечислений не имеют физических ссылок в СУБД и не являются полноценными объектами базы данных. Это не так. На уровне СУБД для каждого объекта конфигурации типа «Перечисление» создается отдельная полноценная таблица.

Имя таблицы перечисления имеет формат _Enum<n>, где <n> — это порядковый номер объекта в метаданных конфигурации. Каждая такая таблица состоит всего из двух колонок:

  1. _IDRRef — поле типа binary(16), содержащее уникальный двоичный идентификатор конкретного значения перечисления (его UUID).
  2. _EnumOrder — числовое поле, определяющее индекс порядка значения перечисления, заданный в конфигураторе (индексация начинается с 0).

Когда в справочнике или документе присутствует реквизит с типом «ПеречислениеСсылка», в соответствующей таблице СУБД создается поле _Fld<x>RRef (для простых типов) или набор полей (для составных типов), куда напрямую записывается значение _IDRRef из таблицы перечисления. Таким образом, сопоставление по уникальному идентификатору абсолютно надежно и гарантирует 100% точность.

Способ 1. Использование встроенного метода УникальныйИдентификатор()

Самый простой и очевидный способ получить UUID значения перечисления в коде 1С — вызвать стандартный метод УникальныйИдентификатор(). Вопреки старым мифам, значения перечислений являются ссылочным типом данных (ПеречислениеСсылка), поэтому у них есть этот метод.

Рассмотрим пример кода:


ВыбранноеЗначение = Перечисления.ДниНедели.Вторник;
УИД = ВыбранноеЗначение.УникальныйИдентификатор();
Сообщить("Уникальный идентификатор: " + Строка(УИД));
// Выведет стандартную строку UUID: "a73c8a1c-3d84-f454-458a-a55dfb87efd1"

Полученную строку можно напрямую передавать во внешние системы для интеграции.

Способ 2. Использование универсальной функции XMLСтрока()

Отличным и очень быстрым альтернативным решением является использование платформенного механизма сериализации XML. Функция XMLСтрока() принимает ссылку перечисления и возвращает строковое представление его UUID.

Давайте посмотрим на пример реализации:


ЗначениеПеречисления = Перечисления.ДниНедели.Понедельник;
СтрокаUUID = XMLСтрока(ЗначениеПеречисления);
// Результат будет аналогичен методу УникальныйИдентификатор()

Для выполнения обратного преобразования (когда из внешней системы приходит строковый GUID и нужно получить ссылку перечисления в 1С), мы можем использовать парную функцию XMLЗначение():


ИскомыйТип = Тип("ПеречислениеСсылка.ДниНедели");
СсылкаНаЭлемент = XMLЗначение(ИскомыйТип, "a73c8a1c-3d84-f454-458a-a55dfb87efd1");

Способ 3. Извлечение UUID из внутреннего представления ЗначениеВСтрокуВнутр()

Иногда при низкоуровневой обработке или сериализации данных программисты используют системную функцию ЗначениеВСтрокуВнутр(). При ее вызове для значения перечисления платформа генерирует строку специального формата:

{"#",de626819-9250-492e-ad27-1776ea2ee050,39:a73c8a1c3d84f454458aa55dfb87efd1}

Проанализируем структуру этой строки:

Обратите внимание, что байты в СУБД и в стандартном UUID формата RFC4122 записываются в разном порядке. Платформа 1С осуществляет побайтовую перестановку (сдвиг подстрок) при преобразовании внутренней строки в стандартный GUID. Если вам требуется сопоставить эту строку напрямую с полем _IDRRef в СУБД, вы можете использовать строковые функции для парсинга и перегруппировки байт.

Способ 4. Получение идентификатора через запрос (для современных платформ)

В современных версиях платформы 1С:Предприятие (начиная с 8.3.27) появилась возможность извлекать уникальный идентификатор прямо внутри запроса. Для этого используется функция УНИКАЛЬНЫЙИДЕНТИФИКАТОР().

Рассмотрим, как это выглядит на практике:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	УНИКАЛЬНЫЙИДЕНТИФИКАТОР(ДниНедели.Ссылка) КАК ГУИДСтрока
    |ИЗ
    |	Перечисление.ДниНедели КАК ДниНедели
    |ГДЕ
    |	ДниНедели.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Перечисления.ДниНедели.Вторник);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    Сообщить("Идентификатор из запроса: " + Выборка.ГУИДСтрока);
КонецЕсли;

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

Способ 5. Прямое сопоставление по индексу _EnumOrder через SQL

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

Разберем этот процесс по шагам:

  1. С помощью встроенного метода 1С ПолучитьСтруктуруХраненияБазыДанных() определяем имя таблицы СУБД для интересующего нас перечисления (например, _Enum123).
  2. Выполняем прямой SQL-запрос к этой таблице: SELECT _IDRRef, _EnumOrder FROM _Enum123 ORDER BY _EnumOrder
  3. В коде стороннего приложения сопоставляем полученные строки с массивом значений метаданных перечисления из 1С. Порядок записей в СУБД (колонка _EnumOrder со значениями 0, 1, 2...) всегда строго соответствует порядку элементов перечисления в конфигураторе (например, Понедельник = 0, Вторник = 1, Среда = 2 и т.д.).

Такой подход позволяет один раз кэшировать карту соответствия идентификаторов во внешнем приложении и затем мгновенно сопоставлять любые бинарные поля _IDRRef без обращения к серверу приложений 1С.

← На главную