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