В процессе работы с базами данных 1С, особенно в крупных конфигурациях вроде 1С:УПП 1.3, специалисты часто сталкиваются с появлением записей вида <Объект не найден> (138:80d70cc47a72290911e5e5ff661ce5ad). Это так называемые «битые» ссылки. Они возникают, когда в базе данных остается ссылка на объект (в регистрах, документах или других справочниках), но сам объект из соответствующей таблицы метаданных был удален.
В этой статье мы подробно разберем, как расшифровать эти данные, выяснить, к какой таблице относится идентификатор 138, и как восстановить работоспособность системы.
Первое число в скобках после текста «Объект не найден» (в нашем примере это 138) — это внутренний идентификатор типа объекта в конкретной информационной базе. Важно понимать, что этот номер не является фиксированным для всех конфигураций 1С. Он присваивается платформой динамически при обновлении конфигурации базы данных. Поэтому в одной базе 138 может быть справочником Контрагенты, а в другой — документом РеализацияТоваровУслуг.
Для того чтобы узнать, какой объект скрывается под этим номером, воспользуемся встроенными средствами платформы. Рассмотрим основной программный метод:
Проанализируем использование функции ПолучитьСтруктуруХраненияБазыДанных(). Мы можем запустить небольшой фрагмент кода во внешней обработке, чтобы найти соответствие идентификатора имени метаданных:
ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого СтрокаТаблицы Из ТаблицаСтруктуры Цикл
Если СтрокаТаблицы.ИмяТаблицыХранения = "Reference138"
Или СтрокаТаблицы.ИмяТаблицыХранения = "Document138" Тогда
Сообщить("Это объект: " + СтрокаТаблицы.ИмяТаблицы);
КонецЕсли;
КонецЦикла;
Однако более эффективным способом будет перебор коллекции метаданных для поиска соответствия по внутреннему идентификатору. Разберем, как это сделать правильно:
НужныйИдентификатор = 138;
Для Каждого МетаОбъект Из Метаданные.Справочники Цикл
Если ИнформационнаяБаза.ТипВсеСсылки().СодержитТип(Тип("СправочникСсылка." + МетаОбъект.Имя)) Тогда
// Здесь можно использовать специализированные обработки для получения ID типа
КонецЕсли;
КонецЦикла;
Для работы в 1С:УПП 1.3 (на обычных формах) наиболее мощным и удобным средством является консоль «Инструменты разработчика». Посмотрим, какие возможности она предоставляет для решения нашей задачи:
<Объект не найден>.GUID, который указан в ссылке.Если мы выяснили, что таблица 138 — это, к примеру, справочник ДоговорыКонтрагентов, и у нас есть GUID (уникальный идентификатор), мы можем «воскресить» этот объект. Это не вернет данные, которые были в нем заполнены (наименование, реквизиты), но уберет ошибку «Объект не найден» и позволит перевыбрать или дозаполнить данные. Для выполнения этой операции без написания кода можно воспользоваться обработкой для поиска и создания объектов по УИД.
Важно правильно подготовить GUID. В строке 80d70cc47a72290911e5e5ff661ce5ad байты переставлены относительно стандарта 1С. Проанализируем пример кода для восстановления:
// Приводим GUID к стандартному виду 1С
ИдентификаторСтрокой = "661ce5ad-e5ff-11e5-e509-29097a720cc4";
УникальныйИд = Новый УникальныйИдентификатор(ИдентификаторСтрокой);
// Создаем ссылку программно (на примере справочника Контрагенты)
СсылкаНаОбъект = Справочники.Контрагенты.ПолучитьСсылку(УникальныйИд);
// Проверяем, существует ли объект на самом деле
Если СсылкаНаОбъект.ПолучитьОбъект() = Неопределено Тогда
НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(СсылкаНаОбъект);
НовыйОбъект.Наименование = "Внимание! Восстановленный объект (был удален)";
НовыйОбъект.Записать();
Сообщить("Объект успешно воссоздан с исходным идентификатором.");
КонецЕсли;
Интересной особенностью GUID в 1С (особенно версии 1, основанной на времени) является возможность узнать дату его генерации. В нашем примере 80d70cc47a72290911e5e5ff661ce5ad относится именно к такому типу. Разберем, что это нам дает:
Специализированные алгоритмы разбора Time-based UUID позволяют определить, что данный объект был создан в марте 2016 года. Это критически важная информация для системного администратора: теперь мы точно знаем, из какой архивной копии базы (за какой период) можно попробовать восстановить этот объект целиком через выгрузку-загрузку XML, чтобы не просто закрыть «дыру» в данных, а вернуть потерянную информацию.
Если битых ссылок очень много, ручное восстановление становится нецелесообразным. Рассмотрим стандартный механизм 1С:
Важно: Перед выполнением Тестирования и исправления обязательно создайте резервную копию базы данных! При наличии большого количества баз задачу упрощает автоматическое архивирование и пакетное тестирование 1С в фоновом режиме.
Выясним, почему такие ситуации возникают, чтобы предотвратить их в будущем:
Объект.Удалить() вместо безопасной пометки на удаление. При непосредственном удалении платформа не всегда проверяет наличие ссылок в движениях регистров._ReferenceXXX или _DocumentXXX напрямую через SQL-запросы, минуя объектную логику 1С.Используя предложенные методы — от программного поиска через ПолучитьСтруктуруХраненияБазыДанных() до мощных инструментов вроде ИР — вы сможете эффективно контролировать целостность данных в 1С:УПП и оперативно исправлять последствия некорректного удаления объектов.