К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно определить тип объекта в 1С

Способы программного определения типа объекта в 1С: функция Тип(), ТипЗнч(), Метаданные(), сравнение типов и проверка ссылок. Примеры кода и типичные ошибки.

При разработке на платформе 1С:Предприятие регулярно возникает задача понять, какой именно тип данных пришёл в переменную, параметр процедуры или реквизит объекта. Это особенно актуально при работе с составными типами, универсальными обработчиками, подписками на события и обменами данных, где заранее неизвестно, с каким объектом придётся иметь дело.

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

Материал разбирает все основные способы с примерами кода, объясняет, чем отличается проверка типа значения от проверки типа ссылки, и показывает, как безопасно строить ветвление логики в зависимости от типа объекта.

Функция ТипЗнч() — базовый способ определить тип значения

Функция ТипЗнч() возвращает тип переданного ей значения. Это основной инструмент, когда нужно понять, что находится в переменной: строка, число, ссылка на справочник, таблица значений или что-то иное.

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

Если ТипЗначения = Тип("СправочникСсылка.Номенклатура") Тогда

// обработка ссылки на номенклатуру

КонецЕсли;

Результат вызова — значение специального типа «Тип». Его можно сравнивать с другими значениями типа «Тип» операторами равенства и неравенства, но нельзя напрямую приводить к строке для сравнения. Если нужно вывести тип в сообщение, используйте Строка(ТипЗнч(Значение)) или передачу в Сообщить().

Важно понимать: ТипЗнч() работает с фактическим значением, а не с объявленным типом реквизита. Если реквизит имеет составной тип «СправочникСсылка.Контрагенты или СправочникСсылка.Организации», функция вернёт тип конкретного хранящегося значения.

Функция Тип() — задание типа для сравнения

Функция Тип() принимает строковое имя типа и возвращает соответствующее значение типа «Тип». Именно так формируется правая часть сравнения при проверке. Имена ссылочных типов строятся по шаблону: вид объекта метаданных, точка, имя объекта — например, ДокументСсылка.РеализацияТоваровУслуг или СправочникСсылка.Контрагенты.

Для примитивных типов используются короткие имена: Тип("Строка"), Тип("Число"), Тип("Дата"), Тип("Булево"). Для коллекций — Тип("Массив"), Тип("Структура"), Тип("ТаблицаЗначений").

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

bsl
Если Метаданные.НайтиПоПолномуИмени("Справочник.Партнеры") <> Неопределено Тогда
    Если ТипЗнч(Значение) = Тип("СправочникСсылка.Партнеры") Тогда
        // тип существует в конфигурации и совпал
    КонецЕсли;
КонецЕсли;

Метод Метаданные() — определение вида ссылочного объекта

У ссылочных значений (ссылки на справочники, документы, планы счетов и другие) есть метод Метаданные(), возвращающий объект описания метаданных. Через него можно получить имя объекта, его вид и полное имя — это удобно, когда нужно не просто сравнить тип, а построить универсальную логику.

ИмяОбъекта = Ссылка.Метаданные().Имя;              // "Номенклатура"

ПолноеИмя = Ссылка.Метаданные().ПолноеИмя(); // "Справочник.Номенклатура"

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

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

Проверка принадлежности к группе типов

Часто нужно ответить не на вопрос «это документ такого-то вида?», а на более общий: «это вообще ссылка?», «это любой документ?», «это перечисление?». Для этого платформа предоставляет предопределённые описания типов у менеджеров объектов.

  • Справочники.ТипВсеСсылки() — все ссылочные типы справочников;
  • Документы.ТипВсеСсылки() — все ссылочные типы документов;
  • Перечисления.ТипВсеСсылки() — все типы перечислений;
  • ПланыОбмена.ТипВсеСсылки(), ПланыСчетов.ТипВсеСсылки() и аналогично для других видов.

Проверка выполняется методом СодержитТип():

Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда

// значение — ссылка на какой-то документ

КонецЕсли;

Для отличия ссылки от объекта (например, СправочникСсылка от СправочникОбъект) есть отдельные описания: Справочники.ТипВсеСсылкиДополнительныхОбъектов() не существует, поэтому объектные типы проверяют прямым сравнением — ТипЗнч(Объект) = Тип("СправочникОбъект.Номенклатура") — либо по наличию свойства ЭтоНовый().

Сравнение подходов: когда какой метод выбирать

ЗадачаИнструментОграничение
Точный тип значенияТипЗнч() + Тип()Имя типа должно существовать в конфигурации
Вид объекта как строкаМетаданные().ПолноеИмя()Только для ссылочных и объектных значений
Принадлежность к группе (любой документ)ТипВсеСсылки().СодержитТип()Не различает конкретные виды
Объект метаданных по имениМетаданные.НайтиПоПолномуИмени()Возвращает Неопределено при отсутствии

Практическое правило: если ветвление зависит от одного-двух конкретных типов — используйте прямое сравнение ТипЗнч() = Тип(), оно самое быстрое и читаемое. Если логика универсальная и должна работать с произвольными видами объектов — переходите на Метаданные() и строковые имена. Для фильтрации «ссылка или нет» применяйте ТипВсеСсылки().

Маршрут решения

Как выбрать способ проверки

