Почему в КД 2.1 не срабатывает «Отказ = Истина» в обработчике «Перед выгрузкой» для Счет-фактуры в УПП?

Программист 1С v8.3 (Обычные формы) Промышленность, строительство и АПК
← На главную

При работе с механизмом «Конвертация данных 2.1» программисты часто сталкиваются с ситуацией, когда стандартные методы фильтрации объектов не приносят ожидаемого результата. Типичный пример: в правиле конвертации объекта (ПКО) прописано условие отмены выгрузки через Отказ = Истина, но при выполнении обмена объекты всё равно попадают в файл выгрузки или загружаются в приемник. Особенно часто это проявляется при работе с конфигурацией УПП 1.3 и документами типа СчетФактураПолученный.

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

Разберем причину №1: Особенности хранения оснований в УПП 1.3

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

Рассмотрим ситуацию: если в документе заполнена табличная часть ДокументыОснования, то реквизит шапки ДокументОснование может быть либо пустым, либо содержать лишь одну из ссылок (обычно первую). Если ваш код в обработчике выглядит так:


Если ТипЗнч(Источник.ДокументОснование) <> Тип("ДокументСсылка.ПоступлениеТоваровУслуг") Тогда 
    Отказ = Истина;
КонецЕсли;

То возможны два варианта некорректной работы:

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

Решение: Нам необходимо проверить не только реквизит шапки, но и содержимое табличной части. Пример кода для более надежной проверки:


// Сначала проверяем шапку
ЕстьНужноеОснование = (ТипЗнч(Источник.ДокументОснование) = Тип("ДокументСсылка.ПоступлениеТоваровУслуг"));

// Если в шапке не нашли, проверяем табличную часть (если она существует в этом релизе)
Если Не ЕстьНужноеОснование Тогда
    Для Каждого СтрокаТЧ Из Источник.ДокументыОснования Цикл
        Если ТипЗнч(СтрокаТЧ.ДокументОснование) = Тип("ДокументСсылка.ПоступлениеТоваровУслуг") Тогда
            ЕстьНужноеОснование = Истина;
            Прервать;
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

Если Не ЕстьНужноеОснование Тогда
    Отказ = Истина;
КонецЕсли;

Разберем причину №2: Выгрузка объекта по ссылке

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

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

Как с этим бороться:

  1. В ПКС (Правилах Конвертации Свойств), где передается ссылка на счет-фактуру, необходимо установить флаг «Не выгружать объекты свойств по ссылкам».
  2. Если это невозможно, продублируйте проверку типа в обработчике Перед выгрузкой самого ПКС. Там Значение — это ссылка на объект. Если условие не выполняется, установите Значение = Неопределено;.

Разберем причину №3: Кэширование правил и внешняя обработка

Выясним техническую причину, не связанную с кодом. При разработке в КД 2.1 мы часто вносим изменения в базу «Конвертация данных», сохраняем их и запускаем выгрузку в рабочей базе через обработку V8Exchan82.epf.

Посмотрим на типичные ошибки в этом процессе:

Совет по диагностике: Откройте сформированный файл выгрузки XML любым текстовым редактором и найдите секцию с вашим ПКО. Убедитесь, что ваш программный код (условие с ТипЗнч) действительно присутствует внутри файла. Если его там нет — вы работаете со старыми правилами.

Разберем причину №4: Методика «агрессивной» отладки

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

  1. Проверка попадания в процедуру: Напишите в самом начале обработчика Сообщить("Выгружаем: " + Источник);. Если при запуске выгрузки вы не видите сообщений в окне сообщений 1С, значит, управление в этот обработчик просто не заходит (например, объект выгружается через другое правило или ПКО вообще не используется).
  2. Безусловный отказ: Попробуйте написать просто Отказ = Истина; без всяких условий. Если объекты всё равно выгружаются — значит, они идут «транзитом» по ссылке из других правил (см. Причину №2).
  3. Использование прерывания: Попробуйте добавить Возврат; сразу после установки отказа. В некоторых сложных вложенных алгоритмах это помогает корректно выйти из процедуры.
  4. Проверка версии КД: Убедитесь, что вы используете актуальную версию КД (например, 2.1.8.2). Старые версии имели баги, связанные с обработкой Отказ в специфических случаях.

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

Проанализируем ситуацию с пустыми значениями. Если Источник.ДокументОснование имеет составной тип и не заполнен, ТипЗнч(Источник.ДокументОснование) может вернуть тип Неопределено или тип «пустой ссылки» первого в списке типа.

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


Если НЕ (Источник.ДокументОснование ССЫЛКА Документ.ПоступлениеТоваровУслуг) Тогда
    Отказ = Истина;
КонецЕсли;

Оператор ССЫЛКА в языке запросов работает надежно, но в коде 1С (в обработчиках КД) лучше использовать проверку через ТипЗнч или проверку метаданных. Однако помните, что пустая ссылка составного типа — это не то же самое, что пустая ссылка конкретного типа при сравнении типов через Тип().

Итог

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

  1. Проверить наличие оснований в табличных частях Счет-фактуры в УПП.
  2. Проверить ПКС всех объектов, которые могут ссылаться на Счет-фактуру.
  3. Использовать Сообщить() для подтверждения выполнения кода обработчика.
  4. Убедиться, что правила в обработке выгрузки действительно обновлены.
← На главную