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

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

Как сравнить типы данных в 1С

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

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

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

В материале разобраны основные приёмы: как получить тип значения, как сравнить его с эталоном, как проверить значение реквизита составного типа, как сравнивать сами значения с учётом типа и какие ошибки встречаются чаще всего. Примеры приведены для встроенного языка 1С:Предприятие 8.3.

Что такое тип данных в 1С и как он хранится

Каждое значение во встроенном языке 1С имеет тип: Число, Строка, Дата, Булево, ссылочные типы (СправочникСсылка, ДокументСсылка и другие), а также объектные типы. Тип определяет, какие операции допустимы со значением и как оно сравнивается с другими значениями.

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

Имена типов для функции Тип() пишутся без пробелов: «СправочникСсылка.Номенклатура», «ДокументСсылка.РеализацияТоваровУслуг», «Число», «Строка», «Дата», «Булево». Ошибка в имени (лишний пробел, опечатка в имени объекта метаданных) приведёт к исключению во время выполнения, поэтому строковые литералы стоит проверять особенно внимательно.

Базовое сравнение типа через ТипЗнч и Тип

Стандартная конструкция проверки типа выглядит так:

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

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

КонецЕсли;

Этот приём работает для любых типов — примитивных и ссылочных. Для примитивных типов имена простые: Тип("Число"), Тип("Строка"), Тип("Дата"), Тип("Булево"). Для ссылочных типов указывается полное имя: вид объекта метаданных, точка, имя объекта в конфигурации.

Если нужно проверить несколько допустимых типов, условия объединяют через ИЛИ:

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

Или ТипЗнч(Значение) = Тип("СправочникСсылка.Услуги") Тогда

// значение — ссылка на один из двух справочников

КонецЕсли;

Обратный сценарий — убедиться, что значение НЕ относится к типу — пишется через оператор неравенства: Если ТипЗнч(Значение) <> Тип("Строка") Тогда. Это удобно для раннего выхода из процедуры при некорректном параметре.

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

Сравнение значений с учётом типа

Оператор равенства в 1С сравнивает не только содержимое, но и типы. Значение 1 (Число) не равно значению "1" (Строка) и не равно Истина (Булево). Это строгое поведение отличает 1С от языков с неявным приведением типов и одновременно является источником ошибок при работе с данными из внешних источников.

Типичная ситуация: данные загружены из файла или получены через веб-сервис, и числовой код пришёл как строка. Сравнение КодИзФайла = НомерИзБазы вернёт Ложь, даже если визуально значения совпадают. Перед сравнением значение нужно привести к нужному типу функциями Число(), Строка(), Дата() или через ОписаниеТипов.

Для ссылок сравнение через = сравнивает именно ссылки, а не реквизиты объектов. Две ссылки равны, только если указывают на один и тот же объект одного и того же вида. Ссылка на справочник «Номенклатура» никогда не будет равна ссылке на документ, даже если у них совпадают представления.

Проверка реквизитов составного типа

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

Типовой шаблон обработки составного типа:

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

ИНН = Строка.Контрагент.ИНН;

ИначеЕсли ТипЗнч(Строка.Контрагент) = Тип("СправочникСсылка.Организации") Тогда

ИНН = Строка.Контрагент.ИНН;

Иначе

ИНН = "";

КонецЕсли;

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

Порядок проверки составного типа
  1. 1
    Получите тип значения: ТекущийТип = ТипЗнч(Значение)
  2. 2
    Сравните его с ожидаемыми типами через Тип("ИмяТипа")
  3. 3
    Для каждого подходящего типа выполните свою ветку обработки
  4. 4
    В ветке Иначе предусмотрите поведение для непредусмотренных типов
  5. 5
    Проверьте результат на тестовых данных каждого вида

Сравнение типов в запросах

В языке запросов 1С проверка типа выполняется иначе — через функцию ТИПЗНАЧЕНИЯ() и оператор ССЫЛКА. Конструкция выглядит так:

ВЫБРАТЬ

ВЫБОР

КОГДА ТИПЗНАЧЕНИЯ(Таблица.Контрагент) = ТИП(Справочник.Контрагенты)

ТОГДА "Контрагент"

ИНАЧЕ "Прочее"

КОНЕЦ КАК ВидКонтрагента

ИЗ Документ.РеализацияТоваровУслуг КАК Таблица

Дополнительно в запросах есть оператор ССЫЛКА для условий: ГДЕ Таблица.Поле ССЫЛКА Справочник.Номенклатура. Он проверяет, является ли значение ссылкой указанного вида, и часто читается проще, чем сравнение через ТИПЗНАЧЕНИЯ. Для приведения составного типа к конкретному используется ВЫРАЗИТЬ(Поле КАК Справочник.Номенклатура) — после этого к реквизитам справочника можно обращаться напрямую.

