При разработке собственных объектов в конфигурациях, работающих в облачных сервисах (SaaS) или использующих Библиотеку стандартных подсистем (БСП), программисты часто сталкиваются с неожиданным поведением стандартных механизмов. Одной из таких проблем является ошибка «Несоответствие типов» при вызове метода Добавить() в общем модуле МиграцияПриложений. Это происходит в момент проведения или записи документа, когда система пытается автоматически зарегистрировать изменения для обмена данными.
В этой статье мы подробно разберем, почему возникает эта ошибка, как работает механизм миграции в облаке и какими способами можно исключить ваш документ из этого процесса, чтобы восстановить работоспособность системы.
Давайте проанализируем ситуацию. Ошибка возникает в строке кода:
Источник.ОбменДанными.Получатели.Добавить(Выборка.Ссылка);
Метод Добавить() коллекции Получатели ожидает в качестве параметра ссылку на узел плана обмена (ПланОбменаСсылка). Однако, если документ является «самописным» и не включен в состав ни одного плана обмена, используемого механизмом миграции, переменная Выборка.Ссылка может принимать неопределенное или некорректное значение.
Причина кроется в подписках на события. В современных конфигурациях (особенно в решениях от Рарус или типовых БСП-решениях) существуют общие подписки на события ПередЗаписью или ПриЗаписи, настроенные на тип ДокументОбъект. Это означает, что любой созданный вами документ автоматически попадает в обработку модуля МиграцияПриложений. Если механизм миграции «видит» документ, но не находит для него правил в планах обмена, происходит сбой логики, ведущий к ошибке типов.
Это наиболее правильный и «мягкий» способ решения проблемы, если вы не планируете передавать данные этого документа в другие базы или облачные шлюзы. Мы можем передать в обработчик обмена специальный флаг, который прикажет системе игнорировать данный объект.
Рассмотрим, как правильно реализовать это в модуле объекта вашего документа. Нам понадобится предопределенная процедура ПередЗаписью.
Важный момент: часто разработчики допускают синтаксические ошибки при работе с коллекцией ДополнительныеСвойства. Посмотрим на корректный пример кода:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Устанавливаем признак, который считывается подписками БСП
ЭтотОбъект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов", Истина);
// В некоторых версиях БСП используются альтернативные ключи
ЭтотОбъект.ДополнительныеСвойства.Вставить("ОбменДаннымиСобытия_ПропускатьСобытие", Истина);
КонецПроцедуры
Обратите внимание, что мы используем ЭтотОбъект. Если вы пытаетесь сделать это из модуля формы, необходимо обращаться к реквизиту Объект (преобразовав его в ДанныеФормыВЗначение), но надежнее всего размещать этот код именно в модуле объекта, так как запись может инициироваться не только из формы, но и программно.
Если первый способ по каким-то причинам не срабатывает (например, в вашей версии конфигурации используются специфические модификации модуля миграции), можно прибегнуть к установке свойства Загрузка.
Когда свойство Источник.ОбменДанными.Загрузка установлено в Истина, большинство подписок на события обмена данными (включая регистрацию изменений) игнорируют объект. Однако помните, что это также отключает и прикладные проверки (например, контроль остатков в ОбработкаПроведения), если они не обернуты в условие проверки этого флага.
Пример реализации в модуле объекта:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если НЕ ЭтотОбъект.ОбменДанными.Загрузка Тогда
// Этот код сработает, если мы хотим принудительно
// заставить систему думать, что идет загрузка данных
// Но используйте это с осторожностью!
// ЭтотОбъект.ОбменДанными.Загрузка = Истина;
КонецЕсли;
КонецПроцедуры
Если документ должен синхронизироваться с другими узлами, то правильным решением будет не отключение механизма, а его корректная настройка. Проанализируем, какие шаги необходимо выполнить в конфигураторе:
Миграция или относятся к синхронизации данных в модели сервиса).Разрешить (или Запретить, если регистрация должна управляться программно через правила).После этого механизм МиграцияПриложений будет понимать, как обрабатывать ваш документ, и коллекция Получатели будет заполняться корректно, что устранит ошибку Несоответствие типов.
Разберем, почему у автора вопроса не получалось решить проблему изначально. Рассмотрим ошибки в коде, которые часто встречаются на практике:
ДокмуентОбъект вместо ДокументОбъект или ЭтотОбъект. В 1С важна точность написания идентификаторов.ДополнительныеСвойства сложную строку вида "Источник.ДополнительныеСвойства.Свойство(...)". Коллекция ДополнительныеСвойства — это структура, где первым параметром идет Имя свойства (ключ), а вторым — его Значение.Поскольку работа ведется в облачной базе, где отладка может быть затруднена, рекомендуем использовать следующий алгоритм при возникновении подобных ошибок:
Во-первых, всегда проверяйте, не включен ли ваш объект в общие подписки на события. Это можно сделать в конфигураторе в ветке Общие -> Подписки на события. Посмотрите на подписки с именами вроде ОбменДанными...ПередЗаписью.
Во-вторых, если вы добавляете новый функционал в типовое решение (как в случае с Рарус: НКО), старайтесь следовать архитектуре БСП. Если система требует регистрации всех документов в планах миграции — лучше добавить документ в план обмена, чем пытаться «обмануть» систему программными заглушками.
В-третьих, используйте Журнал регистрации. Даже в облаке он доступен и может содержать более подробный стек ошибки, который укажет на конкретный узел обмена, вызывающий сбой.
Таким образом, мы выяснили, что ошибка вызвана конфликтом нового объекта метаданных с автоматизированными механизмами облачной платформы. Применяя один из описанных выше методов — программное отключение через ДополнительныеСвойства или настройку состава планов обмена — вы сможете успешно провести документ и избежать прерывания работы системы.