Когда мы встречаемся с битой ссылкой в Предприятии 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));
КонецФункции







Ну что, так то в изображении все есть все понятно. Где эту науку можно применять то?
В РИБах бывают такие проблемы, что из-за сбоев, вдруг исчезает документ или элемент справочника… на его месте остается битая ссылка. В отчетах или реквизитах справочников, документов и проч. можно её увидить. при этом она будет в виде <Объект не найден> (N:GUID). И иногда самым простым выходом бывает быстренько создать элементик идентификатором UUID и заполнить его реквизиты ручками или программно.
Думаю, для 8-ки нужно иметь такой инструментик. В 7.7 с такой хренью часто сталкивался. Особенно в РИБ. Но там механизм преобразования немного другой из 10-ичного в 36-ричный (и наоборот).
Сам столкнулся недавно, когда выполнял ТИИ. Конфигуратор выдал ID, по которому нужно было найти ссылку на документ. Минут 20 передвигал буковки в табло, прежде чем допёрло, что к чему 🙂
Большое спасибо за информацию. мне вот другое интересно — откуда информацию взял?:) Ссылку можно?
Теоретическую часть оценил, спасибо. Проблема при восстановлении битой ссылки в основном заключается в определении типа ее значения, а не в создании самого объекта..
я сам подобное писал, когда надо было UUID в таблицах SQL заполнить в таблицах (где поле ссылки на другой справочник не заполнено было)
вот именно для этого она полезна…
(6) В комментах к публикации есть код для определения типа объекта. Он же вставлен в обработку.
в 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
подобным же образом можно сделать и ф-ции в публикации
Вот спасибо теперь с обменами разбираться гораздо проще станет
Спасибо. Как раз сегодня с утра с идентификаторами развлекаюсь, так что публикация ваша как раз вовремя.
(3) warenic,
Вот именно:
«Проблема при восстановлении битой ссылки в основном заключается в определении типа ее значения, а не в создании самого объекта..»
а не
(2) nalivai: «В РИБах бывают такие проблемы, что из-за сбоев, вдруг исчезает документ или элемент справочника… на его месте остается битая ссылка»
Если там в типах данных пятнадцать документов — ну и какой из них Вы восстанавливать будете??
Боюсь, что создавая «типа ссылку на реальный документ», и не разбираясбь в каждом конкретном случае, что там и зачем было, Вы обманете сам себя..
не говоря уже о том, что потом «по запросу» по этой ссылке понадобится инфо, и в ЛУЧШЕМ СЛУЧАЕ! возникнет ошибка (хотя б сообщение будет, и можно будет разобраться), а обычно (зная нелюбовь 1С ко всяческим проверкам типов данных/вводимых значений/получаемых результатов) — пролетит со свостом, и потом будете полгода искать ошибку неправильного формирования отчетности…
хотя — я теперь ничему не удивляюсь: нынешнее поколение плевать на все хотело, и работает «on-demand»: случилась попа — забегали/поувольнялись, не случилась — сидят на попе ровно…
Проблема определения типа битой ссылки — это решаемая проблема. Если мы имеем «битую ссылку» при выполнении программы, то её тип определяется так же как и тип «небитой ссылки». Если мы имеем строковое представление битой ссылки, то определение её типа решено в данной публикации, есть и другие решения на Infostart’е.
Таким образом, если есть битая ссылка, то однозначно известен её тип, даже если тип данных того поля, в котором она обнаружена, имеет составной тип, в составе которого ссылочных типов более одного.
Может быть вы путаете битую ссылку с «уникальный идентификатором», который действительно абсолютно ничего не говорит о типе, это составляющая объекта, которая делает его уникальным на просторах базы данных.
С восстановлением битых ссылок, конечно, нужно быть предельно осторожным, как и с любыми нетрадиционными операциями с базой данных, не заложенными в логику программы (конфигурации). Не говоря о том, что битые ссылки, которые нужно восстановить, скорее всего уже появились как результат неосторожного обращения с базой данных, или недоработок обмена данными.
Хороший вариант — восстановление битых ссылок из резервной базы данных.
не говоря уже о том, что потом «по запросу» по этой ссылке понадобится инфо, и в ЛУЧШЕМ СЛУЧАЕ! возникнет ошибка (хотя б сообщение будет, и можно будет разобраться),
Я не предлагал использовать генератор случайных чисел для заполнения реквизитов при восстановлении объекта.
(12) AlexO,
Если там в типах данных пятнадцать документов — ну и какой из них Вы восстанавливать будете??
С восьмеркой только-только начинаю разбираться, категоричных заявлений пока делать не буду.
В 7-ке тип, и вид внутренний идентификатор описывает однозначно. Более того, в нем содержится информация в какой именно базе РИБ он создан. Устанавливается это не по типу поля, где битая ссылка появилась, а из содержания: какой именно <объект не найден>. В 8-ке не так???
Именно так: по содержанию поля с битой ссылкой, а не по типу поля.
Объект не найден (N:GUID); Если сравнить с публикацией О типе битой ссылки. (см. комментарий от 23.11.11 , то у кого то перепутан GUID с UUID.
ИМХО: По идее должно быть так: Объект не найден (N:UUID);
ИМХО: По идее должно быть так: Объект не найден (N:UUID);
По какой идее? По подробнее идею!
Я рассуждал так: удобнее обозначение N:GUID, так как UUID — используется в документации 1C это объект УникальныйИдентификатор, который мы записываем как?… Вот так, c дефисами: hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh.
Хотя, можно и наоборот посмотреть на вопрос.
Для GUID во многих других программных продуктах используется маска: hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh. И для получения объекта UUID в 1C используется строка GUID, тогда это будет выглядеть так: UUID = Новый UUID(GUID).
Вопрос спорный, и не понятно стоит ли он спора вообще.
Тут нужно голосование и статистические данные))))
(16) hr7095, Да, вы правы. Спасибо.
(14) хорошо, вы расшифровываете ссылку и находите в архиве периферийной базы удаленный документ.
Тогда вот пример.
В основной базе одним из менеджеров формируется заказ и отсылается при очередном обновлении на периферию.
На периферии менеджер на основе заказа формирует счет на оплату или заготовку реализации (считаем, что ни заказ, ни остальные документы — не проведены, иначе дисскусия о битой ссылке в проведеных доках и удаленном проведенном доке не имеет смысла — тут уж восстанавливай, не восстанавливай — все равно надо пересчитывать весь период заново).
В основной базе первый менеджер передумал и удалил свой заказ (клиент что говорится «отвалил»).
РИБ добросовестно переносит изменения на периферию и тоже удаляет его в периферийной базе (здесь срабатывает механизм обхода запретов удаления ссылочных объектов при обмене).
Вот тут-то и подкладывает нам всем 1С большу-у-ую РИБ.
Т.к. именно по описанной выше схеме и происходит «потеря» доков при обменах РИБ.
Потому как это не «распределенные данные одной базы», а «распределенные базы данных». Т.о. в каждая база «живет» независимо от других: имеет свой отдельный механизм контроля документов/ссылок, свой набор ссылок, создает свой объекты.
Вы видите <Объект не найден>, быстро находите по ссылке объект, восстанавливаете его, и, счастливый, ставите точку.
А что вы нашли на самом деле? Вы нашли и восстановили объект в периферийной базе, который к основной базе не имеет уже никакого отношения (как по учету — в основной он удален вовсе, так и по целостности БД — ссылки-то в базах в каждой свои, уникальные).
И дальше? А дальше — то самое действие, которое нужно было сделать с самого начала и не заморачиваться с восстановлением ссылок: звонить в основной офис, искать менеджера этого дока/контрагента, и выяснять, какова дальнейшая судьба удаленного дока, и что делать с уже созданными зависимыми доками.
А это, как вы понимаете, полностью исключает применение каких-либо обработок по расшифровке ссылок и т.д.
О чем я и писал ранее.
(19) AlexO,
Пример показательный. Если нужно объяснить, откуда берутся «плановые» битые ссылки, которые неизбежны, и бороться с ними бессмысленно.
Даже в идеальной РИБ, при идеальном функционировании, такие битые ссылки могут возникнуть. И это нормально.
Ничего восстанавливать или удалять тогда, чтобы избавиться от битой ссылки, не нужно.
Далеко не все РИБ идеальны и условия их выполнения тоже.
Тогда может что-то удалиться, то что не должно удаляться в том самом режиме, когда ничего не контролируется.
Подобные обработки нужны не для пользователей и, тем более, не для манагеров.
И плевать, если они видят битую ссылку и у них голова кружится.
Это для тех людей, которые знают, что: «Вот эта хрень исчезла, а должна была остаться.»
И нужно разобраться «Почему?».
(20)
ну вот, сама подоплека идеи понятна и принимается ))
поддерживаю….
а вот от самой проблемы обмена — через битую ссылку ушли в сторону вместе с обработкой.. мое мнение ))
Интересная методика. я использовал обработку при настройке соответствия баз.
В Функции СоответствиеИдентификаторовТипов() следует добавить:
МассивКоллекцийМенеджеровСсылочныхОбъектов.Добавить(ПланыВидовРасчета);
Есть у меня база которая при ТиИ выдаёт следующее:
ОбщийРеквизит.ОбластьДанных = 0
Объект, на который ссылается значение, отсутствует.
Так вот если рассчитать код типа по этой статье или так как в комментариях у ediks, то получается что типа с кодом 614 не существует. Если соответствующий гуид подсунуть в обработку «Администратор1С» от СтепБайСтеп то оказывается что это ПВХ «Настройки пользователей». Он имеет код 606. А что тогда 614? Где Я туплю?