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

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

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

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

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

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

Ниже разобраны основные приёмы определения типа значения с примерами кода, указаны ограничения каждого метода и типичные ошибки, которые встречаются даже у опытных разработчиков.

Функция ТипЗнч: основной способ определить тип

Функция ТипЗнч(Значение) — стандартный и наиболее часто используемый инструмент. Она принимает любое значение и возвращает объект типа Тип, описывающий его фактический тип. Работает как на сервере, так и на клиенте, в тонком и веб-клиенте.

Значение = Справочники.Номенклатура.НайтиПоКоду("000000001");

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

Сообщить(ТипЗначения); // выведет: СправочникСсылка.Номенклатура

Чаще всего результат ТипЗнч сразу сравнивают с ожидаемым типом, чтобы ветвить логику обработки. Это особенно актуально для реквизитов составного типа, например полей «Контрагент» или «ДокументОснование», где в одном поле могут храниться ссылки разных объектов.

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

// обработка реализации

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

// обработка заказа

КонецЕсли;

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

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

Функция Тип("ИмяТипа") создаёт объект типа по его строковому имени. Это обратная операция: у вас есть строка, и нужно получить тип для сравнения или для работы с ОписаниеТипов.

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

Если ТипЗнч(МоеЗначение) = ТипСсылка Тогда

Сообщить("Это ссылка на номенклатуру");

КонецЕсли;

Имена типов строятся по шаблону: для ссылочных объектов — «СправочникСсылка.ИмяСправочника», «ДокументСсылка.ИмяДокумента», для объектных значений — «СправочникОбъект.Имя», «ДокументОбъект.Имя». Примитивные типы обозначаются словами «Строка», «Число», «Булево», «Дата».

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

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

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

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

ВЫБРАТЬ

Расчеты.Регистратор

ИЗ

РегистрНакопления.РасчетыСКлиентами КАК Расчеты

ГДЕ

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

Для проверки ссылочных полей удобнее оператор ССЫЛКА: условие «Поле ССЫЛКА Справочник.Номенклатура» проверяет, что поле содержит ссылку именно на указанный справочник. Этот вариант читается проще и часто работает быстрее, чем сравнение через ТИПЗНАЧЕНИЯ.

ВЫБРАТЬ

Товары.Номенклатура

ИЗ

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

ГДЕ

Товары.Номенклатура ССЫЛКА Справочник.Номенклатура

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

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

ТипЗнч(Значение) = Тип("...")

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

ТИПЗНАЧЕНИЯ() в запросе

Только для полей запроса. Позволяет отфильтровать записи до выгрузки, что быстрее обхода результата в цикле

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

Проще и нагляднее для ссылочных полей, но проверяет только принадлежность к виду объекта, не полный тип

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

Проверяет допустимость типа по описанию реквизита, а не фактический тип значения. Нужен при работе с метаданными

Объект ОписаниеТипов и проверка допустимых типов

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

Чтобы узнать, какие типы разрешены для реквизита объекта метаданных, обращаются к свойству Тип соответствующего объекта описания:

МетаРеквизит = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Сделка;

Для Каждого ТекТип Из МетаРеквизит.Тип.Типы() Цикл

Сообщить(ТекТип);

КонецЦикла;

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

ОписаниеРеквизита = МетаРеквизит.Тип;

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

Объект.Сделка = НовоеЗначение;

КонецЕсли;

Обратная задача — привести значение к описанию типов — решается методом ПривестиЗначение(Значение). Он пытается преобразовать значение к допустимому типу, а при невозможности возвращает значение по умолчанию (пустую строку, ноль, пустую ссылку).

Как узнать тип в отладчике и через строковое представление

В режиме отладки тип значения виден сразу: в табло переменных и в окне «Вычислить выражение» (Shift+F9) рядом со значением отображается его тип. Это самый быстрый способ понять, что фактически пришло в процедуру, без изменения кода.

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

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

ЗаписьЖурналаРегистрации("Обмен", УровеньЖурналаРегистрации.Ошибка, , ,

"Получен неожиданный тип: " + ИмяТипа);

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

При разборе ошибок обмена данными полезно логировать не только текст ошибки, но и ТипЗнч проблемного параметра. Значительная часть «странных» сбоев в универсальных процедурах объясняется тем, что вместо ожидаемой ссылки пришёл объект, строка или Неопределено.
ПЗ
Практическое замечание

Особые случаи: Неопределено, NULL и примитивные типы

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

Значение NULL появляется только в результатах запросов, например при левом соединении без подходящей записи. Для него в коде предусмотрено сравнение Значение = NULL, а в запросе — конструкция ЕСТЬ NULL. Попытка вызвать методы у NULL приведёт к ошибке выполнения.

Для примитивных типов (Строка, Число, Булево, Дата) ТипЗнч работает без ограничений. Учитывайте, что число, полученное из строки неявным преобразованием, и число, заданное литералом, имеют один и тот же тип «Число» — различить их по типу нельзя.

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

Итог = Итог + Количество;

Иначе

ВызватьИсключение "Ожидалось числовое значение, получен тип: "

+ Строка(ТипЗнч(Количество));

КонецЕсли;

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

Проверка результата и контрольные точки

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

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

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

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

Ветка обработки срабатывает
Норма

Для тестового значения нужного типа выполняется нужный код

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

Ветка не срабатывает — проверьте, не сравнивается ли тип со строкой

Поведение на пустых значениях
Норма

Неопределено, NULL и пустые ссылки обрабатываются отдельными проверками

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

На пустом значении возникает ошибка выполнения

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

Возвращаются только записи с нужным типом поля

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

Пустой результат — проверьте правильность имени типа в ТИП(...)

Итог

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

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

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

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

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

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

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

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

Потому что слева объект типа Тип, а справа строка — такое сравнение всегда ложно. Правую часть нужно обернуть в функцию Тип("СправочникСсылка.Номенклатура"), тогда сравниваются два объекта типа.

Можно ли узнать тип значения в управляемой форме на клиенте?

Да, ТипЗнч и Тип доступны на клиенте, включая тонкий и веб-клиент. Однако часть типов (например, объекты СправочникОбъект) на клиенте недоступна в принципе — там работают только со ссылками и примитивными типами.

Как определить тип колонки таблицы значений?

Через свойство ТипЗначения колонки: ТЗ.Колонки.Найти("Сумма").ТипЗначения вернёт объект ОписаниеТипов. Метод Типы() этого описания перечислит все допустимые типы колонки.

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

Тип пустой ссылки совпадает с типом заполненной: для пустой ссылки справочника «Номенклатура» это СправочникСсылка.Номенклатура. Пустоту проверяют отдельно — через ЗначениеЗаполнено() или сравнение с пустой ссылкой.