Расшифровка представления битой ссылки. Как перевернуть ГУИД. UUID to GUID и обратно…



Немножко о UUID и GUID и их взаимосвязи.
Когда мы встречаемся с битой ссылкой в Предприятии 8, иногда возникает необхоимость создать объект с её идентификатором. Однако строка идентификатора и текст битой ссылки в предприятии различаются, но легко восстановить одно зная другое.

Когда мы встречаемся с битой ссылкой в Предприятии 8, иногда возникает необхоимость создать объект с её идентификатором. Однако строка идентификатора и текст битой ссылки в предприятии различаются, но легко восстановить одно зная другое.

Определимся с обозначениями:

UUID — это подстрока, которую мы видим в режиме предприятия в представлении битой ссылки

                                                            Объект не найден (N:UUID);

где N — номер таблицы таблицы в базе данных, например, _ReferenceN — это таблица справочника в базе данных.

Для документа такая таблица будет иметь имя _DocumentN, разглядеть имена этих таблиц можно, если имеется клиент-серверный вариант информационной базы 1С:Предприятия (см. рис.).

GUID — это строка, которую мы используем для создания объекта «УникальныйИдентификатор»:

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

Вот две простые функции, которые легко составить по предложенному рисунку:

//////////////////////////////////////////////////

Функция UUIDToGUID(UUID) Экспорт

    Возврат Прав(UUID, 8) + «-» + Сред(UUID, 21, 4) + «-» + Сред(UUID, 17, 4) + «-» + Лев(UUID, 4) + «-» + Сред(UUID, 5, 12);

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

//////////////////////////////////////////////////

Функция GUIDToUUID(GUID) Экспорт

    Возврат Сред(GUID, 20, 4) + Прав(GUID, 12) + Сред(GUID, 15, 4) + Сред(GUID, 10, 4) + Лев(GUID, 8);

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

//////////////////////////////////////////////////

