Как определить тип источника в обработчике ПКО в Конвертации данных?

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

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

Разберем подробно, почему это происходит и как правильно и безопасно определять тип источника в любых сценариях выгрузки.

Почему Сообщить() выводит синоним типа, а не его системное имя

Выясним причину такого поведения. Функция ТипЗнч() возвращает системный объект типа Тип, который точно идентифицирует тип переданного значения в памяти платформы.

Процедура Сообщить() принимает на вход строку. Если передать в нее значение типа Тип, платформа неявно выполняет строковое преобразование (аналогично вызову Строка(ТипЗнч(Источник))). Для типов прикладных объектов строковое представление по умолчанию формируется на основе синонима объекта конфигурации в пользовательском представлении. Именно поэтому на экран выводятся пробелы и русскоязычные наименования, хотя внутри системы тип сохраняет свою строгую типизацию.

Способ 1. Прямое сравнение с конкретным типом

Если необходимо проверить, относится ли Источник к конкретному документу или справочнику, воспользуемся функцией Тип() и прямым сравнением типов. Посмотрим на пример кода:


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

Такое условие отработает корректно независимо от того, как строковое представление типа выводится в окно сообщений.

Способ 2. Проверка через ТипВсеСсылки и почему падает Источник.Ссылка

Когда требуется проверить принадлежность источника к целому классу метаданных (например, узнать, является ли он любым документом), разработчики часто используют метод Документы.ТипВсеСсылки().

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

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

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


Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник)) Тогда
    // Источник является ссылкой на документ
ИначеЕсли Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Источник)) Тогда
    // Источник является ссылкой на справочник
КонецЕсли;

Важное ограничение: метод ТипВсеСсылки() содержит только ссылочные типы (ДокументСсылка.*). Если в обработчик передан объект данных (например, ДокументОбъект.*), данная проверка вернет Ложь.

Способ 3. Универсальная проверка через объект метаданных

Рассмотрим наиболее надежный способ, который одинаково работает как со ссылками (Ссылка), так и с объектами (Объект), не вызывая исключений при обработке нестандартных данных:


МетаданныеИсточника = Метаданные.НайтиПоТипу(ТипЗнч(Источник));

Если МетаданныеИсточника <> Неопределено Тогда
    Если Метаданные.Документы.Содержит(МетаданныеИсточника) Тогда
        // Обработка любого документа (как ДокументСсылка, так и ДокументОбъект)
    ИначеЕсли Метаданные.Справочники.Содержит(МетаданныеИсточника) Тогда
        // Обработка любого справочника (как СправочникСсылка, так и СправочникОбъект)
    КонецЕсли;
КонецЕсли;

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

  1. МетаданныеИсточника.Имя — возвращает имя объекта конфигурации (например, РеализацияТоваровУслуг).
  2. МетаданныеИсточника.ПолноеИмя() — возвращает имя с классом метаданных (например, Документ.РеализацияТоваровУслуг).

Способ 4. Использование функций Библиотеки Стандартных Подсистем (БСП)

Если конфигурация-источник построена на базе БСП, разберем безопасные методы общего модуля ОбщегоНазначения:


// Проверка на то, что переданное значение является любой ссылкой
Если ОбщегоНазначения.ЭтоСсылка(Источник) Тогда
    // Работа со ссылочным типом
КонецЕсли;

// Проверка принадлежности к документам или справочникам
Если ОбщегоНазначения.ЭтоДокумент(Источник) Тогда
    // Обработка документа
ИначеЕсли ОбщегоНазначения.ЭтоСправочник(Источник) Тогда
    // Обработка справочника
КонецЕсли;

Для безопасного чтения ссылки из объекта без риска получить исключение можно использовать функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Источник, "Ссылка").

Рекомендации по организации правил в КД

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

  1. Ориентироваться на предопределенную переменную обработчика ИмяПКО, в которой содержится строковое имя текущего правила конвертации.
  2. Разделять выгрузку разнородных объектов на отдельные ПКО и ПВД (Правила выгрузки данных), настраивая фильтрацию на этапе выборки данных, а не внутри универсального обработчика.
← На главную