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

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

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

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

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

Во встроенном языке 1С для этого существуют две функции: Тип() и ТипЗнч() (в английском синтаксисе — Type() и TypeOf()). Они решают разные задачи: первая возвращает тип по его имени, вторая определяет тип конкретного значения. Понимание разницы между ними — ключ к корректным проверкам.

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

Функции Тип() и ТипЗнч(): в чём разница

Функция Тип(ИмяТипа) принимает строковое имя типа и возвращает объект типа «Тип». Она не анализирует никакое значение — просто создаёт описание типа по имени. Например, Тип("СправочникСсылка.Контрагенты") вернёт тип ссылки на справочник «Контрагенты».

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

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

// работаем со ссылкой на контрагента

КонецЕсли;

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

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

Примитивные типы проверяются тем же способом, но имена указываются в единственном числе: "Строка", "Число", "Дата", "Булево". Это полезно при разборе данных из файлов, HTTP-запросов и при работе с параметрами произвольного типа.

Если ТипЗнч(Параметр) = Тип("Число") Тогда

Сумма = Сумма + Параметр;

ИначеЕсли ТипЗнч(Параметр) = Тип("Строка") Тогда

Комментарий = Параметр;

КонецЕсли;

Важный нюанс: значение Неопределено и значение Null — это не типы, а специальные значения. Проверка ТипЗнч(Значение) = Тип("Неопределено") вызовет ошибку, так как типа с таким именем не существует. Для них используются прямые сравнения: Если Значение = Неопределено Тогда или Если Значение = Null Тогда.

Для проверки заполненности примитивных значений удобнее функция ЗначениеЗаполнено(), которая корректно отрабатывает пустые строки, нулевые даты, нулевые числа и пустые ссылки одновременно — без необходимости расписывать типы вручную.

Типичные ошибки
01
Попытка проверить Неопределено через Тип("Неопределено") — такого типа нет, возникает ошибка; сравнивайте значение напрямую с Неопределено или Null.
02
Сравнение типа со строкой: ТипЗнч(Знч) = "Строка" всегда ложно, потому что слева объект типа, а справа строка; нужно ТипЗнч(Знч) = Тип("Строка").
03
Опечатка в имени объекта метаданных внутри Тип() — ошибка проявится только в момент выполнения, а не при проверке модуля.

Проверка ссылочных типов: справочники, документы, перечисления

Ссылочные типы именуются по шаблону «ВидОбъекта.ИмяОбъекта»: СправочникСсылка.Номенклатура, ДокументСсылка.РеализацияТоваровУслуг, ПеречислениеСсылка.СтавкиНДС. Имя объекта должно в точности совпадать с именем в конфигураторе.

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

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

ИНН = Плательщик.ИНН;

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

ИНН = Плательщик.ИНН;

КонецЕсли;

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

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

// значение — ссылка на любой справочник

КонецЕсли;

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

Метод ТипЗначения() и описание типов

Метод ТипЗначения() встречается у прикладных объектов: у элементов управления формами, у колонок таблиц значений, у полей компоновки данных. Он возвращает объект «ОписаниеТипов» — не одиночный тип, а допустимый набор типов реквизита или колонки.

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

ОписаниеТипов = Новый ОписаниеТипов("СправочникСсылка.Номенклатура,СправочникСсылка.Услуги");

Если ОписаниеТипов.СодержитТип(ТипЗнч(Значение)) Тогда

// тип входит в допустимый список

КонецЕсли;

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

Проверка типа в запросах и через строковое представление

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

ВЫБРАТЬ

Реализация.Контрагент

ИЗ

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

ГДЕ

Реализация.Контрагент ССЫЛКА Справочник.Контрагенты

Функция ВЫРАЗИТЬ(... КАК Справочник.Контрагенты) не проверяет, а приводит тип: если значение другого вида, результатом будет пустая ссылка или NULL в зависимости от контекста. Это используют для сужения составного типа поля в запросе.

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

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

ТипЗнч() = Тип(...)

Основной способ в коде модулей. Точный, но требует знать конкретное имя объекта метаданных.

ТипВсеСсылки().СодержитТип()

Проверка принадлежности к классу объектов (любой справочник, любой документ) без перечисления видов.

ССЫЛКА в запросе

Фильтрация по типу прямо в запросе; не применима вне языка запросов.

ОписаниеТипов.СодержитТип()

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

Практический порядок действий и проверка результата

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

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

Признак корректно написанной проверки — код не падает с ошибкой «Поле объекта не обнаружено» при любом допустимом значении реквизита. Если ошибка возникает, значит какая-то ветка типа не учтена: обычно это пустая ссылка другого вида или значение Неопределено из необязательного параметра.

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

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

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

Возвращает ожидаемый тип, ветвление срабатывает в нужной ветке

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

Тип отличается от ожидаемого — проверьте источник значения

Работа с составным реквизитом
Норма

Код обрабатывает все виды ссылок из состава типа

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

Ошибка «Поле объекта не обнаружено» на одном из видов

Обработка пустых значений
Норма

Пустые ссылки и Неопределено отсеиваются до обращения к реквизитам

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

Пустое значение проходит в ветку и вызывает ошибку

В продуктивных базах полезно логировать неожиданные типы через ЗаписьЖурналаРегистрации() вместо вызова исключения, если пропуск значения не критичен. Это позволяет собрать статистику реальных данных и доработать алгоритм без остановки обменов и регламентных заданий.

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

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

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

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

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

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

Как проверить значение на Неопределено или Null?

Прямым сравнением: Если Значение = Неопределено Тогда ... или Если Значение = Null Тогда. Через функцию Тип() это сделать нельзя — типов с такими именами не существует, и попытка вызовет ошибку.

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

Потому что ТипЗнч() возвращает объект типа «Тип», а не строку. Сравнение объекта со строкой всегда даёт Ложь. Правильный вариант: ТипЗнч(Знч) = Тип("Строка").

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

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

Что вернёт ТипЗнч() для пустой ссылки?

Полноценный тип ссылки, например СправочникСсылка.Номенклатура. Пустота значения на тип не влияет, поэтому проверку типа при необходимости дополняют функцией ЗначениеЗаполнено() или сравнением с ПустаяСсылка().

Итог

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

Проверка типа в 1С строится на паре функций: ТипЗнч() определяет фактический тип значения, Тип() задаёт тип по имени для сравнения. Для классов объектов используйте ТипВсеСсылки().СодержитТип(), в запросах — оператор ССЫЛКА, для Неопределено и Null — прямое сравнение. Всегда отдельно обрабатывайте пустые значения и непредусмотренные типы.