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

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

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

Разберем причину проблемы: почему объект всё равно выгружается?

Проанализируем ситуацию, описанную в теме. Разработчик добавляет код Если Объект.ПометкаУдаления Тогда Отказ = Истина; КонецЕсли; в глобальный обработчик Перед выгрузкой объекта на уровне всей конвертации. Однако объекты продолжают выгружаться. Выясним причину этого поведения движка конвертации.

В «1С:Конвертация данных» существует два принципиально разных механизма инициации выгрузки:

  1. Непосредственная выгрузка: Когда объект выбирается правилом выгрузки данных (ПВД). Например, выгрузка всех документов «Реализация товаров и услуг» за период.
  2. Выгрузка по ссылке: Когда объект выгружается потому, что на него ссылается другой выгружаемый объект (например, склад в документе реализации).

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

Способ 1: Использование обработчика в правиле конвертации объекта (ПКО)

Проанализируем наиболее надежный способ решения. Чтобы условие срабатывало всегда — и при прямой выгрузке, и при выгрузке по ссылке — код необходимо разместить в конкретном Правиле конвертации объекта (ПКО) в событии Перед выгрузкой.

Важно помнить различие в доступных переменных. В ПКО вместо переменной Объект следует использовать переменную Источник. Рассмотрим пример кода, который нужно прописать в ПКО для каждого типа данных (Справочники, Документы):


Если Источник.ПометкаУдаления Тогда
    Отказ = Истина;
КонецЕсли;

При таком подходе, как только движок конвертации попытается выгрузить объект (неважно, через выборку или по ссылке), он обратится к ПКО, выполнит код и, встретив Отказ = Истина, прекратит процесс выгрузки данных этого объекта.

Способ 2: Универсальное решение через глобальный обработчик

Если в базе данных сотни объектов и прописывать код в каждом ПКО трудозатратно, мы можем использовать глобальный обработчик конвертации Перед выгрузкой объекта, но с правильной проверкой типов. Рассмотрим ситуацию: обработчик вызывается для всех объектов, включая наборы записей регистров или константы, у которых нет реквизита ПометкаУдаления. Это может привести к ошибке «Значение не является значением объектного типа».

Посмотрим на пример универсального безопасного кода для глобального обработчика:


// Проверяем, что Источник является ссылочным типом и имеет метаданные
Если Источник <> Неопределено Тогда
    МетаданныеОбъекта = Источник.Метаданные();
    
    // Проверяем наличие стандартного реквизита ПометкаУдаления
    // Это актуально для справочников, документов, планов видов характеристик и т.д.
    ЕстьРеквизит = Ложь;
    Если МетаданныеОбъекта.СтандартныеРеквизиты.Найти("ПометкаУдаления") <> Неопределено Тогда
        ЕстьРеквизит = Истина;
    КонецЕсли;
    
    Если ЕстьРеквизит И Источник.ПометкаУдаления Тогда
        Отказ = Истина;
    КонецЕсли;
КонецЕсли;

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

Оптимизация размера файла обмена через ПВД

Рассмотрим ситуацию, когда помеченных объектов очень много (сотни тысяч). Если мы используем Отказ = Истина в ПКО, движок конвертации всё равно сначала выбирает объект из базы, инициализирует его, а только потом отказывается от выгрузки. Это создает нагрузку на память и процессор.

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


ВЫБРАТЬ
    Ссылка
ИЗ
    Справочник.Номенклатура
ГДЕ
    ПометкаУдаления = ЛОЖЬ

Такой подход позволит сэкономить значительное время, так как помеченные объекты даже не будут переданы в обработку движку конвертации.

Проблема «битых» ссылок: на что обратить внимание?

Проанализируем важный риск. Представим, что мы запретили выгрузку помеченного на удаление Склада. Но в базе-источнике есть проведенный документ «Реализация», в котором выбран этот самый помеченный склад. При выгрузке документа ссылка на склад должна быть записана в XML.

Если мы установим Отказ = Истина для склада, то в базе-приемнике в документе реализации в поле «Склад» появится значение «Объект не найден». Это называется «битой ссылкой».

Чтобы избежать этой проблемы, рассмотрим два варианта действий:

  1. Дополнительная проверка в ПКС: В правиле конвертации свойства (ПКС) документа перед выгрузкой реквизита «Склад» проверять, не помечен ли он на удаление. Если помечен — очищать реквизит.
  2. Частичная выгрузка: Вместо полного отказа (Отказ = Истина), можно выгружать только ссылку объекта без его реквизитов. Это позволит сохранить целостность данных в приемнике, но объект там будет пустым.

Особенности иерархических справочников

Выясним еще один нюанс, связанный с папками (группами). Если справочник иерархический, и вы пометили на удаление папку, но внутри неё лежат элементы без пометки на удаление, использование Отказ = Истина для папки может привести к тому, что элементы в базе-приемнике потеряют своего родителя и переместятся в корень справочника. Проанализируем это при написании условий и, если иерархия важна, добавьте проверку ЭтоГруппа.

Итоги и рекомендации

Подведем итог нашему разбору. Для гарантированного исключения помеченных на удаление объектов:

  1. Используйте обработчик Перед выгрузкой в конкретном ПКО.
  2. Вместо Объект всегда используйте Источник.
  3. Для массовых выгрузок оптимизируйте запросы в ПВД.
  4. Помните о возможности появления «битых ссылок» и принимайте решение: либо допускать их наличие, либо очищать ссылки в документах-владельцах.

Использование данных методов позволит вам гибко управлять составом выгружаемых данных и значительно уменьшить размер XML-файла обмена, избегая передачи ненужной информации.

← На главную