При выгрузке обмена данными через механизмы конвертации данных (КД 2.0 / Универсальный обмен данными XML) часто возникает необходимость отфильтровать выгружаемые объекты по определенному условию — например, по подразделению или организации. Попытка написать универсальный код фильтрации в глобальном или локальном обработчике ПередКонвертациейОбъекта может привести к сбою выгрузки с различными ошибками.
Рассмотрим детально, почему происходят такие ошибки и как правильно реализовать условие отбора выгружаемых объектов без сбоев системы.
Проанализируем две наиболее частые ошибки, возникающие при попытке получить реквизиты объекта через параметр Источник в событии ПередКонвертациейОбъекта:
Источник.Метаданные().Реквизиты, когда в качестве источника выступает ссылочный тип перечисления (ПеречислениеСсылка). Метод Метаданные() у перечисления возвращает объект метаданных, но у него нет коллекции Реквизиты (вместо неё используется коллекция ЗначенияПеречисления)..Метаданные() у объектов, которые не поддерживают этот метод напрямую. Например, запись регистра сведений (РегистрСведенийЗапись), ключ записи регистра или значение примитивного типа (Строка, Число, Дата, Структура), передаваемое в конвертацию.Кроме того, ошибочной является практика проверки типа через синонимы или строковое представление Строка(Источник.Метаданные()) или Строка(Источник). Представления метаданных зависят от языка конфигурации и синонимов, поэтому проверки вида Найти(Строка(Источник), "ДокументСсылка") работают некорректно или дают ложные результаты.
Чтобы избежать обращения к несуществующим свойствам и методам, сначала проверим, является ли параметр Источник документом или справочником. Для этого определим объект метаданных через глобальную функцию Метаданные.НайтиПоТипу() и проверим его принадлежность к нужной коллекции.
Рассмотрим пример кода в обработчике ПередКонвертациейОбъекта:
ПодразделениеФильтр = Справочники.ПодразделенияОрганизаций.НайтиПоКоду("СВ0000028");
// Получаем объект метаданных по типу выгружаемого источника
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Источник));
Если ОбъектМД <> Неопределено Тогда
// Проверяем, что выгружаемый объект является документом
Если Метаданные.Документы.Содержит(ОбъектМД) Тогда
// Безопасно проверяем наличие реквизита в метаданных документа
ИмяРеквизита = "";
Если ОбъектМД.Реквизиты.Найти("Подразделение") <> Неопределено Тогда
ИмяРеквизита = "Подразделение";
ИначеЕсли ОбъектМД.Реквизиты.Найти("РК_ПодразделениеОрганизации") <> Неопределено Тогда
ИмяРеквизита = "РК_ПодразделениеОрганизации";
КонецЕсли;
Если ЗначениеЗаполнено(ИмяРеквизита) Тогда
ЗначениеПодразделения = Источник[ИмяРеквизита];
Если ЗначениеЗаполнено(ЗначениеПодразделения) Тогда
Если НЕ (ЗначениеПодразделения.ПринадлежитЭлементу(ПодразделениеФильтр)
ИЛИ ЗначениеПодразделения = ПодразделениеФильтр) Тогда
// Отменяем выгрузку данного документа
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Альтернативный подход заключается в использовании метода СодержитТип() у системных типов ссылок. Это позволяет в одну строку определить, относится ли параметр Источник к документам или справочникам.
Разберем пример такой проверки:
// Проверяем, является ли источник документом
Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник)) Тогда
ОбъектМД = Источник.Метаданные();
// Проверяем наличие реквизита "Подразделение"
РеквизитМД = ОбъектМД.Реквизиты.Найти("Подразделение");
Если РеквизитМД <> Неопределено Тогда
Если Источник.Подразделение <> ПодразделениеФильтр Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
При отмене выгрузки объектов с помощью установки флага Отказ = Истина в событиях правил конвертации объектов (ПКО) важно учитывать следующие нюансы работы механизмов 1С:
Отказ = Истина в событиях ПКО предотвращает самостоятельную выгрузку объекта. Однако если отменяемый документ указан в реквизите другого выгружаемого документа, он все равно может записаться в файл обмена как ссылка или объект по правилам выгрузки подчиненного свойства (ПКС). Чтобы полностью исключить ссылку, следует устанавливать ВыгрузитьОбъект = Ложь в обработчике ПередВыгрузкой соответствующего ПКС.Для более чистой и производительной настройки обменов рекомендуется выполнять фильтрацию на следующих уровнях: