Ситуация, когда после отката обновления конфигурации (например, 1С:Управление торговлей) пользователи начинают сталкиваться с ошибкой в функции ОбщегоНазначения.ОбъектМетаданныхПоИдентификатору, является классической проблемой для систем, построенных на базе Библиотеки стандартных подсистем (БСП). Ошибка возникает из-за того, что в справочнике ИдентификаторыОбъектовМетаданных хранятся данные, которые больше не соответствуют фактической структуре конфигурации после её возврата к старой версии.
Рассмотрим подробно причины возникновения этой проблемы и разберем пошагово методы её решения — от самых простых до радикальных программных способов.
Проанализируем механику работы БСП. Для оптимизации работы и обеспечения ссылочной целостности система не обращается к метаданным напрямую по имени в каждой операции. Вместо этого используется справочник ИдентификаторыОбъектовМетаданных. В нем каждому объекту (документу, справочнику, регистру) соответствует уникальный идентификатор (GUID).
Когда мы обновляем базу, система добавляет новые записи или обновляет существующие. Если же мы делаем откат конфигурации (путем загрузки старого файла .cf или восстановления из бэкапа только конфигурации), данные в справочнике идентификаторов остаются «от новой версии», а метаданные в конфигураторе — «от старой». Возникает конфликт: программный код ищет объект, который либо еще не существует, либо имеет другой внутренний идентификатор. Посмотрим, как это исправить.
Прежде чем приступать к манипуляциям с данными, выясним, не является ли проблема следствием кэширования. В клиент-серверном варианте работы соответствие объектов метаданных их идентификаторам может кэшироваться на стороне сервера 1С.
%ProgramFiles%\1cv8\srvinfo).snccntx и временные файлы внутри папок рабочих процессов (папки с длинными GUID-именами).Local\1C и Roaming\1C).Попробуем заставить систему выполнить штатные процедуры обновления вспомогательных данных. Для этого в 1С предусмотрен специальный ключ запуска.
Разберем, как его прописать:
/C ЗапуститьОбновлениеИнформационнойБазы (обратите внимание: ключ пишется через слеш, а параметр после /C — без пробелов в некоторых версиях, либо в кавычках).После запуска программы в пользовательском режиме должно появиться окно с прогрессом обновления. Если этого не произошло или ошибка осталась, перейдем к более глубоким методам.
В составе Библиотеки стандартных подсистем (БСП) есть специализированная внешняя обработка, предназначенная именно для таких случаев. Она называется ИнструментыРазработчика_ОбновлениеВспомогательныхДанных.epf.
Выполним следующие шаги:
Важно: Иногда штатная обработка не может завершиться из-за уже возникшей ошибки. В этом случае придется прибегнуть к программному вызову методов.
Если стандартные средства не помогают, мы можем вызвать процедуру обновления напрямую через консоль кода или внешнюю обработку. Рассмотрим пример кода, который форсирует перезапись идентификаторов:
// Вызывать в привилегированном режиме или под полными правами
ПараметрыОбновления = Справочники.ИдентификаторыОбъектовМетаданных.ПараметрыОбновленияДанных();
ПараметрыОбновления.ВыполнятьУдаление = Истина;
ПараметрыОбновления.ВыполнятьЗапись = Истина;
Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(ПараметрыОбновления);
В некоторых версиях БСП сигнатура метода может отличаться. Проанализируем более простой, но эффективный вариант вызова, который часто помогает «протолкнуть» зависшее обновление:
Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(Истина, Истина);
Передача параметров Истина, Истина (в зависимости от версии БСП) означает «Обновить существующие» и «Удалить неактуальные». Это позволяет полностью переформировать справочник в соответствии с текущей конфигурацией .cf.
Частая ошибка администраторов — попытка вручную удалить «битую» строку из справочника ИдентификаторыОбъектовМетаданных. Это приводит к тому, что ссылки на этот идентификатор в других таблицах (например, в регистре настроек или прав доступа) превращаются в <Объект не найден>. Система продолжает искать этот GUID и выдает ошибку.
Если вы уже удалили строку и получили ошибку вида Идентификатор "<Объект не найден> (126:835d2068...)" не найден в справочнике, выполните следующее:
ИдентификаторыОбъектовМетаданных с этим конкретным GUID.Пример кода для восстановления «битой» ссылки:
НовыйИдентификатор = Справочники.ИдентификаторыОбъектовМетаданных.СоздатьЭлемент();
// Устанавливаем ссылку, которую ожидает система
УникальныйИдентификатор = Новый УникальныйИдентификатор("c442c18c-a25d-11e9-835d-20689df427e9");
// Метод УстановитьСсылкуНового позволяет создать объект с конкретным GUID
НовыйИдентификатор.УстановитьСсылкуНового(Справочники.ИдентификаторыОбъектовМетаданных.ПолучитьСсылку(УникальныйИдентификатор));
НовыйИдентификатор.Наименование = "ИнойДокументПодтвержденияНДС";
НовыйИдентификатор.ПолноеИмя = "Документ.ИнойДокументПодтвержденияНДС";
НовыйИдентификатор.Имя = "ИнойДокументПодтвержденияНДС";
// Заполните остальные обязательные реквизиты согласно метаданным
НовыйИдентификатор.Записать();
Проанализируем еще несколько моментов, которые могут мешать исправлению ситуации:
Используя предложенные методы в комплексе, вы сможете восстановить работоспособность базы после неудачного обновления и устранить ошибки обращения к метаданным.