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

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

Как получить тип в 1С: способы определения и проверки типов значений

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

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

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

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

Функция ТипЗначения: получаем тип конкретного значения

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

Пример базового использования:

Значение = 123.45;

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

Сообщить(ТипЗначенияПеременной); // выведет: Число

Если ТипЗначения(Значение) = Тип("Число") Тогда

Сообщить("Это число");

КонецЕсли;

Для ссылочных значений функция возвращает точный тип ссылки, например СправочникСсылка.Номенклатура или ДокументСсылка.РеализацияТоваровУслуг. Это позволяет различать не просто «ссылка или примитив», а конкретный вид объекта метаданных.

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

Сокращённая форма ТипЗнч и типичные проверки

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

Типовая проверка значения перед обращением к его свойствам выглядит так:

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

Артикул = Параметр.Артикул;

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

// обработка строкового представления

Иначе

ВызватьИсключение "Неподдерживаемый тип параметра";

КонецЕсли;

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

Функция Тип(): формируем тип по строковому имени

Функция Тип("ИмяТипа") создаёт объект типа по его строковому имени. Имена примитивных типов: "Число", "Строка", "Дата", "Булево". Имена ссылочных типов строятся по шаблону "ВидОбъекта.ИмяОбъекта": "СправочникСсылка.Контрагенты", "ДокументСсылка.ЗаказКлиента", "ПеречислениеСсылка.СтавкиНДС".

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

ИмяТипа = "ДокументСсылка." + ИмяДокумента;

Попытка

НужныйТип = Тип(ИмяТипа);

Исключение

Сообщить("Тип не найден: " + ИмяТипа);

Возврат;

КонецПопытки;

Дополнительный приём — получение имени типа в обратную сторону через XML-сериализацию (XMLТипЗнч()) или через метаданные: Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)) вернёт объект описания метаданных, из которого доступны имя, представление и полное имя вида «Документ.РеализацияТоваровУслуг».

Типичные ошибки
01
Сравнение значения с типом напрямую: Если Парам = Тип("Число") — условие никогда не выполнится, нужно ТипЗнч(Парам) = Тип("Число")
02
Использование Тип("Документ.Заказ") вместо Тип("ДокументСсылка.Заказ") — это разные типы: объект и ссылка
03
Формирование Тип() по имени без проверки: после переименования объекта метаданных код падает с исключением
04
Ожидание, что ТипЗнч(Неопределено) вернёт тип «ожидаемого» значения — возвращается тип Неопределено

Различие ссылочных типов и объектных типов

Частая ловушка для начинающих — различие между СправочникСсылка.Имя и СправочникОбъект.Имя. Ссылка — это лёгкий идентификатор записи в базе, объект — загруженная в память редактируемая копия данных. В переменных, параметрах запросов и реквизитах почти всегда хранятся ссылки; объект появляется только после вызова Ссылка.ПолучитьОбъект() или при создании нового элемента через Справочники.Имя.СоздатьЭлемент().

Проверка «это ссылка вообще на любой объект» выполняется через метод Справочники.ТипВсеСсылки() и аналогичные:

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

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

КонецЕсли;

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

Сравнение вариантов проверки

ТипЗнч(Зн) = Тип("Имя")

Точная проверка на конкретный тип. Подходит, когда ожидается один-два типа. Неудобна для проверки «любая ссылка»

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

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

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

Позволяет получить имя и вид объекта по типу ссылки. Возвращает Неопределено для примитивных типов — это нужно учитывать

Определение типа в запросах

В языке запросов встроенный язык недоступен, поэтому там свои конструкции. Оператор ТИПЗНАЧЕНИЯ(Поле) возвращает тип значения поля, а литерал ТИП(Справочник.Номенклатура) задаёт конкретный тип для сравнения. Обратите внимание: в запросах имя типа указывается без кавычек и без слова «Ссылка».

ВЫБРАТЬ

Регистр.Регистратор КАК Регистратор

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК Регистр

ГДЕ

