Выгрузка документа по условию

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий… А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

На мозговых штурмах начинают предлагать самые фантастические варианты: от нового реквизита документа до специального регистра, от запроса в базу приемник до сохранения регистрации изменений предыдущих выгрузок.

Самый лаконичный способ в этой ситуации: на стороне источника выгружать такие объекты всегда, а на стороне приемника включить такую логику:

ДокументДолженБытьВыгружен = ...;
Объект.ПометкаУдаления = Данные.ПометкаУдаления ИЛИ НЕ ДокументДолженБытьВыгружен;
Если Объект.ЭтоНовый() И Объект.ПометкаУдаления Тогда
Отказ = Истина;
КонецЕсли;
Объект.Проведен = Данные.Проведен и Не Объект.ПометкаУдаления;

Разберемся в том, как это работает:

  1. Во-первых понятно, что из источника документ отправляется всегда, т.е. нет ситуаций когда документ изменился, а этот код в приемнике не выполнился.
  2. В ДокументДолженБытьВыгружен вычисляется соответствующее булево значение, под Объект понимается заполняемый объект, а под Данные — те данные, которые пришли из источника.
  3. Если документ ранее не записывался в приемнике и по нашим условиям не должен — он не запишется (есть одна фича: если в источнике документ "сразу" стал помечен на удаление — тогда в приемник он отже не запишется).
  4. Если документ начал (не важно: сразу или с 3-й попытки) соответствовать условиям выгрузки — он будет записан.
  5. Если документ в какой-то момент перестал соответствовать условиям загрузки — он будет помечен на удаление в приемнике.

Отметим также, что такой подход будет успешно работать как в полностью самописном обмене, так и в обмене по правилам обмена.

Минус такого подхода один: паразитная нагрузка на обмен. Если не рассматривать вариант "у нас таких не много — руками поправим", единственная альтернатива предложенному подходу — "помнить" отправляли мы ненужный документ в приемник или нет, если не отправляли — не отправлять, если отправляли — отправить пометку удаления.
Такая оптимизация избавит нас от выгрузки какого-то количества заведомо ненужных документов, но во-первых не всегда в источнике можно определить нужен ли документ в приемнике, во-вторых такой подход хоть и является более строгим, он добавляет объекты метаданных и содержит куда более сложную логику, которую нужно будет потом поддерживать.
Нужно опираться на ожидаемое количество отказов: если отказ будет выдан 10% документов — вероятно, паразитной нагрузкой можно пренебречь, а если ожидается поступление в приемник 10% документов — это совсем другое дело.

Бонус: самый лаконичный способ выбора режима записи

Если Объект.Проведен Тогда
Режим = РежимЗаписиДокумента.Проведение;
ИначеЕсли Объект.Ссылка.Проведен Тогда
Режим = РежимЗаписиДокумента.ОтменаПроведения;
Иначе
Режим = РежимЗаписиДокумента.Запись;
КонецЕсли;
Объект.Записать(Режим);

 

2 Comments

  1. sergey_garin

    Прочитал, ничего не понял. Можно суть обозначить как-то?

    Reply
  2. e-9

    (1) да уж, такого сферически безупречного коня в идеальном вакууме встречать еще не приходилось…)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *