Про ссылки, уникальные идентификаторы, GUID и не найденные объекты

Публикация № 127208

Администрирование - Администрирование данных 1С - Поиск данных

Одним из основных постулатов теории по программированию в 1С является понятие объектного типа данных, когда мы говорим, что «удаление объекта ссылочного типа из базы данных и затем создание нового объекта в базе с такими же точно реквизитами приведет базу в новое состояние, в отличие от случая с не объектными данными (например записи регистров)». И для начинающих это так. Но иногда, при решении практических задач, этих безусловно полезных для формирования правильной «картины мира» у новичка знаний становится недостаточно...

Про ссылки, GUID, уникальные идентификаторы и ненайденные объекты.

Одним из основных постулатов теории программирования в 1С является понятие объектного типа данных, когда мы говорим, что «удаление объекта  ссылочного типа из базы данных и затем создание нового объекта в базе с такими же точно реквизитами приведет базу в новое состояние, в отличие от случая с необъектными  данными (записи регистров и пр.)». И для новичков это так.

Но иногда, при решении практических задач, этих безусловно полезных для формирования правильной «картины мира» новичка знаний становится недостаточно.

Итак, что же такое ссылка с точки зрения 1С? Ссылка - это тип данных, однозначно идентифицирующий объект в системе. А как ссылка соотносится с уникальным идентификатором (далее УИД) , получаемым методом УникальныйИдентификатор()?  УИД - это по сути свойство ссылки с типом УникальныйИдентификатор, строковое представление которого является 16-ричным числом и выглядит примерно так:

6a09f20a-8de6-11e1-b3e1-001617ec3f2a

К слову, УИД пустой ссылки всегда такой:

00000000-0000-0000-0000-000000000000

Итак, ссылка логически состоит из двух  частей – имени соответствующего объекта метаданных (тип ссылки), например «Справочник.Контрагенты»,  и УИДа, являющегося по своей природе GUIDом (об этом далее). Уникальность имени объекта метаданных контролируется платформой – вы не сможете создать двух справочников с одинаковым именем. Таким образом, ссылка является уникальной сущностью в пределах базы данных и это свойство (уникальности) обеспечивается двумя составляющими.

Теперь, для полноты картины, поговорим о том, что такое GUID.  По данным сайта wikipedia.org:

«GUID (Globally Unique Identifier) — статистически уникальный 128-битный идентификатор. Его главная особенность — уникальность, которая позволяет создавать расширяемые сервисы и приложения без опасения конфликтов, вызванных совпадением идентификаторов. Хотя уникальность каждого отдельного GUID не гарантируется, общее количество уникальных ключей настолько велико (2128 или 3,4028×1038), что вероятность того, что в мире будут независимо сгенерированы два совпадающих ключа, крайне мала. Тем не менее на системе Windows'95 GUID идентификаторы закладки свойств для ярлыка запуска DOS программ(.pif) и программы Zip Magic совпадали.» 
То есть, новые GUIDы получаются генерацией случайных чисел в диапазоне, сопоставимом с количеством атомов во Вселенной (на самом деле в платформе 1С используется другой способ формирования GUIDов, но пока для простоты давайте не будем на этом заостряться, подробнее об этом в конце публикации).

Таким образом, мы теперь понимаем, что при создании нового элемента объектного типа, в  платформе 1С запускается специальный генератор случайных чисел и получается GUID, который и записывается в качестве УИДа ссылки.

Может ли в базе 1С существовать два объекта с одинаковыми уникальными идентификаторами?  Да,  теоретически могут, но не в одной таблице (не в одном типе метаданных).  То есть,  мы можем иметь, например, элемент справочника «Номенклатура» и элемент справочника «Контрагенты» с одинаковым УИД и это нормально (на работоспособности системы это не скажется).

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

С теорией мы разобрались и теперь проведем небольшой эксперимент. Развенчаем "миф" о невозможности приведения системы в прежнее состояние после удаления объекта ссылочного типа. Использовать будем исключительно средства платформы 1С.

Во вложении пример обработки (для 8.2) с процедурой "УдалитьВосстановитьЭлемент", которая сначала удаляет элемент справочника по передаваемой ссылке, а потом создает новый такой же элемент (для простоты предполагается, что справочник не содержит табличных частей).  При этом, после удаления, ссылки на  элемент становятся "битыми" (объект не найдент...), а после воссоздания опять становятся "нормальными".         

