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

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

Как в 1С получить тип реквизита объекта

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

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

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

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

Получение типа реквизита через метаданные

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

МетаданныеРеквизита = Метаданные.Справочники.Номенклатура.Реквизиты.Артикул;

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

Сообщить(ОписаниеТипа); // "Строка(50)"

Если у вас есть объект данных (например, СправочникОбъект), метаданные можно получить через метод Метаданные() объекта, не привязываясь к конкретному виду справочника или документа:

МетаданныеОбъекта = Объект.Метаданные();

ОписаниеТипа = МетаданныеОбъекта.Реквизиты[ИмяРеквизита].Тип;

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

bsl
ОписаниеТипа = Метаданные.Справочники.Номенклатура.Реквизиты.Артикул.Тип;

Проверка, входит ли нужный тип в описание

Реквизит может иметь составной тип — например, «Строка или Число», либо ссылку на несколько видов документов. Поэтому сравнивать описание типов «на равенство» бессмысленно. Для проверки используется метод СодержитТип():

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

// реквизит может хранить строку

КонецЕсли;

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

// реквизит может хранить ссылку на контрагента

КонецЕсли;

Метод возвращает Истина, если указанный тип входит в состав описания. Для составных типов можно получить полный список через метод Типы() — он возвращает массив всех типов, входящих в описание:

Для Каждого ТекТип Из ОписаниеТипа.Типы() Цикл

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

КонецЦикла;

Как узнать фактический тип значения

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

ТипЗначения = ТипЗнч(Объект.Артикул);

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

// значение — строка

КонецЕсли;

Это полезно, когда значение приходит из внешнего источника, из реквизита составного типа или из произвольного параметра процедуры. Учтите: у реквизита составного типа фактическое значение всегда имеет один конкретный тип, поэтому ТипЗнч покажет именно его, а не весь составной тип из метаданных.

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

Два подхода к определению типа

Метаданные + ОписаниеТипов

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

ТипЗнч(Значение)

Показывает фактический тип конкретного значения. Подходит для проверки входных параметров и составных типов. Не скажет ничего о квалификаторах (длина, точность).

Квалификаторы: длина строки, точность числа, состав даты

Объект ОписаниеТипов содержит не только список типов, но и квалификаторы — уточняющие характеристики примитивных типов:

  • КвалификаторыСтроки — длина строки и признак переменной/фиксированной длины;
  • КвалификаторыЧисла — разрядность, разрядность дробной части, допустимый знак;
  • КвалификаторыДаты — состав даты: дата, время или дата и время;
  • КвалификаторыДвоичныхДанных — длина для двоичных данных.
ОписаниеТипа = Метаданные.Справочники.Номенклатура.Реквизиты.Артикул.Тип;

ДлинаСтроки = ОписаниеТипа.КвалификаторыСтроки.Длина;

Точность = ОписаниеТипа.КвалификаторыЧисла.РазрядностьДробнойЧасти;

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

Порядок действий для универсальной проверки реквизита
  1. 1
    Получите метаданные объекта: Объект.Метаданные() или Метаданные.Справочники.Имя.
  2. 2
    Обратитесь к реквизиту: .Реквизиты.ИмяРеквизита и возьмите свойство .Тип.
  3. 3
    Проверьте нужный тип методом СодержитТип(Тип("ИмяТипа")).
  4. 4
    При необходимости прочитайте квалификаторы строки, числа или даты.
  5. 5
    Проверьте результат на тестовом объекте через Сообщить() или отладчик.

Тип реквизита формы и динамических списков

Реквизиты управляемой формы — это не то же самое, что реквизиты объекта конфигурации. У реквизита формы тип хранится в свойстве ТипЗначения, которое также имеет тип ОписаниеТипов:

Для Каждого РеквизитФормы Из ЭтаФорма.ПолучитьРеквизиты() Цикл

Сообщить(РеквизитФормы.Имя + " — " + РеквизитФормы.ТипЗначения);

КонецЦикла;

Метод ПолучитьРеквизиты() возвращает массив реквизитов формы; с параметром-путём (например, "Объект") — реквизиты вложенного объекта. Это удобно при универсальной обработке форм, когда заранее неизвестен состав реквизитов.

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

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

Типичные ошибки и ограничения

Первая распространённая ошибка — попытка сравнить ОписаниеТипов с чем-либо оператором «=». Это составной объект, а не примитив, поэтому корректна только проверка через СодержитТип() или перебор Типы().

Вторая ошибка — обращение к несуществующему реквизиту по имени. В универсальном коде перед обращением стоит проверить наличие реквизита:

РеквизитМета = МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита);

Если РеквизитМета <> Неопределено Тогда

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

КонецЕсли;

Также помните, что стандартные реквизиты (Ссылка, Код, Наименование, Дата, Номер) не входят в коллекцию Реквизиты — они находятся в СтандартныеРеквизиты, и их типы определяются аналогично через свойство Тип.

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

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

Вывод ОписаниеТипа через Сообщить()
Норма

Строка вида «Строка(50)», «Число(15,2)», «СправочникСсылка.Номенклатура»

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

Пустая строка или исключение — реквизит не найден

Результат СодержитТип()
Норма

Истина для типа, реально входящего в описание

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

Ложь при очевидно верном типе — проверьте написание имени типа

ТипЗнч значения реквизита
Норма

Конкретный тип, совместимый с описанием из метаданных

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

Неопределено — значение не заполнено

FAQ

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

Через метаданные: МетаданныеОбъекта.ТабличныеЧасти.ИмяТЧ.Реквизиты.ИмяРеквизита.Тип. Результат — тот же объект ОписаниеТипов, с ним работают методы СодержитТип() и Типы().

Чем ОписаниеТипов отличается от результата ТипЗнч?

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

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

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

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

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

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

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

Итог

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

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