Уникальный идентификатор ссылки в 1С 8.3: где его увидеть и как получить кодом

· 11 мин

Содержание

GUID любого справочника или документа в 1С 8.3 программист получает одной строкой кода: Строка(Ссылка.УникальныйИдентификатор()). Пользователь без конфигуратора узнает GUID через навигационную ссылку объекта: команда «Получить ссылку» в форме даёт строку вида e1cib/data/Справочник.Номенклатура?ref=…, в которой зашиты те же 16 байт, только в другом порядке.

Обычно GUID нужен в неудобный момент: обмен выгрузил дубль, интегратор прислал строку из 36 символов, а в карточке элемента её нигде не видно. Ниже шесть рабочих способов узнать GUID объекта и найти объект по GUID — от вариантов для пользователя до запроса, отладчика и обмена через XML, JSON и OData.

Что такое GUID в 1С и зачем его узнавать

GUID (в 1С — тип УникальныйИдентификатор) — 128-битное значение, которое платформа присваивает каждому объекту ссылочного типа при первой записи. В текстовом виде это 36 символов: 32 шестнадцатеричные цифры в группах 8-4-4-4-12, например 3d5e3f8a-1b2c-11e9-80d5-005056a5b1c2.

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

Три задачи, в которых без GUID не обойтись:

  • 🔄 Обмен данными. Типовые обмены и обмен через формат EnterpriseData сопоставляют объекты по GUID. Если в базе-приёмнике элемент заведён вручную, у него другой GUID, и при загрузке появляется дубль.
  • 🔌 Интеграции. Сайт, мобильное приложение, сервис доставки хранят у себя GUID товара или контрагента и по нему обращаются к базе через HTTP-сервис или OData.
  • 🛠 Разбор битых ссылок. Когда в документе висит <Объект не найден>, по GUID и номеру таблицы выясняют, какой объект удалили и откуда он был.
Чем отличаетсяКод / номерGUID
Кто задаётпользователь или нумераторплатформа
Можно изменитьданет (только при создании нового объекта)
Уникальностьв пределах справочника или периодаглобально, без привязки к базе
Виден в формеданет, без доработок
Где вы ищете GUID?

Как узнать GUID объекта без программирования: навигационная ссылка

В интерфейсе «Такси» у каждой формы объекта есть команда получения ссылки — значок цепочки в заголовке формы рядом со звёздочкой избранного. Тот же пункт «Получить ссылку» есть в главном меню.

  1. Откройте карточку элемента или документа.
  2. Нажмите значок цепочки (или выберите «Получить ссылку» в главном меню).
  3. Скопируйте строку из окна. Она выглядит так:
e1cib/data/Справочник.Номенклатура?ref=80d5005056a5b1c211e91b2c3d5e3f8a

Часть после ref= — это 32 шестнадцатеричные цифры GUID, но переставленные. Платформа пишет их в том порядке, в каком байты лежат в базе: сначала две последние группы, потом третья, вторая и первая.

Группа GUIDПозиции в refПример
1-я (8 символов)25–323d5e3f8a
2-я (4 символа)21–241b2c
3-я (4 символа)17–2011e9
4-я (4 символа)1–480d5
5-я (12 символов)5–16005056a5b1c2

Собираем группы через дефис и получаем 3d5e3f8a-1b2c-11e9-80d5-005056a5b1c2.

Не отправляйте значение ref интегратору или в обмен «как есть». Это не GUID в каноническом виде, а внешняя система по нему ничего не найдёт.

Если переводить приходится часто, функция на встроенном языке делает перестановку сама:

Функция GUIDИзНавигационнойСсылки(Знач Ref) Экспорт
    // Ref — 32 символа после "ref=" в навигационной ссылке
    Возврат Сред(Ref, 25, 8) + "-" + Сред(Ref, 21, 4) + "-"
        + Сред(Ref, 17, 4) + "-" + Сред(Ref, 1, 4) + "-" + Сред(Ref, 5, 12);
КонецФункции

Обратное преобразование — та же перестановка в другую сторону: 4-я и 5-я группы, затем 3-я, 2-я и 1-я, без дефисов.

Поиск объекта по GUID в базе

Найти объект по известному GUID в пользовательском режиме можно через ту же навигационную ссылку.

  1. Переведите GUID в формат ref по таблице выше.
  2. Соберите ссылку: e1cib/data/<Вид>.<Имя объекта>?ref=<32 символа>. Имя объекта — это имя в метаданных, например Справочник.Контрагенты или Документ.РеализацияТоваровУслуг.
  3. В главном меню выберите «Перейти по ссылке», вставьте строку и нажмите «Перейти».

Если форма открылась — объект есть. Если платформа сообщает, что объект не найден, значит, в этом справочнике такого GUID нет: объект удалён, лежит в другой таблице или GUID пришёл из другой базы.

Не знаете, в каком справочнике искать? Начните с типа поля, из которого взят GUID. В обмене это видно по имени элемента XML, в OData — по имени сущности (Catalog_Контрагенты, Document_…).