Теперь немного о практическом применении  полученных знаний. Всем известно такое явление, как «Объект не найден..», которое как известно возникает при удалении объектов без контроля ссылочной целостности.  При этом, в структуре надписи «Объект не найден …» содержится  GUID удаленной ссылки. Вот пример соответствия отображения "битой ссылки" и GUIDа этой ссылки:

Объект не найден (48:b3e2001617ec3f2a11e1912c787ec129)
787ec129-912c-11e1-b3e2-001617ec3f2a:

Здесь видно, что структура отображения ссылки и GUID соответствуют друг другу, но не совпадают. Мы сейчас не будем на этом  останавливаться, скажем только, что восстановить «битую» ссылку можно и этому посвящен ряд отдельных публикаций, например вот эта: Реанимация битых ссылок

Анализируя XML файлы обмена, мы так же можем встретить знакомые уже GUIDы, которые можно в случае необходимости изменять  (такие задачи конечно же редки, но иногда могут встретиться).

Так же, иногда встречаются задачи, когда нам нужно создать и записать сразу два элемента справочника, где один элемент одновременно является владельцем другого и ссылается на него (например, элемент справочника "Номенклатура" с реквизитом "Основная единица измерения" с типом справочник "Единицы измерения", который в свою очередь подчинен номенклатуре).

Используя конструкции:

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

                НоваяСсылка = Справочники[ИмяМетаданных].ПолучитьСсылку(УИД);

                НовыйЭлемент = Справочники[ИмяМетаданных].СоздатьЭлемент();

                НовыйЭлемент.УстановитьСсылкуНового(НоваяСсылка);

мы можем организовать запись каждого из элементов  за один раз.

В задачах обмена данными с помощью конфигурации «Конвертация данных», мы настраиваем соответствие типов в базах источника и приемника и в качестве метода синхронизации можем указать – «По внутреннему идентификатору объекта источника». Здесь «внутренний идентификатор» не что иное как УИД передаваемой ссылки.  Но, так как только УИДа  для однозначной идентификации объекта недостаточно, передается еще и информация о типе данных приемника, например «СправочникСсылка.Склады», которая используется для поиска нужного элемента (или создания нового). При этом, новые элементы в базе приемника создаются с УИДами базы источника. И здесь возможна ситуация, когда, например, при миграции одного документа источника в пару документов приемника  (приходная накладная из базы источника загружается в пару документов приходная накладная и приходный ордер приемника), УИДы у создаваемой в приемнике пары документов будут одинаковыми и равны УИДу документа в базе источника. Как мы уже говорили выше, это вполне нормально.

Замечу, что использовать  данные механизмы нужно крайне осторожно, помня о возможных последствиях.

В начале публикации мы для упрощения понимания основной идеи мы считали, что GUIDы формируются как случайные числа в очень большом диапазоне, к тому же сама идея своей красотой заслуживает к себе внимания. Но, как уже упоминалось ранее, на самом деле в случае платформы 1С это не так - при формировании GUIDов используется время, о чем говорит "1" в первой позиции третьей секции (при случайной генерации на этой позиции "4"):

787ec129-912c-11e1-b3e2-001617ec3f2a

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

Получить дату создания документа или элемента справочника (по UID)

Подробнее о GUIDах можно прочитать здесь:

Руководство по GUID. Часть 1

Руководство по GUID. Часть 2

Руководство по GUID. Часть 3

Скачать файлы

Наименование Файл Версия Размер
Пример работы с УИДами

.epf 6,98Kb
19.10.19
280
.epf 6,98Kb 280 Скачать

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо развёрнутое
Свернуть все
1. vcv 87 06.05.12 09:19 Сейчас в теме
объекта объектного типа

Гм. А объекты необъектного типа бывают?
Не путайте помянутых новичков терминологией. Объект может быть переменной объектного типа или экземпляром объектного типа. Но не бывает объектов объектного типа.
jONES1979; +1 Ответить
2. TSSV 06.05.12 11:33 Сейчас в теме
(1) vcv, Спасибо за проявленный интерес к публикации и заботу о новичках, которую полностью разделяю.
Позволю себе цитату с ресурса http://v8.1c.ru/:
"При манипулировании данными, хранящимися в базе данных 1С:Предприятия, зачастую используется объектный подход. Это значит, что обращение (чтение и запись) к некоторой совокупности данных, хранящихся в базе, происходит как к единому целому. Например, используя объектную технику, можно манипулировать данными справочников, документов, планов видов характеристик, планов счетов и т.д.

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

