Как программно отменить выгрузку объектов в 1С:Конвертации данных, если Отказ = Истина в ПКО не работает?

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

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

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

Причина 1: Некорректный синтаксис и типы данных

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

Проанализируем этот момент. Хотя в некоторых старых версиях платформы 1С числовое значение 1 могло неявно приводиться к булевому значению Истина, в современных версиях и жестких условиях компиляции кода это может приводить к ошибкам или игнорированию флага. Настоятельно рекомендуем использовать только явное булево значение:

Отказ = Истина;

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

Причина 2: Выгрузка объектов по ссылкам (самая частая причина)

Рассмотрим основной механизм КД 2.1, из-за которого чаще всего не срабатывает блокировка в ПКО. Допустим, у нас есть справочник «Номенклатура», в реквизитах или табличных частях которого содержатся ссылки на справочник «Наборы упаковок».

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

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

Как решить эту проблему?

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

Сделаем это по шагам:

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

// Проверяем, заполнено ли свойство в источнике
Если ЗначениеЗаполнено(Источник.НаборУпаковок) Тогда
    // Если набор упаковок помечен на удаление или его коэффициент равен 1
    Если Источник.НаборУпаковок.ПометкаУдаления Или Источник.НаборУпаковок.Коэффициент = 1 Тогда
        // Отменяем выгрузку этого свойства для текущей Номенклатуры
        Отказ = Истина; 
    КонецЕсли;
КонецЕсли;

При таком подходе родительский объект («Номенклатура») выгрузится с пустым значением реквизита «НаборУпаковок», а сам нежелательный набор упаковок вообще не будет инициирован к выгрузке по этой ссылке.

Причина 3: Кэширование объектов при выгрузке

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

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

Причина 4: Использование Правил выгрузки данных (ПВД)

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

Разберем пример кода для обработчика «Перед выгрузкой» в ПВД:


// Обратите внимание: в ПВД используется переменная "Объект" вместо "Источник"
Если Объект.ПометкаУдаления Или Объект.Коэффициент = 1 Тогда
    Отказ = Истина;
КонецЕсли;

Установка отказа на уровне ПВД гарантирует, что объект даже не начнет передаваться в ПКО для последующей конвертации.

Причина 5: Радикальный обход ограничений через очистку Источника

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


Если Источник.ПометкаУдаления Или Источник.Коэффициент = 1 Тогда
    Отказ = Истина;
    Источник = Неопределено; // Полностью разрываем связь с объектом для КД
КонецЕсли;

Установка переменной Источник в значение Неопределено сигнализирует выгрузчику КД, что объекта физически не существует для обработки, и предотвращает даже частичную генерацию XML-узлов для ссылки.

Резюме и рекомендации

Для того чтобы ваша программная отмена выгрузки в КД 2.1 работала стабильно, рекомендуем придерживаться следующего алгоритма:

  1. Всегда используйте точный синтаксис Отказ = Истина;.
  2. Если объекты продолжают выгружаться, проанализируйте файл выгрузки: скорее всего, они тянутся по ссылкам из реквизитов других объектов. Настройте фильтрацию в ПКС этих объектов-владельцев.
  3. При выгрузке через ПВД дублируйте условия отбора в обработчике «Перед выгрузкой» ПВД.
  4. В сложных случаях используйте комбинацию Отказ = Истина; Источник = Неопределено; в ПКО.
← На главную