При настройке обмена данными между устаревшими конфигурациями (например, Комплексная автоматизация 1.1 или Управление производственным предприятием 1.3) и современными редакциями Бухгалтерия предприятия 3.0 (БП 3.0) специалисты часто сталкиваются с неожиданными ошибками после обновления целевой базы. Одной из самых коварных является ошибка: Ошибка при вызове метода контекста (ПолучитьОбработкуЭДО): Попытка передачи мутабельного значения результата метода ПолучитьОбработкуЭДО.
В этой статье мы подробно разберем, почему возникает эта проблема, как она связана с архитектурой 1С:Предприятия и какими способами можно её быстро устранить, не прибегая к масштабному пересмотру правил обмена.
Проанализируем ситуацию: ошибка возникает в процессе записи документа (например, РеализацияТоваровУслуг) в целевую базу. В современных релизах БП 3.0 в подсистему Электронного Документооборота (ЭДО) добавлены механизмы автоматической регистрации документов в специализированных регистрах, таких как ДокументыПоТребованиюФНС. При записи документа срабатывает подписка на событие, которая обращается к общему модулю ЭлектронныйДокументооборотСКонтролирующимиОрганами.
Проблема кроется в методе ПолучитьОбработкуЭДО(). Этот метод пытается инициализировать объект обработки. Если обмен данными происходит через COM-соединение (прямое подключение к базе), система пытается передать этот сложный объект (менеджер или объект обработки) из контекста одной базы в другую. В терминах платформы 1С такие объекты являются мутабельными (изменяемыми), и их передача через границу «клиент-сервер» или между разными процессами через COM запрещена.
Рассмотрим основные сценарии, при которых это происходит:
Если вы используете «Прямое подключение к базе-приемнику» (COM), попробуйте изменить способ обмена. Как показывает практика, переход на обмен через сетевой каталог (выгрузка в XML файл и последующая загрузка) полностью снимает проблему мутабельности. Это происходит потому, что при загрузке из файла все операции выполняются внутри одного серверного контекста целевой базы, и передачи объекта через COM-границу не происходит.
Иногда корень проблемы лежит в области прав доступа. Проверим настройки в целевой базе БП 3.0:
ИспользоватьВнешнийМодульЗащищенногоДокументооборотаСКО и ВнешнийМодульЗащищенногоДокументооборотаСКО.Если мы работаем с Конвертацией данных 2.0, мы можем повлиять на поведение объекта Источник (или Объект в базе-приемнике) непосредственно перед его записью. Чтобы система ЭДО «проигнорировала» данный документ и не запускала цепочку вызовов, приводящую к ошибке, можно воспользоваться специальными флагами.
Рассмотрим пример кода, который можно вставить в обработчик ПослеЗагрузки в правилах обмена или в обработчик ПередЗаписью непосредственно в целевой базе:
// Вариант 1: Установка флага загрузки.
// Внимание! Это отключит ВСЕ проверки и подписки (иногда это нежелательно)
Объект.ОбменДанными.Загрузка = Истина;
// Вариант 2: Использование специфического флага для обхода механизма ФНС
// Это более мягкий способ, отключающий только проблемную часть
Объект.ДополнительныеСвойства.Вставить("ГрупповоеПерепроведение", Истина);
Посмотрим подробнее на Вариант 2. Флаг ГрупповоеПерепроведение анализируется внутренними механизмами БСП. Если он установлен в Истина, подсистема ЭДО считает, что документ обрабатывается массово, и пропускает вызов инициализации формы обработки ЭДО, что и спасает нас от ошибки мутабельности.
Если проблему нужно решить на стороне целевой конфигурации без изменения правил обмена, наиболее правильным путем будет создание расширения. Мы перехватим проблемный метод и заставим его работать более эффективно, без создания мутабельных объектов обработки там, где это не нужно.
Проанализируем пример кода для модуля ЭлектронныйДокументооборотСКонтролирующимиОрганами. Мы заменим стандартную функцию на свою, которая извлекает данные из макета напрямую, не инициализируя всю обработку целиком:
&Вместо("СоответствиеВидовДокументовФНС")
Функция ИСП_СоответствиеВидовДокументовФНС()
// Получаем макет напрямую из метаданных обработки, не создавая объект обработки
Макет = Обработки.ДокументооборотСКонтролирующимиОрганами.ПолучитьМакет("ВидыПредставляемыхДокументов");
ОбластьЯчеек = Макет.Область(1, 1, Макет.ВысотаТаблицы, Макет.ШиринаТаблицы);
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
ПостроительЗапроса.Выполнить();
Виды = ПостроительЗапроса.Результат.Выгрузить();
Виды.Колонки.Добавить("Значение");
// Выполняем предобработку (вспомогательные процедуры должны быть также в расширении или вызываться из общего модуля)
ПредобработкаВидовПредставляемыхДокументов(Виды);
Для каждого Вид Из Виды Цикл
Попытка
Вид.Значение = Перечисления.ВидыПредставляемыхДокументов[Вид.Имя];
Исключение
Вид.Значение = Неопределено;
КонецПопытки;
КонецЦикла;
СоответствиеРезультат = Новый Соответствие;
Для каждого Вид Из Виды Цикл
СоответствиеРезультат.Вставить(Вид.Имя, Вид.Значение);
КонецЦикла;
Возврат СоответствиеРезультат;
КонецФункции
Этот подход хорош тем, что он устраняет первопричину — создание объекта ОбработкаОбъект на сервере при вызове из контекста, который система считает «внешним». Поскольку Соответствие и ТаблицаЗначений (внутри метода) обрабатываются корректно, ошибка исчезает.
Если у вас нет возможности вносить изменения в конфигурацию (БП 3.0 на строгом аудите или поддержке), вернемся к вопросу автора темы о быстрой корректировке правил обмена. Чтобы «не заморачиваться» с обновлением метаданных в Конвертации данных 2.0 при добавлении нового реквизита в целевой базе, выполните следующие действия:
ПКО (Правило Конвертации Объекта), например, для документа РеализацияТоваровУслуг.ПередЗаписью добавьте строку: Объект.ОбменДанными.Загрузка = Истина;. Это универсальный «выключатель» для большинства проблем, связанных с кодом в подписках.ДополнительныеСвойства, как было описано в Способе 3.Разберем, почему установка Загрузка = Истина помогает. В платформе 1С этот флаг сигнализирует системе, что объект записывается механизмом обмена данными. Большинство типовых проверок и тяжелых обработчиков в модулях объектов и подписках обернуты в условие: Если Не ОбменДанными.Загрузка Тогда.... Установив этот флаг, вы просто обходите проблемный участок кода БП 3.0.
Мы выяснили, что ошибка мутабельности в ПолучитьОбработкуЭДО — это следствие усложнения типовых конфигураций и их механизмов интеграции с госорганами. Для быстрого решения используйте файловый обмен или флаг Загрузка = Истина. Для качественного и долгосрочного решения — используйте расширение конфигурации, которое оптимизирует работу с макетами подсистемы ЭДО без создания лишних объектов в памяти.