ТИПЗНАЧЕНИЯ(Регистр.Регистратор) = ТИП(Документ.ПоступлениеТоваровУслуг)

Для полей составного типа (например, регистратор регистра накопления) полезна проверка Поле ССЫЛКА Документ.ЗаказКлиента — она возвращает Истина, если значение является ссылкой указанного вида, и корректно работает в соединениях и условиях.

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

Порядок безопасной работы с составным полем в запросе
  1. 1
    Определите возможные типы поля через конфигуратор: свойства реквизита, состав типа
  2. 2
    Отфильтруйте записи условием ТИПЗНАЧЕНИЯ(Поле) = ТИП(Вид.Имя) или Поле ССЫЛКА Вид.Имя
  3. 3
    Приведите поле через ВЫРАЗИТЬ(Поле КАК НужныйТип) перед обращением к реквизитам
  4. 4
    Проверьте результат запроса в консоли запросов на реальных данных с разными типами
  5. 5
    Убедитесь, что план запроса не содержит лишних соединений по всем таблицам составного типа

Типы в СКД, динамических списках и на форме

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

На управляемой форме тип реквизита задан метаданными и меняется только программно через ИзменитьРеквизиты() с новым объектом ОписаниеТипов. Описание типов создаётся конструктором: Новый ОписаниеТипов("СправочникСсылка.Номенклатура") или набором типов через массив: Новый ОписаниеТипов(МассивТипов). Для примитивов задаются квалификаторы — длина строки, точность числа, состав даты.

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

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

Проверка результата и границы безопасной работы

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

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

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

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

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

Условие ТипЗнч(Зн) = Тип("Имя") срабатывает на ожидаемых значениях

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

Условие никогда не выполняется — вероятно, перепутаны Ссылка/Объект или имя типа

Запрос с ТИПЗНАЧЕНИЯ
Норма

Возвращаются только записи нужного вида объекта

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

Пустой результат при наличии данных — имя типа в ТИП() указано с ошибкой

ВЫРАЗИТЬ перед обращением к реквизиту
Норма

Запрос выполняется, реквизит заполнен для подходящих записей

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

Ошибка «поле не найдено» или заметное замедление запроса

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

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

Ничем, кроме написания. Это два имени одной функции встроенного языка: полное и сокращённое. Результат, поведение и производительность идентичны, выбор — вопрос стиля кодирования, принятого в проекте.

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

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

Почему Тип("Документ.ЗаказКлиента") вызывает ошибку?

Потому что корректные имена ссылочных типов — «ДокументСсылка.ЗаказКлиента» или «ДокументОбъект.ЗаказКлиента». Формат «Документ.Имя» используется в языке запросов в конструкции ТИП(Документ.ЗаказКлиента), но не во встроенном языке.

Как узнать имя объекта метаданных по ссылке?

Через Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).Имя или через свойство ссылки Ссылка.Метаданные().Имя — второй способ короче и не требует отдельного вызова ТипЗнч. Полное имя вида «Документ.РеализацияТоваровУслуг» даёт свойство ПолноеИмя().

Можно ли получить тип значения в запросе без сравнения?

Да, ТИПЗНАЧЕНИЯ(Поле) можно вывести как поле выборки — в результате запроса появится колонка с типом каждого значения. Это удобно для анализа составных полей, например чтобы увидеть, какие виды документов выступают регистраторами регистра.

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

Для Неопределено — тип «Неопределено». Значение NULL существует только в результатах запросов; при передаче в код его тип определяется как «Null». Проверки на эти значения лучше выполнять прямым сравнением: Значение = Неопределено или Значение = NULL.

Итог

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

Во встроенном языке тип получают через ТипЗнч(Значение) и сравнивают с Тип("ИмяТипа"); в запросах — через ТИПЗНАЧЕНИЯ(Поле) и ТИП(Вид.Имя). Различайте ссылку и объект, сужайте составные поля через ВЫРАЗИТЬ, а динамически формируемые имена типов проверяйте, чтобы избежать исключений.