Как настроить перенос реквизита составного типа в КД 2 и избежать аварийного завершения выгрузки

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

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

Разберем по шагам, как корректно сопоставлять составные типы данных, почему выгрузка может аварийно завершаться и как исправить ошибки записи подчиненных справочников в приемнике.

Динамический выбор ПКО для составного типа данных

Рассмотрим ситуацию: в источнике реквизит Владелец имеет составной тип (Организации, Контрагенты, Подразделения), а в приемнике — (Организации, Контрагенты). Если в правилах обмена создано несколько ПКО для одного и того же объекта источника (например, Контрагенты_Контрагенты и Контрагенты_Партнеры), механизм обмена автоматически берет первое подходящее правило из дерева правил. В результате ссылка может конвертироваться не в тот тип данных, который ожидает приемник.

Для явного указания нужного правила конвертации используем обработчик ПередВыгрузкой соответствующего ПКС (Правила конвертации свойства). Проанализируем пример кода:


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

Переменная ИмяПКО принимает строковое значение точного наименования правила конвертации объекта, как оно задано в конфигурации конвертации данных.

Причины падения платформы и аварийного завершения выгрузки

Если после явного указания правила ИмяПКО = "Контрагенты_Контрагенты" сеанс 1С аварийно закрывается без явных сообщений об ошибке, это свидетельствует о переполнении стека вызовов (Stack Overflow) в результате бесконечной рекурсивной выгрузки.

Выясним главные причины возникновения циклической выгрузки:

  1. Флаг «Не запоминать выгруженные объекты» в ПКО: Если в правиле конвертации объекта включена эта опция, механизм обмена перестает кэшировать уже обработанные ссылки во внутренней таблице. Каждый раз, когда объект встречается в ссылочных реквизитах, он выгружается полностью заново со всеми зависимостями.
  2. Циклические и иерархические ссылки в реквизитах: В справочниках часто присутствуют реквизиты, ссылающиеся на этот же справочник, например ГоловнойКонтрагент или Родитель. Если контрагент ссылается сам на себя (или образуется взаимная ссылка между двумя элементами), при отключенном кэшировании выгруженных объектов обработка попадает в бесконечный цикл: контрагент тянет головного контрагента, тот снова запускает выгрузку и так далее до исчерпания памяти стека.

Способы устранения рекурсивного зацикливания

Разберем методы решения проблемы циклической выгрузки:

  1. Отключить флаг «Не запоминать выгруженные объекты»: В ПКО справочника (например, Контрагенты_Контрагенты) проверьте настройки на вкладке основных параметров. Снимите указанный флаг, чтобы платформа регистрировала уже обработанные объекты и выгружала их однократно.
  2. Исключить самоссылки в обработчиках ПКС: Для циклического свойства (например, ГоловнойКонтрагент) в обработчике ПередВыгрузкой проверяем равенство ссылки и источника:
    
    Если Источник.ГоловнойКонтрагент = Источник Тогда
        Значение = Неопределено;
    КонецЕсли;
    
  3. Ограничить глубину выгрузки ссылкой: В настройках ПКС для ссылочных реквизитов, способных породить иерархическую цепочку, можно установить флаг «Выгружать только ссылку» (или переопределить параметр ВыгружатьТолькоСсылку = Истина; в обработчике), чтобы не инициировать полную сериализацию реквизитов связанного объекта.

Почему данные могут не записываться в базе-приемнике

Если файл выгрузки формируется корректно, но при загрузке подчиненные элементы справочника не появляются в базе-приемнике, проанализируем следующие факторы:

  1. Контроль целостности подчиненных справочников: На уровне платформы 1С подчиненный элемент не может быть записан в информационную базу, если реквизит Владелец пуст, не найден по полям поиска или указывает на незаписанный объект. В этом случае вызов метода Объект.Записать() отменяет транзакцию.
  2. Порядок следования объектов: Если подчиненный элемент считывается раньше, чем создается его владелец, и не используется режим отложенного проведения/записи, объект не будет создан. Рекомендуется настраивать порядок выгрузки ПКО так, чтобы справочники-владельцы выгружались выше подчиненных.
  3. Ошибки в обработчиках модулей объектов: При загрузке в приемнике срабатывают типовые события модулей объектов (ПередЗаписью, ПриЗаписи). Если в них не заполнены обязательные реквизиты, запись молча отклоняется при определенных настройках обмена.

Для поиска таких ошибок запускайте универсальный обмен данными в базе-приемнике с включенными флагами «Режим отладки» и «Выводить информационные сообщения в журнал регистрации», либо формируйте модуль отладки обработчиков загрузки через инструмент выгрузки обработчиков в КД 2.

← На главную