Почему возникает ошибка 'Поле объекта недоступно для записи (Ссылка)' при изменении параметра 'Источник' в Конвертации Данных?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке правил обмена в "1С:Конвертация данных 2.0" (КД2) программисты часто сталкиваются с неочевидным поведением платформы. Одна из таких ситуаций — возникновение ошибки "Поле объекта недоступно для записи" при попытке изменить или переопределить параметр Источник внутри обработчика события, например, ПередВыгрузкойОбъекта. Давайте детально разберем, почему это происходит и как правильно решить такую задачу. Для быстрого просмотра доступных параметров процедур можно использовать конфигурацию «Конвертация данных» со встроенными подсказками по обработчикам.

Анализ проблемы: попытка подмены источника

Рассмотрим исходную ситуацию. Разработчик хочет при выгрузке документа "Списание с расчетного счета" с определенным видом операции дополнительно выгрузить связанную сущность, представив ее в виде структуры. Для этого используется вызов ВыгрузитьПоПравилу из одного обработчика, а в другом обработчике делается попытка "превратить" исходный объект в структуру.

Вот как выглядит проблемный код:


// Обработчик события "После выгрузки" для документа
Процедура ПКО_ПослеВыгрузкиВФайл_Документ_СписаниеСРасчетногоСчета(...) Экспорт
    Если Источник.ВидОперации = Перечисления.ВидыОперацийСписаниеДенежныхСредств.ПеречислениеНалога Тогда
        // Вызываем выгрузку по другому правилу, передавая тот же Источник
        ВыгрузитьПоПравилу(Источник, , , , "Справочник_НастройкиСчетовУчетаПрочихОпераций");
    КонецЕсли;
КонецПроцедуры

// Обработчик события "Перед выгрузкой" для правила, которое мы вызвали
Процедура ПКО_ПередВыгрузкой_Справочник_НастройкиСчетовУчетаПрочихОпераций(...) Экспорт
    // !!! ПРОБЛЕМНАЯ СТРОКА !!!
    // Попытка подменить переданный по ссылке Источник на новую Структуру
    Источник = Новый Структура("ВладелецНастройки, СчетУчета, Наименование, ...", 
                               Источник, Источник.СчетУчетаРасчетовСКонтрагентом, , ...);
КонецПроцедуры

В момент выполнения строки Источник = Новый Структура(...) система генерирует ошибку:

Ошибка в обработчике события ПередВыгрузкойОбъекта... ОписаниеОшибки = Поле объекта недоступно для записи (Ссылка)

На первый взгляд, это кажется странным. Ведь Источник — это параметр процедуры, и в 1С параметры по умолчанию передаются по ссылке, что, казалось бы, должно позволять их изменять. Но здесь кроется ключевой нюанс работы механизма КД2.

Выясняем причину: параметр или поле объекта?

Основная причина ошибки заключается в том, что в контексте выполнения обработчиков событий КД2 параметр Источник — это не просто локальная переменная процедуры. Он тесно связан с внутренним состоянием обработки обмена и представляет собой свойство объекта-контекста, который в данный момент обрабатывается.

  1. Связь с реальным объектом: Когда обработчик получает в качестве Источника ссылку на документ или справочник, платформа воспринимает этот параметр как прямое представление объекта из базы данных.
  2. Неизменяемость ссылки: Попытка присвоить параметру Источник совершенно новое значение (в нашем случае, объект типа Структура) интерпретируется платформой не как изменение локальной переменной, а как попытка изменить системное, неизменяемое поле самого объекта — его Ссылку (Ref).
  3. Точная диагностика: Текст ошибки Поле объекта недоступно для записи (Ссылка) говорит нам об этом прямо. Система защищает целостность данных и не позволяет подменить уникальный идентификатор объекта (ссылку) чем-то другим. Это фундаментальное ограничение платформы 1С.

