Как в Конвертации Данных 2.1 обратиться к реквизитам узла обмена и предотвратить появление пустых документов при загрузке?

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

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

Представим сценарий: в узле обмена задана дата начала выгрузки документов (например, 01.06.2020). Мы переносим документ ЗакрытиеЗаказовПокупателей, созданный после этой даты. Однако в его табличной части содержится ссылка на другой документ — ЗаказПокупателя, который был создан раньше (например, 20.05.2020) и, по логике обмена, выгружаться не должен. На практике в базе-приемнике создается пустой документ ЗаказПокупателя, в котором заполнены только номер и дата. При этом попытка ограничить загрузку в обработчике ПослеЗагрузки вызывает ошибку выполнения.

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

Выясняем причину ошибки обращения к узлу обмена при загрузке

Попытка обратиться напрямую к переменной УзелДляОбмена в обработчиках загрузки (на стороне базы-приемника) приводит к ошибке «Значение не является значением объектного типа». Это происходит из-за разделения контекстов работы выгрузки и загрузки:

  1. Переменная УзелДляОбмена доступна только на стороне источника (при выгрузке данных).
  2. На стороне приемника (при загрузке) контекст обмена не знает о существовании этой переменной. Вместо нее система использует переменную УзелОбменаЗагрузкаДанных.
  3. Даже если использовать правильную переменную УзелОбменаЗагрузкаДанных, в базе-приемнике у соответствующего плана обмена может просто не быть реквизита ДатаНачалаВыгрузкиДокументов (например, если структуры баз различаются или реквизит добавлен только в источнике).

Для безопасной передачи любых настроек узла обмена из источника в приемник правильнее всего использовать механизм параметров конвертации. Чтобы автоматизировать выполнение обмена по подготовленным правилам, используется программа для регулярной синхронизации баз 1С по расписанию.

Решение №1. Использование параметров конвертации для передачи даты начала обмена

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

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

Если ЗначениеЗаполнено(УзелДляОбмена) Тогда
    Параметры.ДатаНачалаВыгрузки = УзелДляОбмена.ДатаНачалаВыгрузкиДокументов;
КонецЕсли;
  1. Теперь на стороне приемника в глобальном обработчике «После загрузки объекта» (или в локальном обработчике ПКО) мы можем безопасно обратиться к этому параметру:

Если Параметры.Свойство("ДатаНачалаВыгрузки") И ЗначениеЗаполнено(Параметры.ДатаНачалаВыгрузки) Тогда
    // Проверяем, что загружается документ
    Если СтрНайти(Объект.Метаданные().ПолноеИмя(), "Документ") <> 0 Тогда
        Если Объект.Дата < Параметры.ДатаНачалаВыгрузки Тогда
            Отказ = Истина;
            Сообщить("" + Объект + " не загружен. Дата документа меньше начальной даты обмена.");
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Анализируем проблему появления пустых документов («битых ссылок»)

Хотя отмена загрузки через Отказ = Истина в обработчике ПослеЗагрузки решает проблему непосредственной записи документа, архитектурно это не самый лучший вариант. Если старый ЗаказПокупателя переносится «по ссылке» из табличной части другого документа, то:

Рассмотрим более элегантные способы предотвращения выгрузки таких объектов еще на этапе работы источника.

Решение №2. Фильтрация выгрузки свойства на стороне источника

Самый надежный способ — не допустить отправку «нежелательных» ссылок в XML-файл. Для этого настроим логику в Правилах Конвертации Свойств (ПКС) для реквизита ЗаказПокупателя внутри ПКО документа-владельца (ЗакрытиеЗаказовПокупателей).

В обработчике «Перед выгрузкой» свойства напишем код:


Если ЗначениеЗаполнено(Источник.ЗаказПокупателя) Тогда
    // Проверяем дату подчиненного заказа
    Если Источник.ЗаказПокупателя.Дата < УзелДляОбмена.ДатаНачалаВыгрузкиДокументов Тогда
        // Очищаем значение, чтобы в приемник записалась пустая ссылка
        Значение = Неопределено; 
    КонецЕсли;
КонецЕсли;

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

Решение №3. Использование настроек ПКО («Не создавать новый объект...»)

В КД 2.1 предусмотрен штатный механизм управления ссылками. Если открыть Правило Конвертации Объектов (ПКО) для ЗаказПокупателя, мы увидим настройку: «При переносе объекта по ссылке НЕ создавать новый объект, а только переносить ссылку».

Если установить этот флаг, то при обработке ссылок в табличных частях система запишет в приемнике только GUID (уникальный идентификатор), но не будет физически создавать пустую карточку документа в базе данных, если данный объект ранее не переносился.

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


Если Источник.Дата < УзелДляОбмена.ДатаНачалаВыгрузкиДокументов Тогда
    // Передаем только ссылку без создания полноценного объекта в приемнике
    ТолькоПолучитьСсылка = Истина; 
КонецЕсли;

Использование флага ТолькоПолучитьСсылка позволяет гибко регулировать глубину выгрузки данных, предотвращая замусоривание базы-приемника пустыми карточками документов прошлых периодов и сохраняя при этом ссылочную целостность базы данных.

← На главную