Программный поиск надёжнее, потому что сразу проверяет, существует ли объект. Метод ПолучитьСсылку() вернёт ссылку даже на несуществующий GUID — это будет битая ссылка, поэтому без проверки запросом не обойтись:

Функция СсылкаПоGUID(ВидОбъекта, ИмяОбъекта, СтрокаGUID) Экспорт

    Попытка
        Идентификатор = Новый УникальныйИдентификатор(СтрокаGUID);
    Исключение
        Возврат Неопределено; // строка не является GUID
    КонецПопытки;

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

    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Т.Ссылка ИЗ " + ВидОбъекта + "." + ИмяОбъекта
        + " КАК Т ГДЕ Т.Ссылка = &Ссылка";
    Запрос.УстановитьПараметр("Ссылка", Ссылка);

    Если Запрос.Выполнить().Пустой() Тогда
        Возврат Неопределено; // объекта с таким GUID в базе нет
    КонецЕсли;

    Возврат Ссылка;

КонецФункции

Пример вызова: СсылкаПоGUID("Справочник", "Номенклатура", "3d5e3f8a-1b2c-11e9-80d5-005056a5b1c2").

Как получить GUID через запрос и код

В языке запросов 1С нет функции, которая вернула бы GUID строкой. Запрос выбирает поле Ссылка, а идентификатор из неё достают уже в коде методом УникальныйИдентификатор().

Выгрузка GUID всех элементов справочника — например, чтобы отдать таблицу интегратору:

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

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    GUID = Строка(Выборка.Ссылка.УникальныйИдентификатор());
    Сообщить(Выборка.Код + ";" + Выборка.Наименование + ";" + GUID);
КонецЦикла;

Этот код удобно выполнять во внешней консоли запросов или консоли кода с обработкой результата. Для выгрузки в файл вместо Сообщить пишите строки в ЗаписьТекста или в табличный документ.

Отбор по GUID в запросе делают через параметр-ссылку, а не через строку:

Ссылка = Справочники.Номенклатура.ПолучитьСсылку(
    Новый УникальныйИдентификатор("3d5e3f8a-1b2c-11e9-80d5-005056a5b1c2"));
Запрос.УстановитьПараметр("Ссылка", Ссылка);
// в тексте запроса: ГДЕ Номенклатура.Ссылка = &Ссылка

Полезные методы, которые стоит держать под рукой:

ЗадачаЧто использовать
GUID объекта строкойСтрока(Ссылка.УникальныйИдентификатор())
GUID для XML и обменаXMLСтрока(Ссылка)
Ссылка из строки GUIDXMLЗначение(Тип("СправочникСсылка.Номенклатура"), СтрокаGUID)
Ссылка из значения GUIDСправочники.Номенклатура.ПолучитьСсылку(Идентификатор)
Навигационная ссылкаПолучитьНавигационнуюСсылку(Ссылка)
Новый случайный GUIDНовый УникальныйИдентификатор()
Пустая ссылкаGUID 00000000-0000-0000-0000-000000000000

Если объект надо создать с заранее известным GUID (типичный случай при загрузке из внешней системы), используйте УстановитьСсылкуНового() до первой записи:

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

Для серверной базы на MS SQL или PostgreSQL GUID лежит в поле _IDRRef типа binary(16) — в том же порядке байтов, что и ref в навигационной ссылке. Имена таблиц (_Reference42, _Document157) в каждой базе свои, их показывает ПолучитьСтруктуруХраненияБазыДанных().

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

GUID в конфигураторе и отладчике

Конфигуратор сам по себе GUID элементов справочников не показывает: это режим разработки, а не просмотра данных. Зато в нём есть два места, где GUID видно.

Отладчик

Самый быстрый способ для программиста, если код уже остановлен на точке останова рядом с нужным объектом.

  1. Поставьте точку останова в модуле, где доступна переменная со ссылкой (например, в обработчике ПриОткрытии формы элемента).
  2. Когда выполнение остановится, откройте окно вычисления выражений (Shift+F9).
  3. Введите Строка(Объект.Ссылка.УникальныйИдентификатор()) или подставьте имя своей переменной и нажмите «Рассчитать».

В том же окне можно сделать обратное: вычислить Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор("…")).Наименование. Если вместо наименования пришла ошибка или пустое значение, объекта с таким GUID нет.

GUID метаданных

У самих объектов конфигурации — справочников, реквизитов, форм — тоже есть GUID, но это другая сущность. Он виден после команды Конфигурация → Выгрузить конфигурацию в файлы: в XML-описании каждого объекта стоит атрибут uuid.

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

GUID пользователя и базы

  • 👤 Пользователь информационной базы. ПользователиИнформационнойБазы.НайтиПоИмени("Иванов").УникальныйИдентификатор. В конфигурациях на БСП он же хранится в реквизите ИдентификаторПользователяИБ элемента справочника «Пользователи».
  • 🗄 Информационная база на сервере. Идентификатор базы в кластере показывает rac infobase summary list --cluster=<id кластера>, id кластера — rac cluster list. Этот же GUID стоит в имени папки базы в каталоге кластера srvinfo\reg_1541.

Внешняя обработка для получения GUID

Когда GUID нужен регулярно, а конфигуратора у пользователя нет, проще один раз сделать внешнюю обработку на 5 минут работы.

  1. В конфигураторе: Файл → Новый → Внешняя обработка.
  2. Добавьте реквизиты: ИсходнаяСсылка (составной тип с нужными справочниками и документами), GUIDСтрокой (строка, 36 символов).
  3. Создайте форму обработки, выведите на неё оба реквизита и команду «Показать GUID».
  4. В модуле формы пропишите код:
&НаКлиенте
Процедура ПоказатьGUID(Команда)
    ПоказатьGUIDНаСервере();
КонецПроцедуры

&НаСервере
Процедура ПоказатьGUIDНаСервере()
    Если ЗначениеЗаполнено(Объект.ИсходнаяСсылка) Тогда
        Объект.GUIDСтрокой = Строка(Объект.ИсходнаяСсылка.УникальныйИдентификатор());
    Иначе
        Объект.GUIDСтрокой = "";
    КонецЕсли;
КонецПроцедуры
  1. Сохраните файл .epf и откройте его в пользовательском режиме через Файл → Открыть (для этого нужно право на открытие внешних обработок).

Обработку легко расширить в обратную сторону: добавьте поля «Вид объекта», «Имя объекта» и «GUID» и вызовите на сервере функцию СсылкаПоGUID из раздела про поиск. Результат положите в ИсходнаяСсылка — пользователь сразу откроет найденный объект.

Для GUID в табличной части документа (например, номенклатуры в строке) пройдите по строкам Объект.ИсходнаяСсылка.Товары и выведите GUID каждой строки в таблицу формы.

GUID в обмене данными: XML, JSON и OData

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

XML. При сериализации ссылки (ЗаписатьXML, XMLСтрока) в файл попадает GUID в каноническом виде, 36 символов. В пакетах формата EnterpriseData идентификатор объекта лежит в ключевых свойствах в элементе Ссылка. Открыв файл обмена в текстовом редакторе и поискав GUID, вы быстро увидите, пришёл объект или нет.

JSON. Сериализатор XDTO при записи в JSON тоже пишет ссылку строкой GUID. В своих HTTP-сервисах GUID обычно отдают отдельным полем:

Данные = Новый Структура;
Данные.Вставить("id", XMLСтрока(Ссылка));
Данные.Вставить("name", Ссылка.Наименование);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Данные);
Результат = ЗаписьJSON.Закрыть();

OData. В стандартном интерфейсе OData у каждой сущности есть поле Ref_Key — это и есть GUID. Ссылочные реквизиты приходят полями с суффиксом _Key. Получить один объект по GUID:

http://server/base/odata/standard.odata/Catalog_Номенклатура(guid'3d5e3f8a-1b2c-11e9-80d5-005056a5b1c2')?$format=json

Перед этим объект должен быть включён в состав стандартного интерфейса OData, иначе сервис вернёт ошибку.

КаналГде GUIDФормат
Навигационная ссылкапараметр ref32 символа, переставлены
XML, EnterpriseDataзначение ссылки, ключевые свойства36 символов с дефисами
JSONстроковое поле36 символов с дефисами
ODataRef_Key, поля …_Key36 символов с дефисами
SQL_IDRRefbinary(16), порядок как в ref

Ошибки при работе с GUID и как их избежать

Диагностика: выберите симптом

Ещё три ловушки, на которые натыкаются при интеграциях:

  • 🔡 Регистр. Строка(УникальныйИдентификатор) возвращает символы в нижнем регистре, а внешняя система может хранить верхний. Сравнивайте строки после НРег() или сравнивайте значения типа УникальныйИдентификатор, а не строки.
  • 📋 Копирование объекта. Команда «Скопировать» создаёт новый объект с новым GUID. Для внешней системы это другой товар, даже если все реквизиты совпадают.
  • 📌 GUID в коде. Не вписывайте GUID конкретного элемента в модули: в другой базе этого элемента не будет. Для постоянных значений используйте предопределённые элементы или константы.

Частые вопросы

Меняется ли GUID при изменении кода или наименования?
Нет. Код, наименование, номер и дата документа меняются независимо, GUID остаётся тем же, пока объект не удалён.
Совпадают ли GUID в копии базы?
Да. При выгрузке и загрузке через .dt и в узлах распределённой базы GUID сохраняются. В новой базе, где объекты заведены заново, GUID будут другими.
Можно ли увидеть GUID в списке справочника без доработок?
Нет, типовые формы списка его не показывают. Нужна внешняя обработка, отчёт с вычисляемым полем на встроенном языке или доработка формы через расширение.
Может ли у двух объектов быть одинаковый GUID?
Платформа генерирует GUID случайно, вероятность совпадения пренебрежимо мала. Одинаковые GUID в разных справочниках возможны только при ручной установке через УстановитьСсылкуНового(), и это разные объекты.
Какой GUID у пустой ссылки?
Нули во всех группах: 00000000-0000-0000-0000-000000000000. Проверять пустоту ссылки удобнее через ЗначениеЗаполнено().