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

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

1С: как получить тип данных значения, реквизита и объекта

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

Определение типа данных — одна из самых частых задач при разработке и отладке в 1С. Проверить, какое значение вернул запрос, сравнить тип реквизита с ожидаемым, разобрать составный тип поля — всё это делается встроенными средствами языка без сторонних инструментов.

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

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

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

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

bsl
Значение = Справочники.Номенклатура.НайтиПоКоду("0000001");
ТекущийТип = ТипЗнч(Значение);
Сообщить(ТекущийТип); // СправочникСсылка.Номенклатура

Функция работает с любыми значениями: примитивами (число, строка, дата, булево), ссылками на объекты базы, коллекциями, структурами. Для значения Неопределено она вернёт тип Неопределено, что удобно использовать в проверках.

Важно понимать: ТипЗнч работает со значением, а не с переменной. Если переменной ещё не присвоено значение, обращение к ней вызовет ошибку, а не вернёт «пустой тип».

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

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

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

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

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

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

Сравнение типов: ссылка против объекта

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

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

bsl
Если Значение.Метаданные() = Метаданные.Справочники.Номенклатура Тогда
    // подходит и ссылка, и объект
КонецЕсли;

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

Как узнать тип реквизита через метаданные

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

bsl
Реквизит = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Найти("Контрагент");
Если Реквизит <> Неопределено Тогда
    ОписаниеТипа = Реквизит.Тип; // ОписаниеТипов
    Для Каждого Т Из ОписаниеТипа.Типы() Цикл
        Сообщить(Т);
    КонецЦикла;
КонецЕсли;

Свойство Тип реквизита возвращает объект ОписаниеТипов. Если реквизит составного типа (например, «Контрагент» может быть ссылкой на разные справочники), метод Типы() вернёт массив всех допустимых типов. Метод СодержитТип(Тип(...)) позволяет проверить, входит ли конкретный тип в состав.

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

Определение типа на клиенте и его ограничения

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

Стандартный приём: сравнение типов выполняют в серверной процедуре, а на клиент передают уже готовый результат — булево или строковое имя типа. Либо тип получают на сервере один раз и кэшируют в реквизите формы.

Маршрут решения

Как выбрать действие

Нужно проверить тип значения на сервереИспользуйте ТипЗнч(Значение) = Тип("ИмяТипа")
Проверка нужна в управляемой форме на клиентеВынесите сравнение в серверную процедуру и верните результат
Нужно узнать тип реквизита без значенияОбратитесь к Метаданные...Реквизиты и свойству Тип
Имя типа приходит извне как строкаПроверьте существование через Метаданные.НайтиПоПолномуИмени до вызова Тип()

Проверка результата и отладка

Самый быстрый способ увидеть тип во время отладки — окно «Вычислить выражение» (Shift+F9): введите ТипЗнч(Переменная), и конфигуратор покажет тип. Табло (Ctrl+Alt+W) удобно для постоянного наблюдения за типом переменной при пошаговом выполнении.

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

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

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

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

Условие срабатывает на ожидаемых значениях

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

Условие всегда ложно — проверьте, не сравниваете ли тип со строкой

Имя типа в функции Тип()
Норма

Код выполняется без исключения

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

Ошибка «Тип не определен» — имя не совпадает с объектом конфигурации

Работа на клиенте
Норма

Сравнение типов выполняется на сервере

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

Ошибка компиляции или выполнения в управляемой форме

Частые ошибки и их последствия

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

Вторая группа — логические: смешение ссылки и объекта, проверка только одного типа там, где реквизит составной, игнорирование Неопределено и NULL из запросов. Такие ошибки не падают явно, а молча искажают данные: условие не срабатывает, и ветка обработки пропускается.

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

Итог

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

Тип значения — ТипЗнч(), эталон для сравнения — Тип("ИмяТипа"), тип реквизита без значения — через Метаданные и ОписаниеТипов. На клиенте Тип() недоступен, сравнения выносят на сервер. Всегда различайте ссылку и объект — это разные типы.

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

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

Используйте конструкцию: Если ТипЗнч(Значение) = Тип("Число") Тогда ... КонецЕсли. Учтите, что строка с цифрами типом "Число" не является — при необходимости преобразуйте её через Число() с проверкой.

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

ТипЗнч принимает значение и возвращает его фактический тип. Тип принимает строку с именем типа и возвращает сам тип как объект. Первая функция отвечает на вопрос «что это за значение», вторая создаёт эталон для сравнения.

Как узнать тип значения, полученного из запроса?

После выборки примените ТипЗнч к полю выборки в коде. Если поле может содержать NULL (например, при левом соединении), сначала проверьте значение на NULL, иначе логика сравнения типов может работать неожиданно.

Почему Тип() выдаёт ошибку «Тип не определен»?

Имя в строке не совпадает ни с одним типом конфигурации: опечатка, переименованный объект или неверный шаблон имени (например, Справочник.Номенклатура вместо СправочникСсылка.Номенклатура). Проверьте точное имя объекта в конфигураторе.

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

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

Работает ли ТипЗнч в запросах?

В языке запросов есть своя функция ТИПЗНАЧЕНИЯ(Поле) и оператор ТИП(ИмяТипа) для сравнения. Они применяются внутри текста запроса, а встроенные ТипЗнч и Тип — в коде на встроенном языке после получения результата.