Разработка и Конфигурация · 11 мин
Как узнать тип значения в 1С
Разбираем способы определить тип значения в 1С: функции ТипЗначения и ТипЗнч, проверка типа в запросе, работа с ОписаниеТипов, типичные ошибки и примеры кода.
При разработке и доработке конфигураций 1С регулярно возникает задача определить, какого типа значение хранится в переменной, реквизите или колонке таблицы. Это нужно при обработке составных типов, при универсальных проверках перед вызовом методов, при разборе данных из обмена и при отладке, когда поведение кода зависит от фактического типа переданного параметра.
Платформа 1С:Предприятие предоставляет несколько встроенных механизмов для этого: функции ТипЗнч и Тип, объект ОписаниеТипов, оператор сравнения типов, а также возможности языка запросов. Каждый способ имеет свою область применения, и неправильный выбор приводит либо к лишним вычислениям, либо к ошибкам логики.
Ниже разобраны основные приёмы определения типа значения с примерами кода, указаны ограничения каждого метода и типичные ошибки, которые встречаются даже у опытных разработчиков.
Функция ТипЗнч: основной способ определить тип
Функция ТипЗнч(Значение) — стандартный и наиболее часто используемый инструмент. Она принимает любое значение и возвращает объект типа Тип, описывающий его фактический тип. Работает как на сервере, так и на клиенте, в тонком и веб-клиенте.
Значение = Справочники.Номенклатура.НайтиПоКоду("000000001");
ТипЗначения = ТипЗнч(Значение);
Сообщить(ТипЗначения); // выведет: СправочникСсылка.Номенклатура
Чаще всего результат ТипЗнч сразу сравнивают с ожидаемым типом, чтобы ветвить логику обработки. Это особенно актуально для реквизитов составного типа, например полей «Контрагент» или «ДокументОснование», где в одном поле могут храниться ссылки разных объектов.
Если ТипЗнч(Основание) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
// обработка реализации
ИначеЕсли ТипЗнч(Основание) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
// обработка заказа
КонецЕсли;
Важно понимать: ТипЗнч возвращает тип именно фактического значения, а не тип, объявленный в метаданных. Если реквизит описан как составной, функция покажет тип конкретного значения, которое сейчас лежит в переменной.
Функция Тип: получение типа по имени
Функция Тип("ИмяТипа") создаёт объект типа по его строковому имени. Это обратная операция: у вас есть строка, и нужно получить тип для сравнения или для работы с ОписаниеТипов.
ТипСсылка = Тип("СправочникСсылка.Номенклатура");
Если ТипЗнч(МоеЗначение) = ТипСсылка Тогда
Сообщить("Это ссылка на номенклатуру");
КонецЕсли;
Имена типов строятся по шаблону: для ссылочных объектов — «СправочникСсылка.ИмяСправочника», «ДокументСсылка.ИмяДокумента», для объектных значений — «СправочникОбъект.Имя», «ДокументОбъект.Имя». Примитивные типы обозначаются словами «Строка», «Число», «Булево», «Дата».
Частая задача — проверить, является ли значение ссылкой вообще, без привязки к конкретному виду объекта. Для этого используют проверку через метаданные или через общие модули типовых конфигураций, например ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) в конфигурациях на БСП.
- 1Получите значение реквизита в переменную
- 2Проверьте значение на Неопределено и NULL, если оно могло прийти из запроса
- 3Вызовите ТипЗнч(Значение) и сравните с нужным типом через Тип("ИмяТипа")
- 4В ветках обработки используйте методы, допустимые только для этого типа
- 5Выведите в журнал или сообщение тип значения, если ни одна ветка не сработала
Как узнать тип значения в запросе
В языке запросов 1С аналогом ТипЗнч служит функция ТИПЗНАЧЕНИЯ(Поле). Она возвращает тип значения поля и применяется в условиях отбора, когда нужно выбрать записи только с определённым типом в составном поле.
ВЫБРАТЬ
Расчеты.Регистратор
ИЗ
РегистрНакопления.РасчетыСКлиентами КАК Расчеты
ГДЕ
ТИПЗНАЧЕНИЯ(Расчеты.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)
Для проверки ссылочных полей удобнее оператор ССЫЛКА: условие «Поле ССЫЛКА Справочник.Номенклатура» проверяет, что поле содержит ссылку именно на указанный справочник. Этот вариант читается проще и часто работает быстрее, чем сравнение через ТИПЗНАЧЕНИЯ.
ВЫБРАТЬ
Товары.Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Номенклатура ССЫЛКА Справочник.Номенклатура
Ограничение: ТИПЗНАЧЕНИЯ и ССЫЛКА работают только внутри запроса. Если данные уже выгружены в таблицу значений или выборку, тип проверяют обычной функцией ТипЗнч в коде.
Сравнение способов проверки типа
Универсальный способ в коде. Подходит для любых значений, но имя типа пишется строкой и не контролируется при компиляции
Только для полей запроса. Позволяет отфильтровать записи до выгрузки, что быстрее обхода результата в цикле
Проще и нагляднее для ссылочных полей, но проверяет только принадлежность к виду объекта, не полный тип
Проверяет допустимость типа по описанию реквизита, а не фактический тип значения. Нужен при работе с метаданными
Объект ОписаниеТипов и проверка допустимых типов
ОписаниеТипов — объект, который описывает набор допустимых типов и квалификаторы (длину строки, точность числа, состав даты). Он используется в метаданных реквизитов, в колонках таблиц значений и при программном создании описаний.
Чтобы узнать, какие типы разрешены для реквизита объекта метаданных, обращаются к свойству Тип соответствующего объекта описания:
МетаРеквизит = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Сделка;
Для Каждого ТекТип Из МетаРеквизит.Тип.Типы() Цикл
Сообщить(ТекТип);
КонецЦикла;
Метод СодержитТип(Тип) проверяет, входит ли конкретный тип в описание. Это удобно при универсальных обработках: перед тем как присвоить значение реквизиту, можно убедиться, что его тип допустим, и избежать ошибки преобразования.
ОписаниеРеквизита = МетаРеквизит.Тип;
Если ОписаниеРеквизита.СодержитТип(ТипЗнч(НовоеЗначение)) Тогда
Объект.Сделка = НовоеЗначение;
КонецЕсли;
Обратная задача — привести значение к описанию типов — решается методом ПривестиЗначение(Значение). Он пытается преобразовать значение к допустимому типу, а при невозможности возвращает значение по умолчанию (пустую строку, ноль, пустую ссылку).
Как узнать тип в отладчике и через строковое представление
В режиме отладки тип значения виден сразу: в табло переменных и в окне «Вычислить выражение» (Shift+F9) рядом со значением отображается его тип. Это самый быстрый способ понять, что фактически пришло в процедуру, без изменения кода.
Если нужно получить имя типа строкой, например для записи в журнал регистрации или в сообщение об ошибке, объект Тип преобразуется в строку неявно или через Строка(ТипЗнч(Значение)):
ИмяТипа = Строка(ТипЗнч(Параметр));
ЗаписьЖурналаРегистрации("Обмен", УровеньЖурналаРегистрации.Ошибка, , ,
"Получен неожиданный тип: " + ИмяТипа);
Для ссылочных значений есть нюанс: Строка(Ссылка) вернёт представление объекта (например, наименование), а не тип. Поэтому тип всегда получают именно через ТипЗнч, а не через строковое преобразование самого значения.
При разборе ошибок обмена данными полезно логировать не только текст ошибки, но и ТипЗнч проблемного параметра. Значительная часть «странных» сбоев в универсальных процедурах объясняется тем, что вместо ожидаемой ссылки пришёл объект, строка или Неопределено.
Особые случаи: Неопределено, NULL и примитивные типы
Значение Неопределено имеет собственный тип, который корректно возвращается функцией ТипЗнч. Однако сравнивать значение с Неопределено нужно напрямую (Значение = Неопределено), а не через тип — так код читается однозначнее.
Значение NULL появляется только в результатах запросов, например при левом соединении без подходящей записи. Для него в коде предусмотрено сравнение Значение = NULL, а в запросе — конструкция ЕСТЬ NULL. Попытка вызвать методы у NULL приведёт к ошибке выполнения.
Для примитивных типов (Строка, Число, Булево, Дата) ТипЗнч работает без ограничений. Учитывайте, что число, полученное из строки неявным преобразованием, и число, заданное литералом, имеют один и тот же тип «Число» — различить их по типу нельзя.
Если ТипЗнч(Количество) = Тип("Число") Тогда
Итог = Итог + Количество;
Иначе
ВызватьИсключение "Ожидалось числовое значение, получен тип: "
+ Строка(ТипЗнч(Количество));
КонецЕсли;
Проверка результата и контрольные точки
После внедрения проверки типа убедитесь, что логика срабатывает на всех реально встречающихся вариантах. Составные реквизиты в базе часто содержат значения, о которых разработчик забыл: устаревшие виды документов, ссылки из обменов, пустые ссылки.
Полезный приём — временно добавить ветку «Иначе» с записью фактического типа в журнал регистрации. За несколько дней работы в журнале накопится реальная картина того, какие типы приходят в обработку, и можно будет убрать лишние ветки или добавить недостающие.
Как проверить результат
Для тестового значения нужного типа выполняется нужный код
Ветка не срабатывает — проверьте, не сравнивается ли тип со строкой
Неопределено, NULL и пустые ссылки обрабатываются отдельными проверками
На пустом значении возникает ошибка выполнения
Возвращаются только записи с нужным типом поля
Пустой результат — проверьте правильность имени типа в ТИП(...)
Что важно запомнить
В коде тип определяют через ТипЗнч(Значение) и сравнивают с Тип("ИмяТипа"), в запросе — через ТИПЗНАЧЕНИЯ() или ССЫЛКА. Допустимые типы реквизита смотрят через ОписаниеТипов и метод СодержитТип. Значения Неопределено и NULL проверяют отдельно, до обращения к методам.
Частые вопросы
Чем отличается ТипЗнч от Тип?
ТипЗнч(Значение) возвращает тип конкретного переданного значения, а Тип("Имя") создаёт объект типа по строковому имени. Обычно они используются в паре: тип значения сравнивают с типом, полученным по имени.
Как проверить, что значение — ссылка на любой справочник?
Универсального оператора «любой справочник» нет. В конфигурациях на БСП используют ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) для проверки ссылочности в целом, а принадлежность к справочникам определяют через метаданные: Метаданные.НайтиПоТипу(ТипЗнч(Значение)) и проверку, что найденный объект — справочник.
Почему сравнение ТипЗнч(Значение) = "СправочникСсылка.Номенклатура" не работает?
Потому что слева объект типа Тип, а справа строка — такое сравнение всегда ложно. Правую часть нужно обернуть в функцию Тип("СправочникСсылка.Номенклатура"), тогда сравниваются два объекта типа.
Можно ли узнать тип значения в управляемой форме на клиенте?
Да, ТипЗнч и Тип доступны на клиенте, включая тонкий и веб-клиент. Однако часть типов (например, объекты СправочникОбъект) на клиенте недоступна в принципе — там работают только со ссылками и примитивными типами.
Как определить тип колонки таблицы значений?
Через свойство ТипЗначения колонки: ТЗ.Колонки.Найти("Сумма").ТипЗначения вернёт объект ОписаниеТипов. Метод Типы() этого описания перечислит все допустимые типы колонки.
Что вернёт ТипЗнч для пустой ссылки?
Тип пустой ссылки совпадает с типом заполненной: для пустой ссылки справочника «Номенклатура» это СправочникСсылка.Номенклатура. Пустоту проверяют отдельно — через ЗначениеЗаполнено() или сравнение с пустой ссылкой.