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

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

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

Рассмотрим подробно два основных подхода к решению этой задачи: программный отказ от записи в базе-приемнике и оптимизацию регистрации изменений на стороне источника.

Способ 1. Проверка изменений в обработчике «После загрузки» (в базе-приемнике)

Разберем по шагам, как работает механизм загрузки в правилах конвертации. При чтении объекта из XML-файла создается экземпляр объекта в оперативной памяти приемника, и в него переносятся реквизиты из источника. Прежде чем объект будет физически записан в информационную базу приемника, вызывается обработчик события «После загрузки» правила конвертации объекта (ПКО).

В этом событии доступны ключевые переменные:

  1. Объект — заполненный объект в памяти приемника с новыми значениями из файла обмена;
  2. Объект.Ссылка — ссылка на существующий в базе документ (если объект был найден по полям поиска);
  3. Отказ — булевый флаг, установка которого в значение Истина отменяет выполнение стандартного метода Объект.Записать().

Если Объект.Ссылка пустая (или объект новый), прерывать запись не нужно — документ должен создаться. Если же ссылка найдена, мы можем прочитать текущие данные из базы и сравнить их с новыми значениями, пришедшими в Объект. Если ключевые реквизиты совпадают, мы выставляем Отказ = Истина.

Посмотрим на пример реализации в обработчике «После загрузки» ПКО:


Если Не Объект.ЭтоНовый() Тогда
    
    // Считываем текущие значения из базы через запрос или обращение к ссылке
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Док.СуммаДокумента КАК СуммаДокумента,
        |	Док.Контрагент КАК Контрагент,
        |	Док.Проведен КАК Проведен
        |ИЗ
        |	Документ.РеализацияТоваровУслуг КАК Док
        |ГДЕ
        |	Док.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        // Сравниваем значимые реквизиты
        РеквизитыНеИзменились = (Выборка.СуммаДокумента = Объект.СуммаДокумента)
            И (Выборка.Контрагент = Объект.Контрагент)
            И (Выборка.Проведен = Объект.Проведен);
        
        Если РеквизитыНеИзменились Тогда
            // Отменяем запись объекта, чтобы не вызывать лишнюю блокировку и перезапись
            Отказ = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецЕсли;

При таком подходе установка флага Отказ = Истина в событии «После загрузки» не прерывает общий процесс обмена данными и не генерирует критических ошибок в журнале регистрации. Система просто пропускает вызов записи для данного конкретного документа и переходит к следующему объекту файла.

Особенности сравнения табличных частей и версий данных

Проанализируем ситуацию, когда необходимо проверять не только реквизиты шапки, но и табличные части (например, список товаров):

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

Способ 2. Фильтрация выгрузки на узле плана обмена (в базе-источнике)

Проверка изменений на этапе загрузки увеличивает нагрузку на СУБД приемника, так как для каждого объекта требуется выполнять дополнительные запросы на чтение. Наиболее производительным и архитектурно правильным решением является предотвращение выгрузки неизмененных объектов еще на стороне базы-источника.

Рассмотрим, как настроить отбор на источнике:

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

Важные нюансы при отмене записи

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

  1. Режим загрузки: По умолчанию обмен выполняется со свойством Объект.ОбменДанными.Загрузка = Истина. Это отключает проверки и пересчеты в модуле объекта приемника.
  2. Проведение документов: Если для документа настроена автоматическая запись в режиме проведения (РежимЗаписиДокумента.Проведение), отмена записи через Отказ = Истина сохранит документ и его движения в исходном состоянии, но если вместе с документом выгружались связанные независимые регистры сведений, необходимо контролировать их синхронность.
← На главную