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

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

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

Архитектурные ограничения механизма выгрузки

Проанализируем ключевую особенность платформенного механизма конвертации: в КД 2.x отсутствует автоматический каскадный отказ «снизу вверх». Это означает следующее:

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

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

Способ 1. Фильтрация на этапе выгрузки с динамическим получением списка значений

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

Разберем по шагам реализацию этого механизма:

  1. В глобальном обработчике «Перед выгрузкой данных» обойдем коллекцию правил конвертации значений для нужного перечисления и сохраним во входящую коллекцию параметров только те значения источника, у которых сопоставлен приемник:
    
    СписокРазрешенных = Новый Массив;
    
    // Ищем правило конвертации значений для требуемого перечисления
    Для Каждого Правило Из ПравилаКонвертацииЗначений Цикл
        Если Правило.Имя = "СтатусыОбъектов" Тогда
            Для Каждого СтрокаПКЗ Из Правило.Строки Цикл
                Если ЗначениеЗаполнено(СтрокаПКЗ.ЗначениеПриемника) Тогда
                    СписокРазрешенных.Добавить(СтрокаПКЗ.ЗначениеИсточника);
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    
    Параметры.Вставить("РазрешенныеСтатусы", СписокРазрешенных);
    
  2. В обработчике «Перед выгрузкой» ПКО родительского документа выполним проверку реквизита справочника через полученный список:
    
    ЗначениеРеквизита = Источник.РеквизитСправочник.РеквизитПеречисление;
    
    Если Параметры.РазрешенныеСтатусы.Найти(ЗначениеРеквизита) = Неопределено Тогда
        Отказ = Истина;
    КонецЕсли;
    

При таком подходе любое изменение состава ПКЗ в правилах обмена автоматически скорректирует условия фильтрации без правки программного кода обработчиков.

Способ 2. Оптимизация выборки через запрос в ПВД

Если документов в базе много, проверка каждого объекта в обработчике «Перед выгрузкой» может создавать избыточную нагрузку на дисковую подсистему. Оптимальным решением будет отсечение неподходящих данных на этапе выборки в Правилах выгрузки данных (ПВД).

Для этого в соответствующем ПВД переключим способ выборки на Произвольный алгоритм и используем запрос с соединением:


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

Запрос.УстановитьПараметр("РазрешенныеСтатусы", Параметры.РазрешенныеСтатусы);
ВыборкаДанных = Запрос.Выполнить().Выгрузить();

В этом случае платформа даже не будет считывать лишние документы из информационной базы для сериализации, что существенно сократит время выполнения обмена.

Способ 3. Отмена на стороне загрузки

Если фильтрацию по определенным причинам требуется перенести на сторону приемника, проанализируем порядок выполнения обработчиков событий загрузки в ПКО:

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

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


// Если перечисление не сопоставилось в ПКЗ, в реквизит объекта запишется пустое значение
Если Не ЗначениеЗаполнено(Объект.РеквизитПеречисление) Тогда
    Отказ = Истина;
КонецЕсли;

Важное предостережение: отмена записи справочника на этапе загрузки не отменяет автоматическую загрузку документа, который на него ссылается. Если документ будет записан, в его реквизите появится битая ссылка («Объект не найден»). Поэтому отсечение документов на стороне загрузки требует синхронной проверки и отмены записи как самого справочника, так и всех ссылающихся на него документов.

← На главную