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