+6
GUID (Globally Unique Identifier) — статистически уникальный 128-битный идентификатор. Его главная особенность — уникальность, которая позволяет создавать расширяемые сервисы и приложения без опасения конфликтов, вызванных совпадением идентификаторов. Хотя уникальность каждого отдельного GUID не гарантируется, общее количество уникальных ключей настолько велико (2128 или 3,402 * 10в38), что вероятность того, что в мире будут независимо сгенерированы два совпадающих ключа, крайне мала.
Для получения уникального идентификатора объекта, используйте код вида:
Код 1C v 8.х
ГУИДССЫЛКИ = СсылкаНаОбъект.УникальныйИдентификатор();
// или
НоменклатураСсылка = Справочники.Номенклатура.НайтиПоКоду("00013");
Если НЕ НоменклатураСсылка.Пустая() Тогда
Сообщить("GUID = " + НоменклатураСсылка.УникальныйИдентификатор());
КонецЕсли;
Как с помощью запроса получить уникальный идентификатор:
Код 1C v 8.х
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.НаименованиеПолное,
| Номенклатура.ЕдиницаИзмерения,
| Номенклатура.СтавкаНДС,
| Номенклатура.НоменклатурнаяГруппа,
| Номенклатура.СчетУчетаЗапасов,
| Номенклатура.СчетУчетаЗатрат,
| Номенклатура.Ссылка,
| Номенклатура.ЭтоГруппа
| ИЗ
| Справочник.Номенклатура КАК Номенклатура";
РезультатЗапроса = Запрос.Выполнить();
СпрОбъект = РезультатЗапроса.Выбрать();
Пока СпрОбъект.Следующий() Цикл
СтрокаУИ = Объект.XMLСтрока(СпрОбъект.Ссылка);
GUID = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СокрЛП(СтрокаУИ)));
КонецЦикла;
В 1С 7.7 можно получить так
Через v7plus.dll
Код 1C v 7.x
Инфо = СоздатьОбъект("AddIn.V7SysInfo");
ГлобальноУникальныйИдентификатор = Инфо.СоздатьGUID();
Через WScript
Код 1C v 7.x
Функция СоздатьGUID()
TypeLib = CreateObject("Scriptlet.TypeLib");
NewGUID = TypeLib.Guid();
TypeLib = "";
Возврат NewGUID;
КонецФункции
//*******************************************
Процедура Сформировать()
g=СоздатьGUID();
Сообщить("Создан GUID: "+g);
КонецПроцедуры
при OLE доступе:
Код 1C v 7.x
Если Док_Источник.ВыбратьДокументы(ВыбНачПериода,ВыбКонПериода) = 1 Тогда
Пока Док_Источник.ПолучитьДокумент() = 1 Цикл
Объект = БазаОле.ЗначениеВстрокуВнутр(Док_Источник.ТекущийДокумент());
ИдентификаторДокумента = СокрЛП(ПолучитьИД(Объект));
// Для примера Объект возвращает {"O","0","0","3114","0","0"," 258156CB "},
// а ПолучитьИД(объект) = 258156CB
КонецЦикла;
Еще посмотрите метод:
ЗначениеВСтрокуВнутр(<?>);
Синтаксис:
ЗначениеВСтрокуВнутр(<Объект>)
Назначение:
Преобразование значения объекта агрегатного типа в строковое системное представление.
Возвращает: представление значения объекта в строковом системном виде.
Параметры:
<Объект> – значение объекта агрегатного типа данных которое нужно преобразовать.
Содержание:
1. Что такое GUID в 1С?
2. Чем отличается GUID от UUID?
3. Как получить уникальный идентификатор зная UUID в 1С
1. Что такое GUID в 1С?
GUID – это объект матричной таблицы в системе базы данных из шестнадцатеричных символов, заключенных в круглые скобки и прописанных через дефис. Он формируется с учетом времени и места, указывающего на расположение этого объекта (справочника, документа). Первая половина этого кода является расчетом времени, вторая – местом, где хранится объект. GUID в 1С создается в момент создания объекта. Подобно массивам объект хранится в определенной таблице, на определенном столбце с определенной строкой. При определенном попадании в эти 100 наносекунд могут формироваться абсолютно идентичные объекты. Это настолько мало вероятно, как проверить на уникальность все значения за 10 млрд лет.
В Базе данных для каждого объекта предназначен свой глобальный уникальный идентификатор – GUID (Globally Unique Identifier). Он представляет из себя ссылку из 32 символов, разделенных дефисами, которая состоит из 16 октетов. В первой части содержится время генерации уникального идентификатора, во второй – счетчик и MAC-адрес. Отсчет времени для генерации кода Guid идет с 15 октября 1582 года с интервалом на 100 наносекунд.
Вот так выглядит GUID БД 1С: 3de72ee8-f8b2-11e4-92f1-0050568b35ac
Его UUID можно получить по ссылке.
e1cib/data/Документ.ПриходныйОрдерНаТовары?ref=92f10050568b35ac11e4f8b23de72ee8
Это зеркальное отражение уникального идентификатора в 1С 8.3.
Совпадений разных объектов одной базы крайне малы, т.к. общее количество сгенерированных ключей составляет (2128 или 3,402 * 10в38).
Этот 128-битный код информации определяется ссылкой на тип метаданных, содержащий информацию об объекте. Генерация Guid происходит не только в пространстве, но и во времени псевдослучайным набором чисел. Непрерывно сформированные GUIDы используются в качестве первичных ключей в базе данных.
2. Чем отличается GUID от UUID?
UUID – универсально-уникальный идентификатор по данным всемирной организации стандартизации версии RFC4122. Этот термин используется в спецификациях протокола Windows как синоним GUID в 1С. Он должен быть полностью технически совместим с RFC4122. Из рекомендаций Международного стандарта “Все стандарты UUID, соответствующие этой Рекомендации, должны иметь биты варианта с битом 7 октета 7, установленным в 1 и бит 6 октета 7, установленным в 0”.
3. Как получить уникальный идентификатор зная UUID в 1С
Итак, как же получить GUID зная UUID в 1С?
В конструкторе запроса необходимо создать запрос:
СправочникСсылка=Справочники.ИмяСправочника.НайтиПоНаименованию(«Наименование»);
GUID=СправочникСсылка.УникальныйИдентификатор()
Для установления соответствия объектов разных БД используется GUID.
Необходимо указать узел обмена и тип объекта (склад, договор, контрагент и т.д.). В «источнике» базы данных нужно указать объект, с которым будет устанавливаться соответствие с объектом из «приемника» БД.
Специалист компании ООО «Кодерлайн»
Ирина Оргина.
Пример уникального идентификатора: 4bf85396-cc7a-11ea-9ef0-c86000245adb
// //Узнать уникальный идентификатор ГУИД = КонтрагентСсылка.УникальныйИдентификатор(); //Создаём уникальный идентификатор из строки СтрокаGUID = “4bf85396-cc7a-11ea-9ef0-c86000245adb”; НовыйGUID = Новый УникальныйИдентификатор(СтрокаGUID); //Можно не указывать СтрокаGUID. Программа сгенерирует сама НовыйGUID = Новый УникальныйИдентификатор(); |
// //Получить ссылку на на объект, зная его GUID СсылкаПП = Документы.ПлатежноеПоручениеВходящее.ПолучитьСсылку(НовыйGUID); //Создать документ и присвоить ему ГУИД СтрокаGUID = “4bf85396-cc7a-11ea-9ef0-c86000245adb”; Док = Документы.ПлатежноеПоручениеВходящее.СоздатьДокумент(); СсылкаДок = Документы.ПлатежноеПоручениеВходящее.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)); Док.УстановитьСсылкуНового(СсылкаДок); |
// //Получить ГУИД из COM-объекта V83COMConnector = Новый COMОбъект(“V83.COMConnector”); БД = V83COMConnector.Connect(ПараметрыПодключения); СтрокаГУИД = БД.XMLСтрока(Док.Ссылка); |
Вариант применения в заметке «Сделать из элемента справочника группу»
18.11.2021
Получение уникального идентификатора объекта из ссылки в запросе
Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.
Планируется в версии 8.3.22
По многочисленным просьбам в версии 8.3.22 в язык запросов и в язык выражений СКД добавится функция УникальныйИдентификатор(Ссылка). Параметр Ссылка – выражение, результатом которого является ссылка (кроме ссылок на таблицы внешних источников данных). Функция возвращает уникальный идентификатор переданной ссылки или NULL, если передано значение NULL.
Это нововведение, в частности, упростит задачи интеграции систем на платформе 1С:Предприятие с внешними системами.
Рассмотрим пример. У нас есть интеграция с внешней системой на уровне данных – таблица внешней системы ссылается на справочник Товары в нашей инфобазе.
Структура таблицы внешней системы:
Идентификатор | Ключ (число) |
Наименование | Название товара на английском языке (строка) |
УникальныйИдентификатор | Ссылка на элемент справочника Товары (уникальный идентификатор) |
Нам нужно на стороне 1С вывести содержимое справочника Товары и для каждого товара показать его название на английском языке.
Предположим, мы получили содержимое внешней таблицы в виде таблицы значений (через веб-сервис или внешний источник данных или ещё каким-то образом).
Сейчас связать записи внешней таблицы (лежащие в таблице значений) с элементами справочника Товары можно так:
- Добавить в таблицу значений колонку, которую надо заполнить ссылкой на элементы справочника Товары, обойдя все записи таблицы значений в цикле.
- Полученную таблицу значений с помощью запроса объединить со справочником Товары.
В версии 8.3.22 это можно будет сделать гораздо проще.
Проиллюстрируем это кодом. Содержимое внешней таблицы помещено в таблицу значений ТЗ_ТоварыВнешняя.
“ВЫБРАТЬ
| ТЗ_ТоварыВнешняя.Наименование КАК НаименованиеEn,
| ТЗ_ТоварыВнешняя.УникальныйИдентификатор КАК УникальныйИдентификатор
|ПОМЕСТИТЬ ВТ_ТоварыВнешняя
|ИЗ
| &ТЗ_ТоварыВнешняя КАК ТЗ_ТоварыВнешняя
|;
|
|ВЫБРАТЬ
| Товары.Код КАК Код,
| Товары.Наименование КАК Наименование,
| ВТ_ТоварыВнешняя.НаименованиеEn КАК НаименованиеEn
|ИЗ
| Справочник.Товары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ТоварыВнешняя КАК ВТ_ТоварыВнешняя
| ПО УникальныйИдентификатор(Товары.Ссылка) = ВТ_ТоварыВнешняя.УникальныйИдентификатор
|”;
Запрос.УстановитьПараметр(“ТЗ_ТоварыВнешняя “, ТЗ_ТоварыВнешняя);
Данные = Запрос.Выполнить().Выбрать();
Теги:
8.3.22
запросы
Содержание
Что такое GUID и где он используется в 1С
GUID расшифровывается как Globally Unique Identifier, и представляет собой статистически уникальный 128-битный идентификатор. Вероятность того, что где-нибудь в мире будут независимо сгенерированы два идентичных ключа, исчезающе мала, так как общее количество возможных ключей составляет 2 в 128 степени. В 1С GUID используется в ссылочных типах данных, а также уникальный идентификатор присваивается каждому вновь образуемому типу данных при добавлении метаданных конфигурации. На примере метаданных обработки: GUID есть у самого объекта метаданных, у объекта данных, и у менеджера этой обработки. Эти идентификаторы используются в механизмах сериализации, а также в механизмах сравнения-объединения конфигураций.
Получить идентификатор у ссылочного объекта можно, а вот программного доступа к GUID метаданных нет – но можно посмотреть идентификаторы образованных типов, выгрузив конфигурацию в файлы, либо получив сериализованное представление нужного объекта.
Устройство GUID в 1С на примерах
Строковое представление GUID – это строка из 32 шестнадцатеричных цифр, состоящая из четырех частей, разделенных дефисами. Уникальные идентификаторы делятся на пять версий. В зависимости от версии GUID, его четыре части формируются по-разному, и содержат разную информацию. Подробное строение GUID описано в спецификации UUID – универсального уникального идентификатора, реализацией которого является GUID.
- time-based version. Данная версия содержит информацию о времени генерации GUID и MAC-адресе узла (устройства), на котором идентификатор был сгенерирован
- DCE Security version (POSIX UIDs) – также содержит MAC-адрес, но из-за особенностей генерации не подходит в случаях, когда GUID необходимо генерировать чаще чем раз в 7 минут
- name-based version (MD5 hashing) – GUID генерируется путем хэширования идентификатора пространства имен и имени. Хэширование производится по алгоритму MD5
- randomly generated version – случайно генерируемый GUID
- name-based version (SHA-1 hashing) – то же что и версия 3, только в качестве алгоритма хэширования используется SHA-1
GUID для объектов ссылочных типов, которые генерируются в момент записи объекта, относятся к time-based версии, а идентификаторы объектов метаданных, типов значений, предопределенных элементов, созданных в конфигураторе, и полученные методом Новый УникальныйИдентификатор() относятся к версии 4 – случайно генерируемые.
Вооружившись этими знаниями, займемся исследованием GUID-ов, которые мы можем получить в 1С. В качестве объектов для опытов создадим обработку РаботаСГУИД и справочник ТестовыйСправочник. В обработке добавим команду, а в серверном обработчике этой команды пропишем следующий код:
&НаСервере Процедура ПолучитьСериализованноеПредставлениеНаСервере() МенеджерОбработки = Обработки.РаботаСГУИД; Сообщить(ЗначениеВСтрокуВнутр(МенеджерОбработки)); МенеджерОбъектаОбработки = Обработки.РаботаСГУИД.Создать(); Сообщить(ЗначениеВСтрокуВнутр(МенеджерОбъектаОбработки)); Для Сч = 1 по 3 Цикл Эл = Справочники.ТестовыйСправочник.СоздатьЭлемент(); Эл.Записать(); Сообщить(Эл.Ссылка.УникальныйИдентификатор()); Эл.Удалить(); КонецЦикла; // У объекта языка "Метаданные" GUID всегда один и тот же - 9fb58eea-17f2-4200-b105-b288d62f4303 Сообщить(ЗначениеВСтрокуВнутр(Справочники.ТестовыйСправочник.СоздатьЭлемент().Метаданные())); Сообщить(ЗначениеВСтрокуВнутр(Метаданные.Обработки.РаботаСГУИД)); КонецПроцедуры
Метод ЗначениеВСтрокуВнутр сериализует объекты языка в строку. В рассматриваемом примере в окно сообщений будут выведены следующие данные:
{“#”,ff798e9f-e182-4a0f-af78-224dbb45de69,
{0}
}
{“#”,609fe03c-dbf8-4f78-835d-178eed7ceb70}
8e1f9db8-4be2-11ed-a101-2c4d5450919d
8e1f9db9-4be2-11ed-a101-2c4d5450919d
8e1f9dba-4be2-11ed-a101-2c4d5450919d
{“#”,9fb58eea-17f2-4200-b105-b288d62f4303}
{“#”,9fb58eea-17f2-4200-b105-b288d62f4303}
Если выгрузить конфигурацию в файлы и открыть файл с обработкой РаботаСГУИД, можно увидеть, что идентификаторы экземпляра обработки и менеджера обработки действительно соответствуют тому, что мы получили в результате сериализации:
Разберем структуру GUID на примере идентификатора, созданного в момент записи элемента справочника:
8e1f9db8-4be2-11ed-a101-2c4d5450919d
GUID записывается по группами шестнадцатеричных чисел по схеме 8-4-4-4-12. В случае, когда используется версия 1 (основанная на времени), значение групп будет следующим:
8e1f9db8-4be2 – отметка времени Timestamp
11ed – первые бита – это версия GUID, в нашем случае 1. Остальные – формируют оставшуюся часть отметки времени
a101 – вариант GUID И Clock Sequence
2c4d5450919d – MAC-адрес узла (Node)
Так все-таки, можно ли упорядочивать по GUID?
При записи объектов в 1С версия 1 используется не просто так. Случайные GUID очень плохо кластеризуются, дерево поиска получается максимально широкое, и для того, чтобы оптимизировать операции поиска / вставки, используется комбинированный вариант генерации GUID. Использование отметки времени позволяет сделать ключи более сгруппированными и уменьшить ширину B-дерева. При этом последовательное их возрастание в общем случае не гарантируется. В рамках одного сеанса генерируемые GUID формируются порциями по 32 штуки, и в рамках этой порции они действительно могут быть последовательными. Если объекты одновременно записываются в нескольких параллельных сеансах, их GUID могут быть упорядочены в рамах одного сеанса, одного типа данных, и одного пула из 32 идентификаторов.
Сами уникальные идентификаторы в СУБД хранятся в виде двоичных данных Binary (16), и сортируются побитово как бинарные данные. Попытки использовать GUID для упорядочивания по отметке времени – от лукавого. Во-первых, на оси времени в пределах одной секунды документы разных типов в любом случае не будут располагаться хронологически. Во-вторых, документы одного типа также не будут в общем случае, если они заводятся в рамках разных параллельных сеансов.
Вывод, подкрепленный цитатой Бориса Нуралиева: использовать GUID для хронологического упорядочивания объектов на оси времени в общем случае нельзя!
“Механизм генерации ссылок обеспечивает только их уникальность. Возрастающая последовательность при их генерации не обеспечивается.” (c)
Получить время из GUID
&НаСервереБезКонтекста Функция ОтметкаВремениГУИД(ГУИД) // В спецификации UUID для версии 1 дата содержится в первых трех группах из схемы 8-4-4-4-12 // Например, рассмотрим GUID 8e1f9db8-4be2-11ed-a101-2c4d5450919d // Дата содержится в первых символах, 8e1f9db8-4be2-11ed которые нужно переставить в обратном порядке: 11ed-4be2-8e1f9db8 Строка16 = Сред(ГУИД, 15, 4) + Сред(ГУИД, 10, 4) + Сред(ГУИД, 1, 8); // Убираем знаки "-"(дефисы) Строка16 = СтрЗаменить(Строка16, "-", ""); // Убираем первый символ, так как по спецификации это - номер версии стандарта. Строка15 = Сред(Строка16, 2); // Получаем 60-битную отметку времени : ed4be28e1f9db8 // Преобразуем к десятичному числу ЧислоСек = 0; Для Позиция = 1 По СтрДлина(Строка15) Цикл ЧислоСек = ЧислоСек + Найти("123456789abcdef", Сред(Строка15, Позиция, 1))*Pow(16, СтрДлина(Строка15) - Позиция); КонецЦикла; ЧислоСек = ЧислоСек / 10000000; // Прибавляем к дате начала Григореанского календаря Возврат Дата(1582, 10, 15, 00, 00, 00) + ЧислоСек + СмещениеСтандартногоВремени() + СмещениеЛетнегоВремени();; КонецФункции
Разбор GUID из ссылки
В 1С из ссылки можно получить тип уникального идентификатора (его версию), время и MAC-адрес узла для версии 1.
&НаСервереБезКонтекста Функция ВерсияГУИД(ГУИД) // Номер версии содержится в старшем байте седьмого октета Версия = Число(Сред(ГУИД, 15, 1)); СоответствиеВерсий = Новый Соответствие; СоответствиеВерсий.Вставить(0, "NIL GUID"); СоответствиеВерсий.Вставить(1, "Version 1. (Time-based)"); СоответствиеВерсий.Вставить(2, "DCE Security (POSIX)"); СоответствиеВерсий.Вставить(3, "Version 3. Name-based (MD5 hashing)"); СоответствиеВерсий.Вставить(4, "Version 4. Random"); СоответствиеВерсий.Вставить(5, "Version 5. Name-based (SHA-1 hashing)"); Возврат СоответствиеВерсий.Получить(Версия); КонецФункции
&НаСервереБезКонтекста Функция УзелГУИД(ГУИД) // В маске UUID 8-4-4-4-12 для версии 1 MAC-адрес содержится в последней 12-значной группе. Строка12 = Сред(ГУИД, 25); // Разделим на октеты Результат = ""; Для Позиция = 1 По СтрДлина(Строка12) Цикл Если Позиция % 2 = 1 Тогда Результат = Результат + " "; КонецЕсли; Результат = Результат + ВРЕГ(Сред(Строка12,Позиция,1)); КонецЦикла; Результат = СтрЗаменить(СокрЛП(Результат), " ", ":"); Возврат Результат; КонецФункции
&НаКлиенте Процедура ВывестиИнформациюПоГУИД(Знач ГУИД, Знач СсылкаНаЭлементСправочника) Сообщить("Ссылка: " + СсылкаНаЭлементСправочника); Сообщить("GUID: " + ГУИД); Сообщить("Дата создания: " + ОтметкаВремениГУИД(ГУИД)); Сообщить("Версия: " + ВерсияГУИД(ГУИД)); Сообщить("MAC-адрес хоста: " + УзелГУИД(ГУИД)); КонецПроцедуры
Для любой пустой ссылки идентификатор всегда будет 00000000-0000-0000-0000-000000000000. По идентификатору определить тип значения объекта в общем случае невозможно. Более того, объекты разных типов могут иметь одинаковые идентификаторы даже в пределах одной информационной базы (Например, элементы справочников Номенклатура и Контрагенты), так как их уникальность будет обеспечиваться типами значений (ключи хранятся физически в разных таблицах, следовательно, между собой не пересекаются).
Получение GUID в запросе
В версии платформы 8.3.22 планируется реализовать в языке запросов метод УникальныйИдентификатор(СсылкаНаОбъект) для получения GUID непосредственно в результат запроса.
В остальных же случаях стандартное решение – обойти результат запроса и использовать метод ссылки УникальныйИдентификатор() в цикле.
Как узнать GUID-ы метаданных?
Программного доступа к идентификаторам метаданных у разработчика нет. Тем не менее, можно выгрузить конфигурацию в файлы, и проанализировать их содержимое. Кроме того, сериализуемые объекты можно преобразовать в сериализованную строку и в этой строке узнать идентификатор, например, для объекта обработки или ее менеджера. Разумеется, можно частично это дело автоматизировать, написать скрипты выгрузки конфигурации в файлы, парсинга этих файлов и т.д.
Особенности представления GUID в 1С
Ссылка в 1С представляет собой комбинацию номера таблицы в СУБД и уникального идентификатора. Рассмотрим пример:
&НаСервере Процедура РазобратьСсылкуНовогоНаСервере() ТестСсылка = Справочники.ТестовыйСправочник.ПолучитьСсылку(Новый УникальныйИдентификатор()); ГУИД= ТестСсылка.УникальныйИдентификатор(); ВывестиИнформациюПоГУИД(ГУИД, ТестСсылка); КонецПроцедуры
Дата создания: 23.11.2963 20:26:48 Ссылка: <Объект не найден> (166:adc8d3f7c50e35a2460c6676bb9ce99d) GUID: bb9ce99d-6676-460c-adc8-d3f7c50e35a2 Версия: Version 4. Random MAC-адрес хоста: D3:F7:C5:0E:35:A2
Обратите внимание, т.к. версия формата 4 – все данные представляют собой случайный набор символов, соответственно, ни даты ни мак-адреса случайный GUID не содержит.
Представление ссылки в 1С – это UUID, который записан отличным образом от GUID этой же ссылки. Перед идентификатором выводится номер таблицы в СУБД, в нашем случае 166. Из UUID можно восстановить GUID, и наоборот. Для этого следует разделить запись на октеты (последовательности из 4 символов) и выстроить их в нужном порядке.
- 1 – bb9c
- 2 – e99d
- 3 – 6676
- 4 – 460c
- 5 – adc8
- 6 – d3f7
- 7 – c50e
- 8 – 35a2
- 5 – adc8
- 6 – d3f7
- 7 – c50e
- 8 – 35a2
- 4 – 460c
- 3 – 6676
- 1 – bb9c
- 2 – e99d