Таким образом, попытка "обмануть" систему и подменить тип данных на лету внутри обработчика обречена на провал. Событие ПередВыгрузкойОбъекта предназначено для того, чтобы проанализировать Источник, возможно, изменить какие-то его выгружаемые данные или вовсе отказаться от выгрузки (через параметр Отказ = Истина), но не для того, чтобы подменить сам объект выгрузки.

Правильное архитектурное решение

Чтобы решить задачу корректно, нужно изменить подход. Вместо того чтобы пытаться трансформировать Источник внутри вызываемого правила, необходимо подготовить нужные данные (структуру) заранее и передать в ВыгрузитьПоПравилу уже их.

Разберем по шагам правильный алгоритм:

  1. Определяем место подготовки данных. Логику по созданию структуры нужно разместить в том месте, где инициируется ее выгрузка. В нашем примере это обработчик ПКО_ПослеВыгрузкиВФайл_Документ_СписаниеСРасчетногоСчета.
  2. Создаем и заполняем структуру. Перед вызовом ВыгрузитьПоПравилу создаем новый объект типа Структура и заполняем его всеми необходимыми данными из исходного документа.
  3. Выгружаем готовую структуру. Передаем в качестве первого параметра в ВыгрузитьПоПравилу нашу подготовленную структуру.

Посмотрим на исправленный код:


Процедура ПКО_ПослеВыгрузкиВФайл_Документ_СписаниеСРасчетногоСчета(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО, ВыгруженныеОбъекты, Приемник, УзелСсылки) Экспорт
    // Проверяем условие, при котором нужна выгрузка дополнительных данных
    Если Источник.ВидОперации = Перечисления.ВидыОперацийСписаниеДенежныхСредств.ПеречислениеНалога Тогда
        
        // 1. Создаем структуру с нужными данными
        СтруктураДляВыгрузки = Новый Структура;
        
        // 2. Заполняем ее поля на основе данных документа-источника
        СтруктураДляВыгрузки.Вставить("ВладелецНастройки", Источник);
        СтруктураДляВыгрузки.Вставить("СчетУчета", Источник.СчетУчетаРасчетовСКонтрагентом);
        СтруктураДляВыгрузки.Вставить("Наименование", "Настройка для налога из документа " + СокрЛП(Источник));
        СтруктураДляВыгрузки.Вставить("ПометкаУдаления", Источник.ПометкаУдаления);
        СтруктураДляВыгрузки.Вставить("Субконто1", Неопределено); // Заполняем по своей логике
        СтруктураДляВыгрузки.Вставить("Субконто2", Неопределено);
        СтруктураДляВыгрузки.Вставить("Субконто3", Неопределено);
        
        // 3. Вызываем выгрузку по правилу, передавая уже готовую структуру
        ВыгрузитьПоПравилу(СтруктураДляВыгрузки, , , , "Справочник_НастройкиСчетовУчетаПрочихОпераций");
        
    КонецЕсли;
КонецПроцедуры

Что происходит теперь?

Ключевые выводы

  1. Не переопределяйте Источник. Никогда не пытайтесь присвоить параметру Источник в обработчиках событий КД2 значение другого типа. Это противоречит архитектуре механизма обмена.
  2. Готовьте данные заранее. Если вам нужно выгрузить объект, который не существует в базе данных, или данные в сильно измененной структуре, — формируйте эту структуру или таблицу значений в вызывающем коде.
  3. Используйте ВыгрузитьПоПравилу правильно. Эта процедура универсальна. Она может принимать в качестве первого параметра как ссылку на объект базы данных, так и произвольные данные (Структура, ТаблицаЗначений, Соответствие и т.д.).
  4. Читайте ошибки внимательно. Сообщения платформы 1С часто содержат точное указание на причину проблемы. В данном случае фраза "Поле объекта недоступно для записи (Ссылка)" была ключом к разгадке.

Соблюдение этих простых правил сделает ваши правила обмена более надежными, предсказуемыми и легкими для отладки. Для пошаговой диагностики алгоритмов выгрузки подойдёт инструмент для отладки обработчиков КД в конфигураторе.

← На главную