Разберем одну из классических и в то же время коварных проблем, с которой часто сталкиваются разработчики при настройке правил обмена в конфигурации «1С:Конвертация данных 2.1» (КД 2.1).
Представим сценарий: в узле обмена задана дата начала выгрузки документов (например, 01.06.2020). Мы переносим документ ЗакрытиеЗаказовПокупателей, созданный после этой даты. Однако в его табличной части содержится ссылка на другой документ — ЗаказПокупателя, который был создан раньше (например, 20.05.2020) и, по логике обмена, выгружаться не должен. На практике в базе-приемнике создается пустой документ ЗаказПокупателя, в котором заполнены только номер и дата. При этом попытка ограничить загрузку в обработчике ПослеЗагрузки вызывает ошибку выполнения.
Проанализируем ситуацию, выясним причины ошибок контекста КД 2.1 и рассмотрим несколько эффективных способов решения этой проблемы. Если после настройки правил и переноса документов требуется убедиться в отсутствии расхождений, можно запустить автоматическое сравнение бухгалтерских и налоговых проводок между базами.
Попытка обратиться напрямую к переменной УзелДляОбмена в обработчиках загрузки (на стороне базы-приемника) приводит к ошибке «Значение не является значением объектного типа». Это происходит из-за разделения контекстов работы выгрузки и загрузки:
УзелДляОбмена доступна только на стороне источника (при выгрузке данных).УзелОбменаЗагрузкаДанных.УзелОбменаЗагрузкаДанных, в базе-приемнике у соответствующего плана обмена может просто не быть реквизита ДатаНачалаВыгрузкиДокументов (например, если структуры баз различаются или реквизит добавлен только в источнике).Для безопасной передачи любых настроек узла обмена из источника в приемник правильнее всего использовать механизм параметров конвертации. Чтобы автоматизировать выполнение обмена по подготовленным правилам, используется программа для регулярной синхронизации баз 1С по расписанию.
Рассмотрим по шагам, как передать дату начала выгрузки из источника в приемник через параметры обмена:
ДатаНачалаВыгрузки. Обязательно установим для него флаг «Передавать при выгрузке».
Если ЗначениеЗаполнено(УзелДляОбмена) Тогда
Параметры.ДатаНачалаВыгрузки = УзелДляОбмена.ДатаНачалаВыгрузкиДокументов;
КонецЕсли;
Если Параметры.Свойство("ДатаНачалаВыгрузки") И ЗначениеЗаполнено(Параметры.ДатаНачалаВыгрузки) Тогда
// Проверяем, что загружается документ
Если СтрНайти(Объект.Метаданные().ПолноеИмя(), "Документ") <> 0 Тогда
Если Объект.Дата < Параметры.ДатаНачалаВыгрузки Тогда
Отказ = Истина;
Сообщить("" + Объект + " не загружен. Дата документа меньше начальной даты обмена.");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Хотя отмена загрузки через Отказ = Истина в обработчике ПослеЗагрузки решает проблему непосредственной записи документа, архитектурно это не самый лучший вариант. Если старый ЗаказПокупателя переносится «по ссылке» из табличной части другого документа, то:
Отказ = Истина на этапе после загрузки, мы запретим финальную запись объекта, но в табличной части главного документа (ЗакрытиеЗаказовПокупателей) останется «битая ссылка» (объект в базе отсутствует, но ссылка указывает на пустой УИД). Это может привести к ошибкам проведения документов в приемнике.Рассмотрим более элегантные способы предотвращения выгрузки таких объектов еще на этапе работы источника.
Самый надежный способ — не допустить отправку «нежелательных» ссылок в XML-файл. Для этого настроим логику в Правилах Конвертации Свойств (ПКС) для реквизита ЗаказПокупателя внутри ПКО документа-владельца (ЗакрытиеЗаказовПокупателей).
В обработчике «Перед выгрузкой» свойства напишем код:
Если ЗначениеЗаполнено(Источник.ЗаказПокупателя) Тогда
// Проверяем дату подчиненного заказа
Если Источник.ЗаказПокупателя.Дата < УзелДляОбмена.ДатаНачалаВыгрузкиДокументов Тогда
// Очищаем значение, чтобы в приемник записалась пустая ссылка
Значение = Неопределено;
КонецЕсли;
КонецЕсли;
При таком подходе в базу-приемник запишется просто пустое поле в табличной части, а сам старый заказ даже не попытается выгрузиться.
В КД 2.1 предусмотрен штатный механизм управления ссылками. Если открыть Правило Конвертации Объектов (ПКО) для ЗаказПокупателя, мы увидим настройку: «При переносе объекта по ссылке НЕ создавать новый объект, а только переносить ссылку».
Если установить этот флаг, то при обработке ссылок в табличных частях система запишет в приемнике только GUID (уникальный идентификатор), но не будет физически создавать пустую карточку документа в базе данных, если данный объект ранее не переносился.
Если нам нужно управлять этим поведением гибко (например, применять правило только для документов старше даты начала обмена), мы можем использовать специальный флаг КД 2.1 ТолькоПолучитьСсылка. В ПКО ЗаказПокупателя в обработчике «Перед выгрузкой» пропишем:
Если Источник.Дата < УзелДляОбмена.ДатаНачалаВыгрузкиДокументов Тогда
// Передаем только ссылку без создания полноценного объекта в приемнике
ТолькоПолучитьСсылка = Истина;
КонецЕсли;
Использование флага ТолькоПолучитьСсылка позволяет гибко регулировать глубину выгрузки данных, предотвращая замусоривание базы-приемника пустыми карточками документов прошлых периодов и сохраняя при этом ссылочную целостность базы данных.