Как преобразовать SQL Binary данные (IDRRef) в ссылку 1С:Предприятие?

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

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

Почему формат SQL отличается от 1С?

Для начала проанализируем ситуацию: почему нельзя просто скопировать строку из SQL и вставить её в 1С? Дело в оптимизации. Платформа 1С:Предприятие использует специфический порядок байтов при хранении идентификаторов в MS SQL Server. Это сделано для того, чтобы наиболее часто меняющиеся части GUID находились в конце значения. Для SQL Server это означает более эффективное построение индексов и уменьшение фрагментации таблиц.

Стандартный GUID выглядит как AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP. Однако в поле _IDRRef SQL-таблицы он превращается в 0xIIJJKKLLMMNNOOPPEEFFGGDDAABBCCDD. Как мы видим, блоки байтов меняются местами по определенному алгоритму.

Алгоритм ручной конвертации в коде 1С

Рассмотрим пример кода, который позволяет преобразовать шестнадцатеричную строку из SQL в понятный платформе УникальныйИдентификатор. Если у вас есть строка вида 0x87CBD485614D5F2411E68BCCE80213E6, мы можем применить следующий метод:


// Предположим, входная строка получена из SQL
IDRref = "0x87CBD485614D5F2411E68BCCE80213E6";

// Убираем префикс 0x, если он есть
ЧистаяСтрока = Сред(IDRref, 3); 

// Выполняем перестановку байтов по схеме 1С
// Последние 8 символов (4 байта) + блок 21-24 + блок 17-20 + первые 16 символов
РезультатGUID = НРег(Строка(Прав(ЧистаяСтрока, 8) + "-" + 
                Сред(ЧистаяСтрока, 21, 4) + "-" + 
                Сред(ЧистаяСтрока, 17, 4) + "-" + 
                Лев(ЧистаяСтрока, 4) + "-" + 
                Сред(ЧистаяСтрока, 5, 12)));

УИД = Новый УникальныйИдентификатор(РезультатGUID);

Разберем, что происходит в этом коде. Мы разбиваем исходную бинарную строку на сегменты и пересобираем их в канонический вид GUID, который ожидает конструктор Новый УникальныйИдентификатор(). Важно помнить, что этот метод работает, если вы точно знаете, к какому типу метаданных относится данная запись.

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

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


ИмяМетаданных = "Справочник.Номенклатура";
ТекУИД = Новый УникальныйИдентификатор(РезультатGUID);

// Получаем ссылку через менеджер
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(ТекУИД);

// Проверяем, существует ли объект в базе
Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
    Сообщить("Объект с таким идентификатором не найден в БД");
КонецЕсли;

Важный момент: метод ПолучитьСсылку() не делает запрос к базе данных. Он просто создает ссылку «в памяти». Чтобы убедиться, что запись реально существует, необходимо попытаться прочитать объект или выполнить запрос к этой ссылке.

Использование инструментов разработчика (ИР)

Если вам нужно выполнять такие преобразования часто, проанализируем возможности расширения «Инструменты разработчика». В составе этого комплекса есть «Редактор объекта БД», который позволяет вставить HEX-значение напрямую.

  1. Откройте инструмент «Редактор объекта БД».
  2. Выберите нужный тип метаданных (например, Документ.РеализацияТоваровУслуг).
  3. В поле поиска или идентификатора вставьте ваше значение 0x....
  4. Инструмент автоматически выполнит перестановку байтов и найдет соответствующую запись в интерфейсе 1С.

Конвертация на стороне SQL Server (T-SQL)

Иногда удобнее сразу получить читаемый GUID прямо в консоли запросов SQL (SSMS). Для этого мы можем написать запрос, который переставит байты на лету с помощью функции SUBSTRING. Посмотрим на пример:


SELECT 
    CAST(
        CAST(SUBSTRING(_IDRRef, 13, 4) AS VARBINARY(4)) + 
        CAST(SUBSTRING(_IDRRef, 11, 2) AS VARBINARY(2)) + 
        CAST(SUBSTRING(_IDRRef, 9, 2) AS VARBINARY(2)) + 
        CAST(SUBSTRING(_IDRRef, 1, 8) AS VARBINARY(8)) 
    AS UNIQUEIDENTIFIER) AS GUID_1C
FROM _Reference15 -- Здесь имя вашей таблицы в SQL

В данном запросе мы принудительно пересобираем бинарное значение _IDRRef так, чтобы приведение к типу UNIQUEIDENTIFIER выдало результат, полностью совпадающий с тем, что мы видим в 1С. Это крайне полезно при отладке сложных интеграций или восстановлении данных.

Что делать, если тип объекта неизвестен (поле TRef)?

Рассмотрим более сложную ситуацию, когда у нас есть только бинарный идентификатор, но мы не знаем, к какой таблице он относится. В системных таблицах 1С (например, в регистрах сведений с типом «ЛюбаяСсылка») рядом с полем _RRRef (идентификатор) обычно присутствует поле _RTRef (идентификатор типа).

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


СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
// В этой структуре можно найти соответствие имен таблиц SQL и метаданных 1С

Таким образом, для полной идентификации ссылки из «сырых» данных SQL нам нужно два компонента: _RTRef для определения таблицы (типа объекта) и _IDRRef для поиска конкретной строки в этой таблице.

Обратная задача: из 1С в SQL HEX

В завершение разберем обратный процесс. Если нам нужно найти конкретную ссылку в SQL-запросе, мы должны перевести GUID обратно в HEX. Посмотрим на алгоритм:


Ссылка = Справочники.Номенклатура.НайтиПоНаименованию("Товар");
УИД = Ссылка.УникальныйИдентификатор();
СтрокаGUID = СтрЗаменить(Строка(УИД), "-", "");

// Собираем HEX для SQL
HEX_SQL = Сред(СтрокаGUID, 25, 8) + 
          Сред(СтрокаGUID, 21, 4) + 
          Сред(СтрокаGUID, 17, 4) + 
          Лев(СтрокаGUID, 16);

Сообщить("В SQL искать как: 0x" + ВРег(HEX_SQL));

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

← На главную