Эта ссылка также хранится в поле базы данных, вместе с остальными данными объекта. Кроме того, ссылка может быть использована как значение какого-либо поля другого объекта. Например, ссылка на объект справочника Контрагенты может быть использована как значение соответствующего реквизита документа ПриходнаяНакладная."
И все же думаю Вы правы - вместо "объектного типа" здесь лучше использовать формулировку "ссылочного типа" - так будет понятней о чем идет речь.
3. WKBAPKA 220 12.05.12 13:01 Сейчас в теме
если честно, я не понял про уникальность... если УИД уникальный в пределах вселенной, т.е. вероятность совпадения невероятно мала, то фактически гарантируется уникальность ссылок в пределах всех информационных баз... это, конечно, если 1С придерживается алгоритма генерации гуида
4. TSSV 14.05.12 09:39 Сейчас в теме
(3) WKBAPKA, если мы исходим из того, что 1С придерживается (это конечно не документировано), то УИД уникальный в момент его создания, но, мы можем искусственно записать в базу один и тот же УИД в разные объекты разного типа (например, в элемент справочника "Номенклатура" и элемент справочника "Единицы измерения" - такие вещи могут встретиться при добавлении данных с помощью загрузки с использованием КД). И тогда УИД уже не уникален в пределах базы, но ссылки разные, так как ссылка это тип данных плюс УИД.
5. WKBAPKA 220 14.05.12 14:53 Сейчас в теме
наверное так оно и есть... с одной стороны... а с другой, интересно, получится ли установить две одинаковые ссылки на один и тот же тип данных...
7. Sherlock_kmw 26 17.05.12 14:11 Сейчас в теме
(5) WKBAPKA, нет не получится. в каждой из таблиц базы UUID является ключевым полем. отсюда и невозможность поиметь две номенклатуры с одним UUID
AleksR; TSSV; +2 Ответить
6. dumal 17.05.12 10:04 Сейчас в теме
Замечательная статья. Спасибо Вам за нее
8. Psylocibine 20.05.12 22:48 Сейчас в теме
А можно ли подменить UUID конкретного объекта?
9. TSSV 21.05.12 10:07 Сейчас в теме
(8) Psylocibine, Подменить UUID конкретного объекта можно, но нужно помнить о ссылках на объект - они станут "битыми". Поэтому решение может быть следующим - создаем копию объекта с нужным УИДом, с помощью универсальной обработки "Поиск и замена значений" заменяем ссылки старого объекта на новый, удаляем старый объект. Так же мне приходилось решать задачу перевода метода синхронизации ряда справочников (контрагенты, номенклатура и пр.) с синхронизации по коду на синхронизацию по внутреннему идентификатору в работающей УПП (обмен был с БП) - то есть необходимо было массово заменить УИДы у большого количества элементов. Я поступил следующим образом - сделал полную выгрузку ИБ штатными механизмами УПП - "Выгрузка данных в идентичную конфигурацию" , в сформированном XML файле выгрузки сделал замену GUIDов (предварительно сформировав файл соответствия GUIDов), после чего загрузил переработанный файл выгрузки в пустую базу. Файл выгрузки редактировался как обычный текстовый файл, в каждой строке которого происходил поиск заменяемого GUIDа среди набора подлежащих замене и собственно сама замена. Метод себя оправдал - на операцию ушло несколько часов (не считая подготовки конечно) и в дальнейшем проблем с обменом не возникало.
Tangram; bashinsky; eruil; Kosstikk; +4 Ответить
10. lsp71 19.06.12 11:36 Сейчас в теме
Хорошая статья. И написана понятным языком.
11. petrovaUL 10.07.12 06:12 Сейчас в теме
12. bforce 443 02.09.12 11:51 Сейчас в теме
Может ли в базе 1С существовать два объекта с одинаковыми уникальными идентификаторами? Да, теоретически могут, но не в одной таблице (не в одном типе метаданных). То есть, мы можем иметь, например, элемент справочника «Номенклатура» и элемент справочника «Контрагенты» с одинаковым УИД и это нормально (на работоспособности системы это не скажется).

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

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

