При настройке одностороннего обмена данными (например, выгрузка из УТ 10.3 в Бухгалтерию предприятия 3.0) часто возникает ситуация, когда бухгалтеры в базе-приемнике вручную корректируют счета учета в документах. Однако при повторной выгрузке того же документа из источника все ручные изменения затираются значениями по умолчанию. Рассмотрим подробно, как настроить правила конвертации данных (КД 2.0) таким образом, чтобы реквизиты уже существующих документов оставались неизменными, а новые документы заполнялись полностью.
По умолчанию механизм обмена в КД 2.0 настроен на полную синхронизацию объекта (существует также вариант RabbitMQ + КД2 для передачи по одному объекту). Если объект найден по полям поиска (что часто случается, если используются правила обмена УТ 10.3 - БП 3.0), программа считывает данные из файла и записывает их «поверх» существующих в базе. Чтобы изменить это поведение, необходимо использовать обработчики событий и встроенные механизмы конфигурации-приемника. Проанализируем основные способы решения этой задачи.
Если нам нужно защитить от перезаписи не весь документ, а только конкретный реквизит (например, СчетУчета в табличной части), наиболее эффективным методом является настройка в Правилах Конвертации Свойств (ПКС). Разберем этот процесс по шагам:
ПоступлениеТоваровУслуг.СчетУчета (или аналогичный в табличной части).
Если ОбъектНайден Тогда
Отказ = Истина;
КонецЕсли;
Параметр ОбъектНайден принимает значение Истина, если документ уже существует в базе-приемнике. Установка Отказ = Истина в данном контексте означает, что именно это свойство не будет загружено из файла, и старое значение в базе сохранится.
Проанализируем специфику Бухгалтерии предприятия 3.0. Даже если вы запретите загрузку счета в правилах, он может «перепрыгнуть» на значение по умолчанию в момент записи объекта. Это происходит из-за того, что при изменении номенклатуры в коде документа срабатывают обработчики, автоматически подставляющие счета из регистра сведений «Счета учета номенклатуры».
Чтобы подавить это поведение при обмене, нужно передать специальный флаг в структуру дополнительных свойств объекта. В обработчике «После загрузки» (ПКО документа) можно добавить следующий код:
// Отключаем стандартные механизмы пересчета счетов БП 3.0
Объект.ДополнительныеСвойства.Вставить("ПересчитатьСчетаУчета", Ложь);
Это заставит типовые подписки на события и процедуры модуля объекта проигнорировать заполнение счетов, оставив те данные, которые уже были в документе (или те, что мы запретили перезаписывать в первом способе).
Если логика бизнес-процесса подразумевает, что после первичного попадания документа в бухгалтерию он становится «священным» и не должен меняться вообще (даже если изменились суммы или количество), можно использовать флаг НеЗамещатьОбъект. Рассмотрим, как это реализовать в обработчике «При загрузке» в ПКО:
Если ОбъектНайден Тогда
НеЗамещатьОбъект = Истина;
КонецЕсли;
В этом случае программа найдет ссылку на существующий документ, но не будет выполнять чтение атрибутов и табличных частей из файла обмена. Это максимально быстрый, но радикальный способ защиты данных.
Частая ошибка разработчиков заключается в том, что они правят файл xml с правилами, загружают его в настройку обмена в конфигураторе, но не видят изменений в поведении системы. В современных конфигурациях на базе БСП (как БП 3.0) правила часто хранятся внутри базы данных.
Чтобы изменения вступили в силу, выполните следующие действия:
Только после загрузки в режиме «1С:Предприятие» новые обработчики начнут работать.
При написании кода в обработчиках КД 2.0 важно не путать контексты:
ДокументОбъект). Мы работаем с его реквизитами напрямую: Объект.Комментарий.ДокументСсылка). Из нее можно только читать данные, например: Ссылка.Товары.НайтиСтроки(...).Рассмотрим пример в обработчике «После загрузки», если нужно программно восстановить счет из базы:
Если ОбъектНайден Тогда
Для Каждого СтрокаТовары Из Объект.Товары Цикл
// Пытаемся найти соответствующую строку в старом документе по номеру строки или номенклатуре
// и вернуть старый счет учета
СтараяСтрока = Ссылка.Товары.Найти(СтрокаТовары.Номенклатура, "Номенклатура");
Если СтараяСтрока <> Неопределено Тогда
СтрокаТовары.СчетУчета = СтараяСтрока.СчетУчета;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Этот подход позволяет гибко управлять процессом: обновлять количества и цены, но сохранять специфические бухгалтерские аналитики (счета учета, субконто), которые были настроены вручную после первичной загрузки.