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

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

ТипЗнч как строка: проверка типа значения в 1С по имени

Как проверить тип значения в 1С через строку: ТипЗнч, Тип(), сравнение строковых представлений, типичные ошибки и безопасные приёмы разработки.

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

Правильные подходы сводятся к трём приёмам: получение типа по строковому имени через функцию Тип(), преобразование типа в строку через Строка() или XML-сериализацию, а также проверка через метаданные. У каждого приёма есть ограничения: часть имён типов зависит от локали, часть типов вообще не имеет строкового имени, а сравнение строк медленнее и менее надёжно, чем сравнение объектов типов.

Как устроены ТипЗнч() и Тип() во встроенном языке

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

Имена типов ссылочных объектов строятся по шаблону: вид объекта метаданных, точка, имя объекта в конфигурации. Например: СправочникСсылка.Номенклатура, ДокументСсылка.РеализацияТоваровУслуг, ПеречислениеСсылка.СтавкиНДС. Для примитивных типов используются имена Строка, Число, Дата, Булево. Для объектных (нессылочных) значений — СправочникОбъект.Номенклатура, ДокументОбъект.ПриходнаяНакладная и так далее.

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

Проверка типа значения по строковому имени

Основной сценарий: в настройках хранится строка «ДокументСсылка.ЗаказКлиента», и нужно проверить, что переданное значение имеет именно этот тип. Правильный код выглядит так:

ИскомыйТип = Тип("ДокументСсылка.ЗаказКлиента");

Если ТипЗнч(Значение) = ИскомыйТип Тогда

// Значение — ссылка на заказ клиента

КонецЕсли;

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

bsl
Функция ЭтоТипПоИмени(Значение, ИмяТипа)
    Попытка
        Возврат ТипЗнч(Значение) = Тип(ИмяТипа);
    Исключение
        Возврат Ложь;
    КонецПопытки;
КонецФункции

Если строка с именем типа приходит извне (файл настроек, JSON, параметр регламентного задания), обязательно обрабатывайте исключение. Иначе опечатка в настройке приведёт к аварийному завершению обработки с неинформативной для пользователя ошибкой.

Когда строка не преобразуется в тип

Функция Тип() не сработает для имён, которым не соответствует ни один тип: опечаток, имён объектов, отсутствующих в данной конфигурации, а также для ряда системных типов, у которых нет строкового имени, принимаемого конструктором. Также Тип() не принимает имена в формате XML (например, CatalogRef.Номенклатура — это формат сериализации, а не имя для функции Тип()).

Получение строкового представления типа

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

Более строгий и независимый от локали способ — функция XMLТипЗнч(Значение), которая возвращает структуру с именем типа в формате XML-сериализации: CatalogRef.Номенклатура, DocumentRef.ЗаказКлиента, string, decimal, dateTime. Этот формат стабилен и удобен для логирования и обмена, но не подходит напрямую для функции Тип().

Для вывода пользователю иногда предпочтительнее синоним объекта метаданных, а не техническое имя типа. Его можно получить через метаданные значения: Значение.Метаданные().Представление() — но только для объектов, у которых есть метаданные (ссылки, объекты, записи регистров). У примитивных значений метод Метаданные() отсутствует, и обращение к нему вызовет ошибку.

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

Когда имя типа известно на этапе разработки, строки вообще не нужны. Сравнение ТипЗнч(Значение) = Тип("ДокументСсылка.ЗаказКлиента") — самый быстрый и безопасный вариант. Альтернатива — проверка через метаданные: Метаданные.Документы.ЗаказКлиента и метод Метаданные.НайтиПоТипу(ТипЗнч(Значение)).

Приём через НайтиПоТипу() полезен, когда нужно не просто сравнить тип, а получить объект метаданных — например, чтобы узнать синоним, проверить вид документа или построить универсальную обработку по любым ссылкам. Если тип не является ссылочным объектом метаданных, НайтиПоТипу() вернёт Неопределено — это тоже удобный способ отличить ссылку от примитива.

Сравнение вариантов

ТипЗнч(Значение) = Тип(Имя)

Основной способ проверки по строке. Быстро и надёжно, но требует обработки исключения для строк извне.

Строка(ТипЗнч(Значение)) = Имя

Только для вывода и диагностики. Зависит от локали, медленнее, хрупко при изменениях конфигурации.

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

Стабильное строковое имя для логов и сериализации, не подходит для функции Тип().

Метаданные.НайтиПоТипу()

Когда нужен объект метаданных, а не просто проверка. Работает только для ссылочных типов.

Типичные ошибки и их последствия

Самая распространённая ошибка — прямое сравнение ТипЗнч(Значение) = "СправочникСсылка.Номенклатура". Такое выражение всегда ложно (или завершится ошибкой сравнения в зависимости от контекста), потому что сравниваются значения разных типов: «Тип» и «Строка». Логика молча не срабатывает, и ошибку находят только при тестировании.

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