При условии, конечно, что вы будете использовать внутренние механизмы для генерации УИДов.
21. AlexO 128 18.07.14 09:51 Сейчас в теме
(12) bforce,
Вот здесь написано иначе

Страничка удалена с ИТС.
13. Lo1jke 21.08.13 10:22 Сейчас в теме
Спасибо, очень помоги, как раз занимался переносом XML нетипизированной партянки и нужно было насильно присваивать ГУИД.
14. TSSV 21.08.13 13:21 Сейчас в теме
(13) Lo1jke, (10) рад что пригодилось, спасибо за отзывы!
Вот еще на эту тему: http://infostart.ru/public/192055/
15. volconok27 34 27.09.13 07:58 Сейчас в теме
Отличная статья. Как раз кстати. Спасибо
16. chmv 05.11.13 16:27 Сейчас в теме
17. MaiorovYury 10 01.04.14 11:18 Сейчас в теме
18. AlexO 128 18.07.14 09:20 Сейчас в теме
(0)
При этом, в структуре надписи «Объект не найден …» содержится GUID удаленной ссылки.

Это логично, т.к. платформа натыкается на ссылку, получить которую не может, и генерирует на основе неё - ошибку "Объект не найден" с указанием "переработанной" исходной ссылки.
19. AlexO 128 18.07.14 09:31 Сейчас в теме
(0)
Итак, миф развенчан, но признаем, что он был полезен нам в начале пути.

Вы ничего не развенчали, а еще больше запутали новичков, для которых, якобы, все и "развенчивали".
Вы гарантируете, что после удаления ссылки те данные, на которые она ссылалась - осталось в целости и сохранности? Нет.
Вы гарантируете, что все подчиненные объекты "внутри" удаленного - остались на месте? Нет.
Так называемое "восстановление", да еще и громко названное
приведения системы в прежнее состояние после удаления объекта ссылочного типа

- не более чем создание и подгонка новых объектов под старые (битые) ссылки, а не восстановление старых объектов. Старые (и их содержимое) - потеряны навсегда.
А хотите "обмануть" систему - да пожалуйста, не надо ничего изобретать: создаете новый объект, удаляете старую ссылку, заменяете все старые - на новые.
Вуаля, ссылки восстановлены!
Т.е. статья написана "умно", но много воды, напущено тумана (для умности статьи?), и, главное, выводы сделаны совершенно неправильные (или двусмысленные - видимо, сам не разобрался).
34. DeniskaRediska 23.05.20 19:31 Сейчас в теме
(19)
А хотите "обмануть" систему - да пожалуйста, не надо ничего изобретать: создаете новый объект, удаляете старую ссылку, заменяете все старые - на новые.
Как раз этого делать и не надо, если создать объект со старым "GUID". Делая минимальные действия, можно решить проблему более качественно. естественно "старый объект" надо создавать с всеми его реквизитами.
20. AlexO 128 18.07.14 09:39 Сейчас в теме
(0)
Может ли в базе 1С существовать два объекта с одинаковыми уникальными идентификаторами? Да, теоретически могут, но не в одной таблице (не в одном типе метаданных).

Это сугубо Ваши домыслы.
1С ищет объект по ссылке, а не по "ссылка+тип данных", и что она должна вернуть, если по ссылке - два объекта?
Была теория, что 1С "зашифровала" тип даннных в ссылке, но пока она не получила ни подтверждения, ни полного отпровержения, т.к. ссылки формируются "подряд" (документ - ссылка №1, справочник - ссылка №2, документ - ссылка №3, ссылки по-порядку, последовательно, формируются), однако, и опровержение "зашифрованности" не получено от 1С.
22. AlexO 128 18.07.14 10:03 Сейчас в теме
(0)Tsaregorodtsev,
создавать новую ссылку:
УИД = Новый УникальныйИдентификатор();

НоваяСсылка = Справочники[ИмяМетаданных].ПолучитьСсылку(УИД);

НовыйЭлемент = Справочники[ИмяМетаданных].СоздатьЭлемент();

НовыйЭлемент.УстановитьСсылкуНового(НоваяСсылка);


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

НовыйЭлемент = Справочники[ИмяМетаданных].СоздатьЭлемент();

НоваяСсылка = Справочники[ИмяМетаданных].ПолучитьСсылку(УИД);

Все.
И не надо тыркать по десять раз ссылку туда-сюда.
23. AlexO 128 18.07.14 10:09 Сейчас в теме
(0)Tsaregorodtsev,
А как ссылка соотносится с уникальным идентификатором (далее УИД)

Это UUID:
Объект не найден (48:b3e2001617ec3f2a11e1912c787ec129)


Это GIUD (назван "УИД" в 1С):
787ec129-912c-11e1-b3e2-001617ec3f2a:

А у вас туман один клубится в статье.
24. pavelyar 23.12.14 16:17 Сейчас в теме
Нет штатного средства поиска по GUID в конфиграциях и это очень плохо,под УФ тоже обработок не найти это беда...
25. AlexO 128 04.06.15 10:05 Сейчас в теме
(24) pavelyar,
Нет штатного средства поиска по GUID в конфиграциях
GUID как таковой вообще не используется в платформе 1С. Ссылки хранятся в формате UUID. Что и подтвержадет ошибка "Объект не найден (48:b3e2001617ec3f2a11e1912c787ec129)".
26. Videon 14.03.18 18:27 Сейчас в теме
Мне кажется, что "Ссылка - это тип данных," взрывает мозг новичкам, ибо это не тип данных. Вот выдержка с сайта 1С: "Ссылка - это значение, однозначно характеризующее объекты базы данных (элементы справочников, документы и так далее).
Для хранения ссылок предназначены типы встроенного языка СправочникСсылка.<имя>, ДокументСсылка.<имя> и так далее."
Ссылка - это свойство объекта БД (например, экземпляра справочника Номенклатура). Тип данных этого свойства = СправочникСсылка.<Имя справочника> (например, СправочникСсылка.Номенклатура). То же самое есть в Синтакс-помощнике.
Так или не так?
27. TSSV 1017 15.03.18 06:33 Сейчас в теме
Добрый день! Про новичков - прежде всего я себя имел ввиду, никого не хотел обидеть, если речь об этом. По поводу остального контента - спасибо, теперь буду знать.
29. Big Fox 11.10.18 18:15 Сейчас в теме
GUID и UUID взаимозаменяемы
30. Adam12345678 9 06.12.19 21:50 Сейчас в теме
Здравствуйте. Вопрос к знатокам. Если мы перенесли информацию из одной базы в другую, к примеру, номенклатуру с использованием конвертации данных, оставив уникальный идентификатор одинаковым для источника и приёмника, есть ли теоретическая возможность того, что при создании нового элемента в базе приёмнике система сгенерирует уникальный идентификатор такой же как уже имеющийся, перенесенный из другой базы и тем самым "затрет" ранние данные?
31. CheBurator 3421 07.12.19 00:52 Сейчас в теме
(30) ну так сначала, наверное, в базе приемнике ищем СУЩЕСТВУЮЩИЙ элемент, если не нашли - тогда создаем... как здесь что-то может затереть?
32. TSSV 1017 07.12.19 01:34 Сейчас в теме
(30) Нет, этого не может произойти, так как ссылка - кластерный индекс таблицы справочника на уровне СУБД, элемент с существующим в базе УИДом ссылки не будет записан. Можете проверить с помощью конструкции:

УИД = Новый УникальныйИдентификатор(ЗаданныйУИД);
НоваяСсылка = Справочники[ИмяМетаданных].ПолучитьСсылку(УИД);
НовыйЭлемент = Справочники[ИмяМетаданных].СоздатьЭлемент();
НовыйЭлемент.УстановитьСсылкуНового(НоваяСсылка);
НовыйЭлемент.Записать();
33. Adam12345678 9 09.12.19 10:48 Сейчас в теме
35. vvv123f 24.05.20 13:35 Сейчас в теме
Спасибо за статью и подробный разбор темы.
ipoloskov; TSSV; +2 Ответить
Оставьте свое сообщение

См. также

Некоторые полезные обработки для администрирования и отладки обменов

Поиск данных Распределенная БД (УРИБ, УРБД) Информационная безопасность v8 1cv8.cf Абонемент ($m)

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

1 стартмани

25.10.2012    34967    28    Артано    28    

Помощник работы с идентификаторами объектов

Инструментарий разработчика v8 1cv8.cf Абонемент ($m)

Инструмент для расширенного анализа идентификаторов объектов.

2 стартмани

24.01.2020    6418    22    YPermitin    25