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