Типичные ошибки
01
Сравнение ТипЗнч() со строкой напрямую — условие никогда не выполняется, ветка кода мёртвая.
02
Вызов Тип(Имя) без Попытка...Исключение для строк из настроек — аварийное завершение при опечатке.
03
Сравнение через Строка(ТипЗнч()) — ломается при смене языка встроенного языка конфигурации.
04
Путаница между Ссылка и Объект: Тип("СправочникСсылка.Х") и Тип("СправочникОбъект.Х") — разные типы, проверка не срабатывает.
05
Использование имени формата XML (CatalogRef.Х) в функции Тип() — исключение, такое имя не принимается.

Практические сценарии применения

Универсальная обработка с типами из настроек

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

Логирование и диагностика

При записи в журнал регистрации или собственный лог тип значения удобно фиксировать через XMLТипЗнч(): формат не зависит от локали и одинаково читается в любой конфигурации. Для сообщений пользователю лучше использовать представление метаданных — пользователю понятнее «Реализация товаров и услуг», чем «ДокументСсылка.РеализацияТоваровУслуг».

Проверка составного типа

Если реквизит или параметр имеет составной тип (например, ссылка на несколько видов документов), проверка по одному имени не подходит. Здесь либо перечисляют допустимые типы в массиве и ищут ТипЗнч(Значение) в нём через Найти(), либо, при работе с описанием типов, используют метод СодержитТип() объекта «ОписаниеТипов».

Порядок действий для проверки типа по строке
  1. 1
    Убедитесь, что строка содержит корректное имя типа в формате ВидСсылка.ИмяОбъекта или имя примитивного типа.
  2. 2
    Преобразуйте строку в тип: ИскомыйТип = Тип(ИмяСтрокой), обернув вызов в Попытка...Исключение.
  3. 3
    Сравните: ТипЗнч(Значение) = ИскомыйТип.
  4. 4
    При необходимости вывода используйте Строка(ТипЗнч(Значение)) или XMLТипЗнч(Значение).
  5. 5
    Протестируйте на значениях всех ожидаемых типов, включая Неопределено и примитивы.

Проверка результата и границы применимости

После внедрения проверки протестируйте её на граничных значениях: Неопределено (тип «Неопределено»), NULL (тип «Null» в запросах), пустых ссылках — у пустой ссылки тип тот же, что у заполненной, поэтому проверка типа не заменяет проверку ПустаяСтрока() или ЗначениеЗаполнено(). Это частая логическая ошибка: тип корректный, а ссылка пустая.

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

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

Сравнение типов в отладчике
Норма

ТипЗнч(Значение) и Тип(Имя) показывают одинаковый тип, условие истинно

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

Условие ложно при совпадающем виде объекта — проверьте Ссылка/Объект и опечатки в имени

Строка из настроек
Норма

Тип() преобразует её без исключения

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

Исключение «Недопустимое значение» — имени нет в конфигурации или формат неверный

Перенос между конфигурациями
Норма

Проверка работает на обоих вариантах встроенного языка

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

Код зависит от Строка(ТипЗнч()) — сломается при смене локали

Строковые имена типов — рабочий инструмент, но не универсальный. Там, где тип известен на этапе разработки, используйте прямое сравнение типов без строк; строки оставьте для сценариев, где тип действительно задаётся извне: настройки, обмены, универсальные механизмы. Это снижает и количество исключений, и стоимость сопровождения кода.

Итог

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

ТипЗнч() возвращает объект «Тип», а не строку. Для проверки по строке используйте Тип(Имя) с обработкой исключения, для вывода — Строка() или XMLТипЗнч(). Не сравнивайте типы строками в логике и не путайте типы Ссылка и Объект.

Частые вопросы

Можно ли сравнить ТипЗнч() со строкой напрямую?

Нет. Слева будет объект «Тип», справа строка — такое сравнение не даст истины даже при совпадающем имени. Сначала преобразуйте строку функцией Тип() и сравнивайте два объекта «Тип».

Чем отличается Строка(ТипЗнч()) от XMLТипЗнч()?

Строка(ТипЗнч()) возвращает имя типа на языке встроенного языка конфигурации («СправочникСсылка.Номенклатура» или CatalogRef... в зависимости от варианта). XMLТипЗнч() возвращает имя в формате XML-сериализации, которое стабильно и не зависит от локали, поэтому лучше подходит для логов и обмена.

Почему Тип() вызывает исключение, хотя объект есть в конфигурации?

Чаще всего перепутаны Ссылка и Объект (СправочникСсылка.Х и СправочникОбъект.Х — разные типы), допущена опечатка в имени или использовано имя формата XML (CatalogRef.Х), которое функция Тип() не принимает. Проверьте точное имя объекта в конфигураторе.

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

Используйте Метаданные.НайтиПоТипу(ТипЗнч(Значение)): для ссылочных типов метод вернёт объект метаданных, для примитивов — Неопределено. Альтернатива — проверка через XMLТипЗнч() и анализ пространства имён типа.

Заменяет ли проверка типа проверку на пустое значение?

Нет. Пустая ссылка имеет тот же тип, что и заполненная. После проверки типа дополнительно используйте ЗначениеЗаполнено() или сравнение с ПустаяСсылка() соответствующего менеджера объекта.

Что быстрее: сравнение типов или сравнение строк?

Сравнение объектов «Тип» быстрее и надёжнее: это сравнение внутренних идентификаторов, а не посимвольный разбор строк. Кроме того, при сравнении строк добавляется стоимость преобразования типа в строку на каждом вызове.