Разработка и Конфигурация · 12 мин
ТипЗнч как строка: проверка типа значения в 1С по имени
Как проверить тип значения в 1С через строку: ТипЗнч, Тип(), сравнение строковых представлений, типичные ошибки и безопасные приёмы разработки.
Задача «ТипЗнч как строка» возникает у разработчиков 1С в двух ситуациях: когда нужно сравнить тип значения с типом, заданным строкой (например, из настроек или параметра обмена), и когда нужно получить строковое представление типа для вывода в сообщение, лог или отчёт. Штатная функция ТипЗнч() возвращает объект типа «Тип», а не строку, поэтому прямое сравнение ТипЗнч(Значение) = "СправочникСсылка.Номенклатура" не сработает — слева объект, справа строка.
Правильные подходы сводятся к трём приёмам: получение типа по строковому имени через функцию Тип(), преобразование типа в строку через Строка() или XML-сериализацию, а также проверка через метаданные. У каждого приёма есть ограничения: часть имён типов зависит от локали, часть типов вообще не имеет строкового имени, а сравнение строк медленнее и менее надёжно, чем сравнение объектов типов.
Как устроены ТипЗнч() и Тип() во встроенном языке
Функция ТипЗнч(Значение) возвращает объект встроенного типа «Тип», который описывает тип переданного значения. Это не строка и не число — сравнивать его корректно можно только с другим объектом типа «Тип». Второй ключевой инструмент — функция Тип(ИмяТипа), которая выполняет обратную операцию: принимает строку с именем типа и возвращает соответствующий объект «Тип».
Имена типов ссылочных объектов строятся по шаблону: вид объекта метаданных, точка, имя объекта в конфигурации. Например: СправочникСсылка.Номенклатура, ДокументСсылка.РеализацияТоваровУслуг, ПеречислениеСсылка.СтавкиНДС. Для примитивных типов используются имена Строка, Число, Дата, Булево. Для объектных (нессылочных) значений — СправочникОбъект.Номенклатура, ДокументОбъект.ПриходнаяНакладная и так далее.
Важно понимать: если функции Тип() передать имя несуществующего типа, будет вызвано исключение. Поэтому при работе со строками из внешних источников (настройки, файлы обмена, параметры) вызов Тип() следует оборачивать в Попытка...Исключение или предварительно проверять имя через метаданные.
Проверка типа значения по строковому имени
Основной сценарий: в настройках хранится строка «ДокументСсылка.ЗаказКлиента», и нужно проверить, что переданное значение имеет именно этот тип. Правильный код выглядит так:
ИскомыйТип = Тип("ДокументСсылка.ЗаказКлиента");
Если ТипЗнч(Значение) = ИскомыйТип Тогда
// Значение — ссылка на заказ клиента
КонецЕсли;
Такой вариант надёжен: сравниваются два объекта «Тип», а не строки, поэтому проблемы локализации и регистра исключены. Строку в Тип() можно передавать и в русском, и в английском варианте синтаксиса — платформа примет оба, если имя объекта метаданных указано верно.
Функция ЭтоТипПоИмени(Значение, ИмяТипа)
Попытка
Возврат ТипЗнч(Значение) = Тип(ИмяТипа);
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункцииЕсли строка с именем типа приходит извне (файл настроек, JSON, параметр регламентного задания), обязательно обрабатывайте исключение. Иначе опечатка в настройке приведёт к аварийному завершению обработки с неинформативной для пользователя ошибкой.
Когда строка не преобразуется в тип
Функция Тип() не сработает для имён, которым не соответствует ни один тип: опечаток, имён объектов, отсутствующих в данной конфигурации, а также для ряда системных типов, у которых нет строкового имени, принимаемого конструктором. Также Тип() не принимает имена в формате XML (например, CatalogRef.Номенклатура — это формат сериализации, а не имя для функции Тип()).
Получение строкового представления типа
Обратная задача — вывести тип значения строкой, например в сообщение пользователю или в журнал. Самый простой способ — Строка(ТипЗнч(Значение)). Для ссылочных типов результат обычно совпадает с именем, пригодным для Тип(): «СправочникСсылка.Номенклатура». Для примитивных типов результат зависит от языка конфигурации: «Строка», «Число», «Дата» — или String, Number, Date.
Более строгий и независимый от локали способ — функция XMLТипЗнч(Значение), которая возвращает структуру с именем типа в формате XML-сериализации: CatalogRef.Номенклатура, DocumentRef.ЗаказКлиента, string, decimal, dateTime. Этот формат стабилен и удобен для логирования и обмена, но не подходит напрямую для функции Тип().
Для вывода пользователю иногда предпочтительнее синоним объекта метаданных, а не техническое имя типа. Его можно получить через метаданные значения: Значение.Метаданные().Представление() — но только для объектов, у которых есть метаданные (ссылки, объекты, записи регистров). У примитивных значений метод Метаданные() отсутствует, и обращение к нему вызовет ошибку.
Проверка типа через метаданные без строк
Когда имя типа известно на этапе разработки, строки вообще не нужны. Сравнение ТипЗнч(Значение) = Тип("ДокументСсылка.ЗаказКлиента") — самый быстрый и безопасный вариант. Альтернатива — проверка через метаданные: Метаданные.Документы.ЗаказКлиента и метод Метаданные.НайтиПоТипу(ТипЗнч(Значение)).
Приём через НайтиПоТипу() полезен, когда нужно не просто сравнить тип, а получить объект метаданных — например, чтобы узнать синоним, проверить вид документа или построить универсальную обработку по любым ссылкам. Если тип не является ссылочным объектом метаданных, НайтиПоТипу() вернёт Неопределено — это тоже удобный способ отличить ссылку от примитива.
Сравнение вариантов
Основной способ проверки по строке. Быстро и надёжно, но требует обработки исключения для строк извне.
Только для вывода и диагностики. Зависит от локали, медленнее, хрупко при изменениях конфигурации.
Стабильное строковое имя для логов и сериализации, не подходит для функции Тип().
Когда нужен объект метаданных, а не просто проверка. Работает только для ссылочных типов.
Типичные ошибки и их последствия
Самая распространённая ошибка — прямое сравнение ТипЗнч(Значение) = "СправочникСсылка.Номенклатура". Такое выражение всегда ложно (или завершится ошибкой сравнения в зависимости от контекста), потому что сравниваются значения разных типов: «Тип» и «Строка». Логика молча не срабатывает, и ошибку находят только при тестировании.
Вторая группа ошибок связана со строковыми сравнениями: разработчик пишет Строка(ТипЗнч(Значение)) = "СправочникСсылка.Номенклатура", и код работает, пока конфигурацию не переносят на английский вариант встроенного языка или не меняют представление. Третья типичная проблема — вызов Тип() с именем объекта, которого нет в данной конфигурации (например, код общего модуля рассчитан на документ из другой подсистемы), без обработки исключения.
Практические сценарии применения
Универсальная обработка с типами из настроек
В обработках загрузки и обмена типы целевых объектов часто хранятся в таблице настроек строками. Рекомендуемый порядок: при инициализации обработки один раз преобразовать все строки в типы через Тип() с обработкой ошибок, сохранить результат в соответствие и дальше в цикле сравнивать уже объекты «Тип». Это быстрее, чем вызывать Тип() на каждой итерации, и все ошибки настроек выявляются сразу, а не в середине загрузки.
Логирование и диагностика
При записи в журнал регистрации или собственный лог тип значения удобно фиксировать через XMLТипЗнч(): формат не зависит от локали и одинаково читается в любой конфигурации. Для сообщений пользователю лучше использовать представление метаданных — пользователю понятнее «Реализация товаров и услуг», чем «ДокументСсылка.РеализацияТоваровУслуг».
Проверка составного типа
Если реквизит или параметр имеет составной тип (например, ссылка на несколько видов документов), проверка по одному имени не подходит. Здесь либо перечисляют допустимые типы в массиве и ищут ТипЗнч(Значение) в нём через Найти(), либо, при работе с описанием типов, используют метод СодержитТип() объекта «ОписаниеТипов».
- 1Убедитесь, что строка содержит корректное имя типа в формате ВидСсылка.ИмяОбъекта или имя примитивного типа.
- 2Преобразуйте строку в тип: ИскомыйТип = Тип(ИмяСтрокой), обернув вызов в Попытка...Исключение.
- 3Сравните: ТипЗнч(Значение) = ИскомыйТип.
- 4При необходимости вывода используйте Строка(ТипЗнч(Значение)) или XMLТипЗнч(Значение).
- 5Протестируйте на значениях всех ожидаемых типов, включая Неопределено и примитивы.
Проверка результата и границы применимости
После внедрения проверки протестируйте её на граничных значениях: Неопределено (тип «Неопределено»), NULL (тип «Null» в запросах), пустых ссылках — у пустой ссылки тип тот же, что у заполненной, поэтому проверка типа не заменяет проверку ПустаяСтрока() или ЗначениеЗаполнено(). Это частая логическая ошибка: тип корректный, а ссылка пустая.
Как проверить результат
ТипЗнч(Значение) и Тип(Имя) показывают одинаковый тип, условие истинно
Условие ложно при совпадающем виде объекта — проверьте Ссылка/Объект и опечатки в имени
Тип() преобразует её без исключения
Исключение «Недопустимое значение» — имени нет в конфигурации или формат неверный
Проверка работает на обоих вариантах встроенного языка
Код зависит от Строка(ТипЗнч()) — сломается при смене локали
Строковые имена типов — рабочий инструмент, но не универсальный. Там, где тип известен на этапе разработки, используйте прямое сравнение типов без строк; строки оставьте для сценариев, где тип действительно задаётся извне: настройки, обмены, универсальные механизмы. Это снижает и количество исключений, и стоимость сопровождения кода.
Что важно запомнить
ТипЗнч() возвращает объект «Тип», а не строку. Для проверки по строке используйте Тип(Имя) с обработкой исключения, для вывода — Строка() или XMLТипЗнч(). Не сравнивайте типы строками в логике и не путайте типы Ссылка и Объект.
Частые вопросы
Можно ли сравнить ТипЗнч() со строкой напрямую?
Нет. Слева будет объект «Тип», справа строка — такое сравнение не даст истины даже при совпадающем имени. Сначала преобразуйте строку функцией Тип() и сравнивайте два объекта «Тип».
Чем отличается Строка(ТипЗнч()) от XMLТипЗнч()?
Строка(ТипЗнч()) возвращает имя типа на языке встроенного языка конфигурации («СправочникСсылка.Номенклатура» или CatalogRef... в зависимости от варианта). XMLТипЗнч() возвращает имя в формате XML-сериализации, которое стабильно и не зависит от локали, поэтому лучше подходит для логов и обмена.
Почему Тип() вызывает исключение, хотя объект есть в конфигурации?
Чаще всего перепутаны Ссылка и Объект (СправочникСсылка.Х и СправочникОбъект.Х — разные типы), допущена опечатка в имени или использовано имя формата XML (CatalogRef.Х), которое функция Тип() не принимает. Проверьте точное имя объекта в конфигураторе.
Как проверить, что значение — любая ссылка, без перечисления типов?
Используйте Метаданные.НайтиПоТипу(ТипЗнч(Значение)): для ссылочных типов метод вернёт объект метаданных, для примитивов — Неопределено. Альтернатива — проверка через XMLТипЗнч() и анализ пространства имён типа.
Заменяет ли проверка типа проверку на пустое значение?
Нет. Пустая ссылка имеет тот же тип, что и заполненная. После проверки типа дополнительно используйте ЗначениеЗаполнено() или сравнение с ПустаяСсылка() соответствующего менеджера объекта.
Что быстрее: сравнение типов или сравнение строк?
Сравнение объектов «Тип» быстрее и надёжнее: это сравнение внутренних идентификаторов, а не посимвольный разбор строк. Кроме того, при сравнении строк добавляется стоимость преобразования типа в строку на каждом вызове.