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