Как исправить ошибку «Несоответствие типов» при обновлении подчиненного узла РИБ в 1С?

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

При обновлении конфигурации распределенной информационной базы (РИБ) системные администраторы и разработчики нередко сталкиваются с ситуацией, когда центральный узел успешно обновляется, но на подчиненных узлах при запуске в режиме «1С:Предприятие» выполнение процедур обновления аварийно прерывается.

Типичный пример такой ошибки возникает при работе процедур Библиотеки стандартных подсистем (БСП):

«РассылкаОтчетов.ЗарегистрироватьДанныеДляАктуализацииСпискаРегламентныхЗаданий отложенного обработчика обновления РассылкаОтчетов.АктуализироватьСписокРегламентныхЗаданий произошла ошибка: {ОбщийМодуль.ОбщегоНазначения.Модуль}: Ошибка при вызове метода контекста (Содержит): Возврат Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных); по причине: Несоответствие типов (параметр номер 1)».

Разберем детально механизм возникновения этой неполадки и рассмотрим проверенные способы её устранения.

Причина возникновения ошибки в распределенной базе

Проанализируем стек вызовов и поведение платформы. Ошибка Несоответствие типов при передаче параметра в метод Содержит() означает, что переменная ОбъектМетаданных содержит значение Неопределено вместо ссылки на объект метаданных. Это происходит из-за того, что прикладной код пытается получить метаданные предопределенного элемента (например, предопределенного элемента ЛичныеДанные справочника РассылкиОтчетов), но сам элемент физически отсутствует в таблице базы данных узла.

Выясним причину отсутствия предопределенного элемента в подчиненной базе:

  1. В платформе «1С:Предприятие 8.3» для большинства объектов метаданных свойство «Обновление предопределенных данных» установлено в значение Авто.
  2. В центральном узле (и в нераспределенных базах) режим Авто платформа интерпретирует как команду «Обновлять автоматически». Поэтому при первом старте или реструктуризации все предопределенные элементы создаются без сбоев.
  3. В подчиненных узлах РИБ платформа трактует значение Авто строго как «Не обновлять автоматически». Архитектура РИБ предполагает, что данные должны приходить из главного узла через файлы обмена.
  4. Если справочник не включен в состав плана обмена (или правила регистрации запрещают его миграцию в конкретный узел), новый предопределенный элемент в дочернюю базу не передается.

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

Способ 1. Перенос недостающего элемента из центрального узла (рекомендуемый)

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

Разберем по шагам порядок действий:

  1. Открываем центральную информационную базу (или её актуальную копию) в режиме «1С:Предприятие».
  2. С помощью универсальной обработки ВыгрузкаЗагрузкаДанныхXML находим справочник (в нашем случае РассылкиОтчетов) и выгружаем нужный предопределенный элемент (например, ЛичныеДанные) в файл XML.
  3. Открываем аварийный подчиненный узел до запуска процедуры обновления (либо временно запускаем базу с ключом /C ЗапуститьОбновлениеИнформационнойБазы снятым, если настроен автоматический запуск, либо входим под учетной записью без запуска фоновых заданий).
  4. Загружаем файл XML с помощью той же обработки в подчиненную базу.
  5. Запускаем процесс обновления информационной базы повторно. Процедура успешно найдет предопределенный элемент по его идентификатору и завершит отложенные обработчики.

Способ 2. Принудительное включение обновления предопределенных данных через Конфигуратор

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

Рассмотрим запуск через командную строку. Для этого выполним пакетное обновление с параметром /SetPredefinedDataUpdate -UpdateAutomatically:


"C:\Program Files\1cv8\common\1cv8.exe" CONFIG /F "D:\Bases\SubNode" /N "Администратор" /P "Пароль" /SetPredefinedDataUpdate -UpdateAutomatically /UpdateDBCfg

После успешного обновления конфигурации базы данных и создания необходимых записей запустим базу в режиме предприятия и дождемся завершения работы обработчиков. Затем обязательно вернем исходное состояние параметра для подчиненного узла:


"C:\Program Files\1cv8\common\1cv8.exe" CONFIG /F "D:\Bases\SubNode" /N "Администратор" /P "Пароль" /SetPredefinedDataUpdate -Auto

Способ 3. Программная инициализация предопределенных данных

Посмотрим на программный метод решения проблемы. Платформа 1С предоставляет разработчику методы встроенного языка для точечного управления предопределенными данными конкретного метаданного без изменения всей конфигурации.

Создадим внешнюю обработку и выполним следующий код:


// Принудительно разрешаем создание элементов для конкретного справочника
Справочники.РассылкиОтчетов.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

// Сбрасываем флаг инициализации, чтобы платформа выполнила повторный поиск элементов
Справочники.РассылкиОтчетов.УстановитьИнициализациюПредопределенныхДанных(Ложь);

// Обращаемся к элементу для инициализации его создания в таблице
Попытка
    ТестоваяСсылка = Справочники.РассылкиОтчетов.ЛичныеДанные;
Исключение
    Сообщить("Ошибка обращения к предопределенному элементу: " + ОписаниеОшибки());
КонецПопытки;

// Возвращаем режим в исходное значение
Справочники.РассылкиОтчетов.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.Авто);

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


УстановитьОбновлениеПредопределенныхДанныхИнформационнойБазы(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

Важное предостережение: при локальной генерации предопределенного элемента в подчиненном узле платформой генерируется новый УникальныйИдентификатор. Если в будущем данный справочник будет добавлен в состав плана обмена, это может привести к появлению дубликатов или ошибкам слияния данных с главным узлом. Именно поэтому Способ 1 (перенос через XML) остается приоритетным.

Способ 4. Временное отключение узла от главного плана обмена

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

Разберем алгоритм:

  1. Открываем внешнюю обработку и очищаем ссылку на главный узел: ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
  2. Запускаем подчиненную базу в обычном режиме. Поскольку база больше не считает себя дочерним узлом РИБ, платформа автоматически создаст недостающие предопределенные данные и успешно завершит отложенные процедуры обновления.
  3. После завершения всех процедур обновления возвращаем признак подчиненности главному узлу:
    
    // В качестве параметра передаем ссылку на узел центральной базы в плане обмена
    Главный = ПланыОбмена.ПолнотекстовыйОбмен.НайтиПоКоду("ЦУ");
    ПланыОбмена.УстановитьГлавныйУзел(Главный);
    

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

← На главную