Важно помнить: функции ТипЗнч() и Тип() из встроенного языка в тексте запроса недоступны. Смешение двух синтаксисов — частая ошибка начинающих разработчиков.

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

ТипЗнч + Тип во встроенном языке

Универсальный способ для кода. Подходит для любых типов, но требует точного строкового имени типа.

ТИПЗНАЧЕНИЯ и ССЫЛКА в запросе

Работает только в тексте запроса. Позволяет фильтровать и группировать данные по типу на стороне СУБД.

Метаданные.НайтиПоТипу

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

Типичные ошибки при сравнении типов

Самая распространённая ошибка — сравнение типа со строкой: Если ТипЗнч(Значение) = "Число" Тогда. Такое условие всегда ложно, потому что слева объект типа, а справа строка. Правильный вариант — ТипЗнч(Значение) = Тип("Число").

Вторая частая проблема — опечатки и лишние пробелы в имени типа внутри Тип(). Строка "СправочникСсылка. Номенклатура" с пробелом после точки вызовет исключение. Если имя типа формируется динамически, его стоит собирать из метаданных, а не писать вручную.

Третья группа ошибок связана с Неопределено и NULL. Значение Неопределено имеет собственный тип, и ТипЗнч(Неопределено) вернёт тип «Неопределено», а не тип ожидаемого реквизита. Перед проверкой типа значения из запроса стоит отдельно обработать NULL через ЕСТЬ NULL в запросе или проверку Значение = Неопределено в коде.

Типичные ошибки
01
Сравнение ТипЗнч(Значение) со строкой вместо Тип("ИмяТипа") — условие всегда ложно
02
Сравнение числа со строкой без приведения — условие молча не срабатывает
03
Пропуск обработки NULL и Неопределено перед проверкой типа — ошибка или неверная ветка логики
04
Использование синтаксиса встроенного языка внутри текста запроса — ошибка компиляции запроса

Как проверить корректность сравнения

Надёжный способ убедиться, что проверка типа написана верно, — отладчик. Поставьте точку останова на условии и посмотрите в табло значение ТипЗнч(Значение): платформа покажет тип значения, и его можно сравнить с тем, что ожидается в условии.

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

Сообщить("Тип значения: " + ТипЗнч(Значение));

Объект типа при преобразовании в строку выводит читаемое имя типа, что позволяет быстро увидеть расхождение между фактическим и ожидаемым типом. Для ссылочных значений дополнительно полезно вывести само значение — по представлению часто видно, какого вида объект пришёл на самом деле.

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

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

Значение ТипЗнч() в отладчике
Норма

Показанный тип совпадает с именем в Тип()

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

Тип отличается — условие не сработает

Результат сравнения значений
Норма

Равные по смыслу значения дают Истина

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

Визуально равные значения дают Ложь — вероятно, разные типы

Обработка NULL из запроса
Норма

NULL заменён через ЕСТЬNULL или проверен отдельно

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

NULL попадает в сравнение и ломает логику

Частые вопросы

Чем отличается ТипЗнч от Тип в 1С?

ТипЗнч(Значение) принимает значение и возвращает его тип. Тип("ИмяТипа") не требует значения — она создаёт объект типа по строковому имени. В паре они используются для сравнения: тип фактического значения сравнивается с типом-эталоном.

Можно ли сравнить тип со строкой напрямую?

Нет. Сравнение ТипЗнч(Значение) = "Число" всегда возвращает Ложь, потому что объект типа и строка — разные сущности. Строку нужно сначала преобразовать в тип функцией Тип().

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

Через метаданные: получить объект метаданных по типу (Метаданные.НайтиПоТипу) и проверить, принадлежит ли он к коллекции справочников, например через Метаданные.Справочники.Содержит(ОбъектМетаданных). Перечислять все виды справочников через ИЛИ не требуется.

Почему сравнение "равных" значений возвращает Ложь?

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

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

Используйте ТИПЗНАЧЕНИЯ(Поле) = ТИП(Справочник.ИмяСправочника) в конструкции ВЫБОР или условие Поле ССЫЛКА Справочник.ИмяСправочника в секции ГДЕ. Функции встроенного языка в запросе недоступны.

Что вернёт ТипЗнч для Неопределено и NULL?

Для Неопределено функция вернёт специальный тип «Неопределено». Для NULL из запроса — тип «NULL». Оба не совпадут ни с одним прикладным типом, поэтому такие значения нужно обрабатывать отдельными проверками до основной логики сравнения типов.

Итог

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

Тип значения получают через ТипЗнч(), эталонный тип — через Тип("ИмяТипа"), сравнивают их оператором равенства. Значения разных типов никогда не равны, поэтому перед сравнением данные приводят к одному типу. В запросах используются ТИПЗНАЧЕНИЯ и ССЫЛКА, а NULL и Неопределено обрабатываются отдельно.