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