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