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