О типе битой ссылки. (см. комментарий от [QUOTE]ediks 23.11.11 10:25[/QUOTE] //infostart.ru/public/83378/)

Исходя из смысла числа N в строке битой ссылки Объект не найден (N:UUID), это число можно считать идентификатором типа.

Для определения типа можно заполнить заранее, например, соответствие (Число N — ТипОбъекта). А N определять из представления битой ссылки.

Вот функции модуля обработки для определения типа (всего одна экспортная функция для рашифровки битой ссылки):

 // Представление битой ссылки: Объект не найден (TypeID:UUID)
 // TypeID — идентификатор типа
 // UUID — глобальный идентификатор
 
Функция СтруктураПредставленияБитойСсылки(ПредставлениеБитойСсылки)

     // Ищем позицию скбоки
    
Поз1 = Найти(ПредставлениеБитойСсылки, «(«);
    
Поз2 = Найти(ПредставлениеБитойСсылки, «:»);

     Если Поз1 > 0 И Поз2 > 0 И Поз2 > Поз1 Тогда
        
TypeID = Сред(ПредставлениеБитойСсылки, Поз1 + 1, Поз2 Поз1 1);
        
UUID = Сред(ПредставлениеБитойСсылки, Поз2 + 1, 32);
     Иначе
        
TypeID = «»;
        
UUID = ПредставлениеБитойСсылки;
     КонецЕсли;

     Возврат Новый Структура(«TypeID, UUID», TypeID, UUID);

 КонецФункции
 // Возвращает соответствие: Идентификатор типа (строка) — Строка определения типа
 
Функция СоответствиеИдентификаторовТипов()

     Соответствие = Новый Соответствие;

     МассивКоллекцийМенеджеровСсылочныхОбъектов = Новый Массив;
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(Справочники);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(Документы);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(ПланыВидовХарактеристик);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(ПланыСчетов);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(БизнесПроцессы);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(Задачи);
    
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(ПланыОбмена);

     Для Каждого КоллекцияМенеджеровСсылочныхОбъектов Из МассивКоллекцийМенеджеровСсылочныхОбъектов Цикл
         Для Каждого
МенеджерСсылоногоОбъекта Из КоллекцияМенеджеровСсылочныхОбъектов Цикл
            
БитаяСсылка = МенеджерСсылоногоОбъекта.ПолучитьСсылку(Новый УникальныйИдентификатор);
            
Соответствие.Вставить(СтруктураПредставленияБитойСсылки(Строка(БитаяСсылка)).TypeID, СтрЗаменить(БитаяСсылка.Метаданные().ПолноеИмя(), «.», «Ссылка.»));
         КонецЦикла;
     КонецЦикла;

     Возврат Соответствие;

 КонецФункции
 // Возвращает структуру: «TypeID, UUID, Тип, GUID»
 
Функция РасшифровкаПредставленияБитойСсылки(ПредставлениеБитойСсылки) Экспорт

     Если мСоответствиеИдентификаторовТипов = Неопределено Тогда
        
мСоответствиеИдентификаторовТипов = СоответствиеИдентификаторовТипов();
     КонецЕсли;

     СтруктураПредставления = СтруктураПредставленияБитойСсылки(ПредставлениеБитойСсылки);

     СтрокаТипа = мСоответствиеИдентификаторовТипов[СтруктураПредставления.TypeID];
     Если
СтрокаТипа = Неопределено Тогда
        
СтрокаТипа = «Неопределено»;
     КонецЕсли;

     Возврат Новый Структура(«TypeID, UUID, Тип, GUID», СтруктураПредставления.TypeID, СтруктураПредставления.UUID, СтрокаТипа, UUIDToGUID(СтруктураПредставления.UUID));

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

 

24 Comments

  1. Angeros

    Ну что, так то в изображении все есть все понятно. Где эту науку можно применять то?

    Reply
  2. nalivai-chai

    В РИБах бывают такие проблемы, что из-за сбоев, вдруг исчезает документ или элемент справочника… на его месте остается битая ссылка. В отчетах или реквизитах справочников, документов и проч. можно её увидить. при этом она будет в виде <Объект не найден> (N:GUID). И иногда самым простым выходом бывает быстренько создать элементик идентификатором UUID и заполнить его реквизиты ручками или программно.

    Reply
  3. warenic

    Думаю, для 8-ки нужно иметь такой инструментик. В 7.7 с такой хренью часто сталкивался. Особенно в РИБ. Но там механизм преобразования немного другой из 10-ичного в 36-ричный (и наоборот).

    Reply
  4. sa1m0nn

    Сам столкнулся недавно, когда выполнял ТИИ. Конфигуратор выдал ID, по которому нужно было найти ссылку на документ. Минут 20 передвигал буковки в табло, прежде чем допёрло, что к чему 🙂

    Reply
  5. ninch

    Большое спасибо за информацию. мне вот другое интересно — откуда информацию взял?:) Ссылку можно?

    Reply
  6. Defm

    Теоретическую часть оценил, спасибо. Проблема при восстановлении битой ссылки в основном заключается в определении типа ее значения, а не в создании самого объекта..

    Reply
  7. gortol

    я сам подобное писал, когда надо было UUID в таблицах SQL заполнить в таблицах (где поле ссылки на другой справочник не заполнено было)

    вот именно для этого она полезна…

    Reply
  8. ediks

    (6) В комментах к публикации http://infostart.ru/public/83378/ есть код для определения типа объекта. Он же вставлен в обработку.

    Reply
  9. cool.vlad4

    в sql я делал такую ф-цию

    CREATE function [dbo].[sp_getid] (@id binary(16))

    returns char(36)

    as

    begin

    declare @unidentifier char(36)

    declare @charvalue char(36)

    select @unidentifier = CONVERT(char(36),CAST(@id as uniqueidentifier))

    select @charvalue =

    right(@unidentifier, 8)

    + substring(@unidentifier,24,5)

    + substring(@unidentifier,19,5)

    + ‘-‘

    + substring(@unidentifier,7,2)

    + substring(@unidentifier,5,2)

    + ‘-‘

    + substring(@unidentifier,3,2)

    + left(@unidentifier,2)

    + substring(@unidentifier,12,2)

    + substring(@unidentifier,10,2)

    + substring(@unidentifier,17,2)

    + substring(@unidentifier,15,2)

    return ( @charvalue )

    end

    Конвертирует для удобства идентификаторы в УИД,

    (через ADO можно например писать запрос SELECT [dbo].[sp_getid]([_IDRRef])) FROM

    подобным же образом можно сделать и ф-ции в публикации

    Reply
  10. Artemuch2

    Вот спасибо теперь с обменами разбираться гораздо проще станет

    Reply
  11. ms200999

    Спасибо. Как раз сегодня с утра с идентификаторами развлекаюсь, так что публикация ваша как раз вовремя.

    Reply
  12. AlexO

    (3) warenic,

    Вот именно:

    «Проблема при восстановлении битой ссылки в основном заключается в определении типа ее значения, а не в создании самого объекта..»

    а не

    (2) nalivai: «В РИБах бывают такие проблемы, что из-за сбоев, вдруг исчезает документ или элемент справочника… на его месте остается битая ссылка»

    Если там в типах данных пятнадцать документов — ну и какой из них Вы восстанавливать будете??

    Боюсь, что создавая «типа ссылку на реальный документ», и не разбираясбь в каждом конкретном случае, что там и зачем было, Вы обманете сам себя..

    не говоря уже о том, что потом «по запросу» по этой ссылке понадобится инфо, и в ЛУЧШЕМ СЛУЧАЕ! возникнет ошибка (хотя б сообщение будет, и можно будет разобраться), а обычно (зная нелюбовь 1С ко всяческим проверкам типов данных/вводимых значений/получаемых результатов) — пролетит со свостом, и потом будете полгода искать ошибку неправильного формирования отчетности…

    хотя — я теперь ничему не удивляюсь: нынешнее поколение плевать на все хотело, и работает «on-demand»: случилась попа — забегали/поувольнялись, не случилась — сидят на попе ровно…

    Reply
  13. nalivai-chai

    Проблема определения типа битой ссылки — это решаемая проблема. Если мы имеем «битую ссылку» при выполнении программы, то её тип определяется так же как и тип «небитой ссылки». Если мы имеем строковое представление битой ссылки, то определение её типа решено в данной публикации, есть и другие решения на Infostart’е.

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

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

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

    Хороший вариант — восстановление битых ссылок из резервной базы данных.

    ms200999 пишет:

    не говоря уже о том, что потом «по запросу» по этой ссылке понадобится инфо, и в ЛУЧШЕМ СЛУЧАЕ! возникнет ошибка (хотя б сообщение будет, и можно будет разобраться),

    Я не предлагал использовать генератор случайных чисел для заполнения реквизитов при восстановлении объекта.

    Reply
  14. warenic

    (12) AlexO,


    Если там в типах данных пятнадцать документов — ну и какой из них Вы восстанавливать будете??

    С восьмеркой только-только начинаю разбираться, категоричных заявлений пока делать не буду.

    В 7-ке тип, и вид внутренний идентификатор описывает однозначно. Более того, в нем содержится информация в какой именно базе РИБ он создан. Устанавливается это не по типу поля, где битая ссылка появилась, а из содержания: какой именно <объект не найден>. В 8-ке не так???

    Reply
  15. nalivai-chai

    Именно так: по содержанию поля с битой ссылкой, а не по типу поля.

    Reply
  16. hr7095

    Объект не найден (N:GUID); Если сравнить с публикацией О типе битой ссылки. (см. комментарий от 23.11.11 http://infostart.ru/public/83378/), то у кого то перепутан GUID с UUID.

    ИМХО: По идее должно быть так: Объект не найден (N:UUID);

    Reply
  17. nalivai-chai
    hr7095 пишет:

    ИМХО: По идее должно быть так: Объект не найден (N:UUID);

    По какой идее? По подробнее идею!

    Я рассуждал так: удобнее обозначение N:GUID, так как UUID — используется в документации 1C это объект УникальныйИдентификатор, который мы записываем как?… Вот так, c дефисами: hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh.

    Хотя, можно и наоборот посмотреть на вопрос.

    Для GUID во многих других программных продуктах используется маска: hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh. И для получения объекта UUID в 1C используется строка GUID, тогда это будет выглядеть так: UUID = Новый UUID(GUID).

    Вопрос спорный, и не понятно стоит ли он спора вообще.

    Тут нужно голосование и статистические данные))))

    Reply
  18. nalivai-chai

    (16) hr7095, Да, вы правы. Спасибо.

    Reply
  19. AlexO

    (14) хорошо, вы расшифровываете ссылку и находите в архиве периферийной базы удаленный документ.

    Тогда вот пример.

    В основной базе одним из менеджеров формируется заказ и отсылается при очередном обновлении на периферию.

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

    В основной базе первый менеджер передумал и удалил свой заказ (клиент что говорится «отвалил»).

    РИБ добросовестно переносит изменения на периферию и тоже удаляет его в периферийной базе (здесь срабатывает механизм обхода запретов удаления ссылочных объектов при обмене).

    Вот тут-то и подкладывает нам всем 1С большу-у-ую РИБ.

    Т.к. именно по описанной выше схеме и происходит «потеря» доков при обменах РИБ.

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

    Вы видите <Объект не найден>, быстро находите по ссылке объект, восстанавливаете его, и, счастливый, ставите точку.

    А что вы нашли на самом деле? Вы нашли и восстановили объект в периферийной базе, который к основной базе не имеет уже никакого отношения (как по учету — в основной он удален вовсе, так и по целостности БД — ссылки-то в базах в каждой свои, уникальные).

    И дальше? А дальше — то самое действие, которое нужно было сделать с самого начала и не заморачиваться с восстановлением ссылок: звонить в основной офис, искать менеджера этого дока/контрагента, и выяснять, какова дальнейшая судьба удаленного дока, и что делать с уже созданными зависимыми доками.

    А это, как вы понимаете, полностью исключает применение каких-либо обработок по расшифровке ссылок и т.д.

    О чем я и писал ранее.

    Reply
  20. nalivai-chai

    (19) AlexO,

    Пример показательный. Если нужно объяснить, откуда берутся «плановые» битые ссылки, которые неизбежны, и бороться с ними бессмысленно.

    Даже в идеальной РИБ, при идеальном функционировании, такие битые ссылки могут возникнуть. И это нормально.

    Ничего восстанавливать или удалять тогда, чтобы избавиться от битой ссылки, не нужно.

    Далеко не все РИБ идеальны и условия их выполнения тоже.

    Тогда может что-то удалиться, то что не должно удаляться в том самом режиме, когда ничего не контролируется.

    Подобные обработки нужны не для пользователей и, тем более, не для манагеров.

    И плевать, если они видят битую ссылку и у них голова кружится.

    Это для тех людей, которые знают, что: «Вот эта хрень исчезла, а должна была остаться.»

    И нужно разобраться «Почему?».

    Reply
  21. AlexO

    (20)

    ну вот, сама подоплека идеи понятна и принимается ))

    поддерживаю….

    а вот от самой проблемы обмена — через битую ссылку ушли в сторону вместе с обработкой.. мое мнение ))

    Reply
  22. ligailnet

    Интересная методика. я использовал обработку при настройке соответствия баз.

    Reply
  23. tarasenkov

    В Функции СоответствиеИдентификаторовТипов() следует добавить:

    МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(ПланыВидовРасчета);

    Reply
  24. Pavean

    Есть у меня база которая при ТиИ выдаёт следующее:

    Проверка логической целостности. РегистрСведений.БИТ_CRM_НастройкиПользователей.Измерение.Настройка ПользовательПользователь:<Объект не найден> (614:976f5ec7ad3dda5c49973d22033b18fa)

    ОбщийРеквизит.ОбластьДанных = 0

    Объект, на который ссылается значение, отсутствует.

    Так вот если рассчитать код типа по этой статье или так как в комментариях у ediks, то получается что типа с кодом 614 не существует. Если соответствующий гуид подсунуть в обработку «Администратор1С» от СтепБайСтеп то оказывается что это ПВХ «Настройки пользователей». Он имеет код 606. А что тогда 614? Где Я туплю?

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *