Как определить тип метаданных и получить ссылку из строки вида ЗначениеНеНайдено

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе в 1С разработчики и администраторы нередко сталкиваются со строковыми представлениями битых ссылок вида «ЗначениеНеНайдено <132:bb530015170eeeb611dd97911478ed0e>» или «<Объект не найден> (132:bb530015170eeeb611dd97911478ed0e)». Подобные ситуации возникают в результате удаления объектов без контроля ссылочной целостности (прямым методом Удалить() или запросами в СУБД), сбоев при синхронизации данных или некорректного переноса между базами.

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

Структура внутреннего представления битой ссылки

Проанализируем внутреннее устройство строки 132:bb530015170eeeb611dd97911478ed0e:

  1. Числовой префикс (132) — это внутренний идентификатор таблицы базы данных. В реляционной СУБД (например, MS SQL или PostgreSQL) таблица справочника именуется как _Reference132, а документа — _Document132.
  2. 32-символьная шестнадцатеричная строка (HEX) — это упакованный 128-битный глобальный уникальный идентификатор (GUID) объекта, записанный платформой 1С в специфическом порядке байтов (байт-своп).

Шаг 1. Определение объекта метаданных по номеру таблицы

Чтобы быстро и гарантированно сопоставить номер 132 с именем метаданных без медленного ручного перебора всех объектов дерева конфигурации, воспользуемся методом ПолучитьСтруктуруХраненияБазыДанных(). Этот метод доступен на стороне сервера и возвращает таблицу значений с описанием всех физических таблиц СУБД.

Посмотрим на пример функции, которая находит имя метаданных по номеру таблицы:


Функция ОпределитьИмяМетаданныхПоНомеруТаблицы(НомерТаблицы) Экспорт
    СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных();
    
    // Ищем соответствие для справочников и документов
    ПрефиксСправочника = "_Reference" + Формат(НомерТаблицы, "ЧГ=0");
    ПрефиксДокумента   = "_Document" + Формат(НомерТаблицы, "ЧГ=0");
    
    Для Каждого СтрТаблица Из СтруктураХранения Цикл
        Если ВРег(СтрТаблица.ИмяТаблицыХранения) = ВРег(ПрефиксСправочника)
            Или ВРег(СтрТаблица.ИмяТаблицыХранения) = ВРег(ПрефиксДокумента) Тогда
            Возврат СтрТаблица.ИмяТаблицы; // Например, "Справочник.СтатьиЗатрат"
        КонецЕсли;
    КонецЦикла;
    
    Возврат Неопределено;
КонецФункции

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

Шаг 2. Преобразование шестнадцатеричной строки в канонический GUID

Платформа 1С сохраняет уникальные идентификаторы в СУБД с перестановкой групп байтов. Чтобы получить стандартный вид GUID формата XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, выполним перегруппировку символов 32-значной строки.

Разберем алгоритм преобразования:


Функция ПреобразоватьСтрокуВУникальныйИдентификатор(Стр16) Экспорт
    // Проверяем корректность длины строки
    Если СтрДлина(Стр16) <> 32 Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Выполняем перестановку байтовых сегментов согласно формату 1С
    СтрGUID = Сред(Стр16, 25, 8) + "-"
            + Сред(Стр16, 21, 4) + "-"
            + Сред(Стр16, 17, 4) + "-"
            + Сред(Стр16, 1, 4)  + "-"
            + Сред(Стр16, 5, 12);
            
    Возврат Новый УникальныйИдентификатор(СтрGUID);
КонецФункции

Шаг 3. Получение ссылки и восстановление объекта

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

Рассмотрим комплексный пример: от парсинга строки до создания недостающего элемента с тем же GUID, чтобы в базе восстановились все потерянные связи:


Процедура ВосстановитьБитауюСсылку(СтрокаЗначениеНеНайдено)
    // 1. Извлекаем номер таблицы и шестнадцатеричную часть
    // Исходный формат: "132:bb530015170eeeb611dd97911478ed0e"
    СтрОчищенная = СтрЗаменить(СтрокаЗначениеНеНайдено, "ЗначениеНеНайдено", "");
    СтрОчищенная = СтрЗаменить(СтрОчищенная, "<", "");
    СтрОчищенная = СтрЗаменить(СтрОчищенная, ">", "");
    СтрОчищенная = СокрЛП(СтрОчищенная);
    
    ПозицияДвоеточия = СтрНайти(СтрОчищенная, ":");
    Если ПозицияДвоеточия = 0 Тогда
        Возврат;
    КонецЕсли;
    
    НомерТаблицы = Число(Лев(СтрОчищенная, ПозицияДвоеточия - 1));
    СтрHEX = Сред(СтрОчищенная, ПозицияДвоеточия + 1);
    
    // 2. Получаем имя метаданных и GUID
    ИмяМетаданных = ОпределитьИмяМетаданныхПоНомеруТаблицы(НомерТаблицы);
    УИД = ПреобразоватьСтрокуВУникальныйИдентификатор(СтрHEX);
    
    Если ИмяМетаданных = Неопределено Или УИД = Неопределено Тогда
        ВызватьИсключение "Не удалось распознать метаданные или идентификатор.";
    КонецЕсли;
    
    // 3. Получаем ссылку через менеджер метаданных
    // Например, для "Справочник.СтатьиЗатрат"
    МассивИмени = СтрРазделить(ИмяМетаданных, ".");
    Менеджер = Справочники[МассивИмени[1]];
    
    СсылкаНаОбъект = Менеджер.ПолучитьСсылку(УИД);
    
    // 4. Восстанавливаем элемент в базе данных, если он отсутствует
    НовыйОбъект = Менеджер.СоздатьЭлемент();
    НовыйОбъект.УстановитьСсылкуНового(СсылкаНаОбъект);
    НовыйОбъект.Наименование = "Восстановленный элемент (" + Строка(УИД) + ")";
    НовыйОбъект.Записать();
КонецПроцедуры

Альтернативные штатные способы исправления битых ссылок

Если битых ссылок в базе много и требуется массовая нормализация, проанализируем стандартные административные инструменты платформы:

  1. Тестирование и исправление информационной базы (в режиме Конфигуратора: Администрирование -> Тестирование и исправление...):

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

  2. Загрузка данных из резервной копии:

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

← На главную