Уникальный идентификатор ссылки в 1С 8.3: где его увидеть и как получить кодом
Содержание
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 запросом.Ref_Key в OData: в разных базах у одного и того же объекта он совпадает, только если объект пришёл обменом или копией базы.Как узнать GUID объекта без программирования: навигационная ссылка
В интерфейсе «Такси» у каждой формы объекта есть команда получения ссылки — значок цепочки в заголовке формы рядом со звёздочкой избранного. Тот же пункт «Получить ссылку» есть в главном меню.
- Откройте карточку элемента или документа.
- Нажмите значок цепочки (или выберите «Получить ссылку» в главном меню).
- Скопируйте строку из окна. Она выглядит так:
e1cib/data/Справочник.Номенклатура?ref=80d5005056a5b1c211e91b2c3d5e3f8a
Часть после ref= — это 32 шестнадцатеричные цифры GUID, но переставленные. Платформа пишет их в том порядке, в каком байты лежат в базе: сначала две последние группы, потом третья, вторая и первая.
| Группа GUID | Позиции в ref | Пример |
|---|---|---|
| 1-я (8 символов) | 25–32 | 3d5e3f8a |
| 2-я (4 символа) | 21–24 | 1b2c |
| 3-я (4 символа) | 17–20 | 11e9 |
| 4-я (4 символа) | 1–4 | 80d5 |
| 5-я (12 символов) | 5–16 | 005056a5b1c2 |
Собираем группы через дефис и получаем 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 в пользовательском режиме можно через ту же навигационную ссылку.
- Переведите GUID в формат
refпо таблице выше. - Соберите ссылку:
e1cib/data/<Вид>.<Имя объекта>?ref=<32 символа>. Имя объекта — это имя в метаданных, напримерСправочник.КонтрагентыилиДокумент.РеализацияТоваровУслуг. - В главном меню выберите «Перейти по ссылке», вставьте строку и нажмите «Перейти».
Если форма открылась — объект есть. Если платформа сообщает, что объект не найден, значит, в этом справочнике такого 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Строка(Ссылка) |
| Ссылка из строки GUID | XMLЗначение(Тип("СправочникСсылка.Номенклатура"), Строка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 видно.
Отладчик
Самый быстрый способ для программиста, если код уже остановлен на точке останова рядом с нужным объектом.
- Поставьте точку останова в модуле, где доступна переменная со ссылкой (например, в обработчике
ПриОткрытииформы элемента). - Когда выполнение остановится, откройте окно вычисления выражений (
Shift+F9). - Введите
Строка(Объект.Ссылка.УникальныйИдентификатор())или подставьте имя своей переменной и нажмите «Рассчитать».
В том же окне можно сделать обратное: вычислить Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор("…")).Наименование. Если вместо наименования пришла ошибка или пустое значение, объекта с таким 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 минут работы.
- В конфигураторе:
Файл → Новый → Внешняя обработка. - Добавьте реквизиты:
ИсходнаяСсылка(составной тип с нужными справочниками и документами),GUIDСтрокой(строка, 36 символов). - Создайте форму обработки, выведите на неё оба реквизита и команду «Показать GUID».
- В модуле формы пропишите код:
&НаКлиенте
Процедура ПоказатьGUID(Команда)
ПоказатьGUIDНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПоказатьGUIDНаСервере()
Если ЗначениеЗаполнено(Объект.ИсходнаяСсылка) Тогда
Объект.GUIDСтрокой = Строка(Объект.ИсходнаяСсылка.УникальныйИдентификатор());
Иначе
Объект.GUIDСтрокой = "";
КонецЕсли;
КонецПроцедуры
- Сохраните файл
.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 | Формат |
|---|---|---|
| Навигационная ссылка | параметр ref | 32 символа, переставлены |
| XML, EnterpriseData | значение ссылки, ключевые свойства | 36 символов с дефисами |
| JSON | строковое поле | 36 символов с дефисами |
| OData | Ref_Key, поля …_Key | 36 символов с дефисами |
| SQL | _IDRRef | binary(16), порядок как в ref |
Ошибки при работе с GUID и как их избежать
ref взяли за GUID без перестановки групп. Переведите его по таблице позиций или функцией GUIDИзНавигационнойСсылки.СокрЛП() и оберните вызов в Попытка.ПолучитьСсылку() не проверяет существование объекта. Добавьте проверку запросом или сравните Ссылка.ПолучитьОбъект() с Неопределено.Ещё три ловушки, на которые натыкаются при интеграциях:
- 🔡 Регистр.
Строка(УникальныйИдентификатор)возвращает символы в нижнем регистре, а внешняя система может хранить верхний. Сравнивайте строки послеНРег()или сравнивайте значения типаУникальныйИдентификатор, а не строки. - 📋 Копирование объекта. Команда «Скопировать» создаёт новый объект с новым GUID. Для внешней системы это другой товар, даже если все реквизиты совпадают.
- 📌 GUID в коде. Не вписывайте GUID конкретного элемента в модули: в другой базе этого элемента не будет. Для постоянных значений используйте предопределённые элементы или константы.
Частые вопросы
Меняется ли GUID при изменении кода или наименования?
Совпадают ли GUID в копии базы?
.dt и в узлах распределённой базы GUID сохраняются. В новой базе, где объекты заведены заново, GUID будут другими.Можно ли увидеть GUID в списке справочника без доработок?
Может ли у двух объектов быть одинаковый GUID?
УстановитьСсылкуНового(), и это разные объекты.Какой GUID у пустой ссылки?
00000000-0000-0000-0000-000000000000. Проверять пустоту ссылки удобнее через ЗначениеЗаполнено().