Нужно проверить один конкретный типИспользуйте ТипЗнч(Значение) = Тип("ИмяТипа")
Нужно отличить ссылку от примитивного значенияПроверьте через Справочники.ТипВсеСсылки() и аналоги других менеджеров
Нужно универсально обработать любые объектыПолучите ПолноеИмя() через Метаданные() и ветвитесь по строке
Конфигурация может не содержать нужный типСначала проверьте Метаданные.НайтиПоПолномуИмени() на Неопределено

Типичные ошибки при определении типа

Типичные ошибки
01
Сравнение типа со строкой: ТипЗнч(Х) = "Строка" всегда даёт Ложь, правильно — ТипЗнч(Х) = Тип("Строка")
02
Путаница между ссылкой и объектом: проверка на СправочникСсылка не срабатывает для СправочникОбъект
03
Вызов Метаданные() у примитивного значения приводит к ошибке выполнения
04
Обращение к Тип() с именем объекта, которого нет в конфигурации, вызывает исключение
05
Проверка типа Неопределено: ТипЗнч(Неопределено) возвращает тип Неопределено, что надо обрабатывать отдельно

Отдельно стоит сказать про значение NULL, которое приходит из запросов при левых соединениях. ТипЗнч(NULL) вернёт тип «NULL», и сравнение с ожидаемым ссылочным типом даст Ложь. Если переменная может содержать NULL из запроса, проверяйте это до основной логики типов.

Ещё одна ловушка — даты с пустым значением. Пустая дата '00010101' имеет тип «Дата», поэтому проверка типа пройдёт успешно, но логика, ожидающая заполненную дату, сработает неверно. Тип и заполненность значения — независимые проверки.

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

Соберём типовую функцию, которая принимает произвольное значение и возвращает строковое описание того, что в нём находится. Такой код часто нужен при отладке, логировании и построении универсальных обменов.

Функция ОписаниеТипаЗначения(Значение) Экспорт

ТипЗначения = ТипЗнч(Значение);

Если Значение = Неопределено Тогда

Возврат "Неопределено";

ИначеЕсли Справочники.ТипВсеСсылки().СодержитТип(ТипЗначения) Тогда

Возврат "Ссылка на справочник: " + Значение.Метаданные().Имя;

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

Возврат "Ссылка на документ: " + Значение.Метаданные().Имя;

Иначе

Возврат "Примитивный тип или коллекция: " + Строка(ТипЗначения);

КонецЕсли;

КонецФункции

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

Контрольные точки

Как проверить результат

Сравнение типов
Норма

Условие срабатывает для ожидаемых значений и не срабатывает для чужих

Тревожный признак

Условие всегда Ложь — вероятно, тип сравнивается со строкой

Вызов Метаданные()
Норма

Возвращается объект с корректным Имя и ПолноеИмя

Тревожный признак

Ошибка выполнения — значение не ссылочного типа

Универсальный обработчик
Норма

Каждый вид значения попадает в свою ветку

Тревожный признак

Ссылки попадают в ветку примитивов — нарушен порядок проверок

Часто задаваемые вопросы

Как определить тип значения в запросе 1С?

В языке запросов используется оператор «ВЫРАЗИТЬ» для приведения типов и функция ТИПЗНАЧЕНИЯ() в сочетании с ТИП() для сравнения: ГДЕ ТИПЗНАЧЕНИЯ(Поле) = ТИП(Справочник.Номенклатура). Для проверки ссылочности поля применяют конструкцию ССЫЛКА, например: ГДЕ Поле ССЫЛКА Справочник.Контрагенты.

Чем ТипЗнч() отличается от Тип()?

ТипЗнч() принимает значение и возвращает его фактический тип. Тип() принимает строку с именем типа и возвращает сам тип для сравнения. Первая функция отвечает на вопрос «что это?», вторая формирует эталон для проверки.

Как проверить, что значение — именно объект, а не ссылка?

Сравните тип с объектным вариантом: ТипЗнч(Значение) = Тип("ДокументОбъект.РеализацияТоваровУслуг"). Универсальный признак объекта — наличие метода ЭтоНовый(), но вызывать его можно только после подтверждения объектного типа.

Как узнать тип реквизита объекта метаданных?

Через метаданные конфигурации: Метаданные.Справочники.Номенклатура.Реквизиты.ИмяРеквизита.Тип вернёт описание типов реквизита. Метод СодержитТип() этого описания позволяет проверить, допускает ли реквизит конкретный тип.

Почему сравнение ТипЗнч(Х) = "Строка" не работает?

Потому что слева значение типа «Тип», а справа строка — это разные типы данных, и сравнение всегда даёт Ложь без ошибки. Правильная форма: ТипЗнч(Х) = Тип("Строка").

Можно ли определить тип без жёсткой привязки к конфигурации?

Да. Получайте полное имя через Метаданные() самого значения и работайте со строкой, а наличие нужного типа проверяйте через Метаданные.НайтиПоПолномуИмени(). Так код не упадёт, если объекта нет в конкретной конфигурации.

Итог

Что важно запомнить

Основная пара инструментов — ТипЗнч() для получения типа значения и Тип() для задания эталона сравнения. Для ссылок дополнительно доступен Метаданные() с именем и видом объекта, а групповые проверки выполняются через ТипВсеСсылки(). Ссылка и объект — разные типы, а сравнение типа со строкой всегда даёт Ложь.