Как в 1С определить, является ли значение справочником, документом или другим типом объекта

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

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

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

Способ 1. Использование универсального метода Метаданные.НайтиПоТипу()

Проанализируем наиболее надежный и универсальный подход. Он хорош тем, что корректно обрабатывает и ссылки (CatalogRef), и объекты (CatalogObject). Суть метода заключается в получении описания объекта метаданных по типу переданного значения.

Рассмотрим пример реализации:


// Переменная Значение может содержать ссылку или объект
МетаОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Значение));

Если МетаОбъекта <> Неопределено Тогда
    Если Метаданные.Документы.Содержит(МетаОбъекта) Тогда
        Сообщить("Это документ: " + МетаОбъекта.Имя);
    ИначеЕсли Метаданные.Справочники.Содержит(МетаОбъекта) Тогда
        Сообщить("Это справочник: " + МетаОбъекта.Имя);
    ИначеЕсли Метаданные.Отчеты.Содержит(МетаОбъекта) Тогда
        Сообщить("Это отчет: " + МетаОбъекта.Имя);
    Иначе
        Сообщить("Это тип: " + МетаОбъекта.ПолноеИмя());
    КонецЕсли;
КонецЕсли;

Почему это лучший вариант? Метод Метаданные.НайтиПоТипу() возвращает объект типа ОбъектМетаданных. После этого мы просто проверяем, входит ли этот объект в соответствующую коллекцию (Документы, Справочники и т.д.) с помощью метода Содержит(). Это работает стабильно и не зависит от языка интерфейса платформы.

Способ 2. Проверка через коллекции типов (только для ссылок)

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

Посмотрим на код проверки:


ТипПроверяемогоЗначения = ТипЗнч(Значение);

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

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

Способ 3. Анализ полного имени метаданных

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


ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Значение));
Если ОбъектМетаданных <> Неопределено Тогда
    ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); // Вернет, например, "Справочник.Контрагенты"
    
    Если СтрНачинаетсяС(ПолноеИмя, "Справочник") Тогда
        Сообщить("Работаем со справочником");
    ИначеЕсли СтрНачинаетсяС(ПолноеИмя, "Документ") Тогда
        Сообщить("Работаем с документом");
    КонецЕсли;
КонецЕсли;

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

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

Если ваша конфигурация разработана на основе БСП, крайне рекомендуется использовать готовые функции из модуля ОбщегоНазначения. Это делает код более читаемым и соответствующим стандартам разработки фирмы «1С».

Проанализируем полезные функции БСП:

  1. ОбщегоНазначения.ЭтоСсылка(Значение) — позволяет быстро отличить ссылочный тип от примитивного или объектного.
  2. ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Имя") — используется для получения данных, но также полезна для косвенной проверки существования объекта.
  3. ОбщегоНазначения.МенеджерОбъектаПоСсылке(Ссылка) — возвращает менеджер (например, Справочники.Номенклатура), через который можно программно выполнять действия с объектом.

Способ 5. Работа с XML-типами (строковое представление типа)

Существует «хитрый» способ через сериализацию типа в XML. Он возвращает внутреннее имя типа платформы, которое не зависит от локализации (всегда на английском или всегда по стандарту XML).


ИмяТипаXML = XMLТип(ТипЗнч(Значение)).ИмяТипа;
Если Найти(ИмяТипаXML, "Catalog") > 0 Тогда
    Сообщить("Это справочник (в терминах XML)");
КонецЕсли;

Метод специфичен и чаще используется в механизмах обмена данными, но его полезно знать как альтернативу, когда стандартные средства метаданных по какой-то причине недоступны (хотя в 1С 8.x такое бывает редко).

Важные нюансы и рекомендации

При выборе способа проверки учитывайте следующие моменты:

  1. Производительность: Обращение к Метаданные.НайтиПоТипу() достаточно быстрое, но если вы делаете это в цикле на 100 000 итераций, лучше один раз кэшировать типы в соответствие или массив.
  2. Попытка-Исключение: При обращении к методу Значение.Метаданные() напрямую (без НайтиПоТипу), программа может вызвать ошибку, если у значения нет этого метода (например, у Числа или Строки). Всегда проверяйте тип или используйте Попытку.
  3. Универсальность: Не забывайте, что помимо справочников и документов существуют ПланыВидовХарактеристик, Задачи, БизнесПроцессы и ПланыОбмена. Если вы пишете по-настоящему универсальный механизм (например, логирование изменений), ваш код должен уметь обрабатывать и их.

Подводя итог, можно сказать, что для большинства повседневных задач программиста 1С оптимальным является Способ №1 (через Метаданные.НайтиПоТипу), так как он наиболее полно и безопасно отвечает на вопрос о принадлежности значения к объектам конфигурации.

← На главную