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

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

Как проверить тип значения в 1С 8

Как в 1С 8 проверить тип значения: функции ТипЗнч, Тип, сравнение типов, работа с составными типами, проверка ссылок и примитивных значений. Примеры кода.

Проверка типа значения — одна из самых частых задач при разработке на встроенном языке 1С. Она нужна, когда переменная может содержать данные разных видов: например, реквизит составного типа, результат запроса, параметр процедуры или значение из универсальной обработки. Без корректной проверки легко получить ошибку «Поле объекта не обнаружено» или неправильную логику расчёта.

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

Ниже разобраны основные способы проверки типа с примерами кода, типичные ошибки и рекомендации, какой вариант выбрать в конкретной ситуации.

Основной способ: функции ТипЗнч и Тип

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

Стандартная конструкция проверки выглядит так:

Если ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") Тогда

// работаем со ссылкой на номенклатуру

ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда

// работаем со строкой

КонецЕсли;

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

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

Проверка ссылочных и примитивных типов

Подход к проверке немного отличается в зависимости от того, что ожидается: ссылка на объект базы данных или примитивное значение.

Проверка примитивных типов

Для примитивов — Число, Строка, Дата, Булево — достаточно прямого сравнения. Учтите, что Неопределено и NULL — это тоже типы, и их часто нужно отсекать первыми:

Если Значение = Неопределено Тогда

Возврат;

КонецЕсли;

Если ТипЗнч(Значение) = Тип("Число") Тогда

// арифметика безопасна

КонецЕсли;

Отдельная тонкость: пустая дата и пустая строка — это всё ещё значения типов Дата и Строка. Проверка типа не заменяет проверку заполненности через ЗначениеЗаполнено().

Проверка ссылок

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

Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда

// это ссылка на какой-то справочник

КонецЕсли;

Аналогично работают Документы.ТипВсеСсылки(), Перечисления.ТипВсеСсылки(), ПланыСчетов.ТипВсеСсылки() и другие менеджеры. Это удобно, когда нужно отличить «любую ссылку» от примитивного значения, не перечисляя все виды объектов.

Проверка через ОписаниеТипов и метод СодержитТип

Когда реквизит или параметр имеет составной тип, проверка через цепочку сравнений становится громоздкой. Удобнее сформировать ОписаниеТипов и вызвать метод СодержитТип():

МассивТипов = Новый Массив;

МассивТипов.Добавить(Тип("СправочникСсылка.Контрагенты"));

МассивТипов.Добавить(Тип("СправочникСсылка.Организации"));

Допустимые = Новый ОписаниеТипов(МассивТипов);

Если Допустимые.СодержитТип(ТипЗнч(Значение)) Тогда

// тип значения входит в список допустимых

КонецЕсли;

Также полезно помнить, что у реквизита объекта метаданных уже есть готовое описание типов. Его можно получить через метаданные и проверить, допускает ли реквизит конкретное значение:

ОписаниеРеквизита = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Контрагент.Тип;

Если ОписаниеРеквизита.СодержитТип(ТипЗнч(Значение)) Тогда

// значение можно безопасно записать в реквизит

КонецЕсли;

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

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

Проверка типа по строковому представлению

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

Если Строка(ТипЗнч(Значение)) = "Номенклатура" Тогда

// ...

КонецЕсли;

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

Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда

ИмяТипа = Значение.Метаданные().ПолноеИмя(); // например, "Справочник.Номенклатура"

КонецЕсли;

Способ через строки держите как запасной: он медленнее и хрупче прямого сравнения типов, но незаменим в универсальных механизмах обмена и расширениях.

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

Проверка типа в запросах

В языке запросов 1С свои механизмы проверки типа. Оператор ССЫЛКА проверяет принадлежность поля к ссылочному типу, а функция ТИПЗНАЧЕНИЯ() позволяет сравнить тип с конкретным значением через ТИП():

ВЫБРАТЬ

Регистр.Значение

ИЗ

РегистрСведений.ЗначенияСвойств КАК Регистр

ГДЕ

Регистр.Значение ССЫЛКА Справочник.Номенклатура

И ТИПЗНАЧЕНИЯ(Регистр.Значение) = ТИП(Справочник.Номенклатура)

Для составных полей полезна функция ВЫРАЗИТЬ() — она приводит значение к указанному типу, и если приведение невозможно, результатом будет NULL или пустая ссылка. Это позволяет безопасно обращаться к реквизитам через точку без ошибок соединения.

Помните, что обращение через точку к реквизиту составного поля без ВЫРАЗИТЬ() порождает соединения со всеми таблицами возможных типов, что заметно замедляет запрос на больших объёмах данных.

bsl
Если ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") Тогда
    Сообщить("Это номенклатура: " + Значение);
КонецЕсли;

Какой способ выбрать в разных ситуациях

Выбор зависит от контекста: где выполняется код, насколько он универсален и что именно нужно проверить.

Маршрут решения

Как выбрать способ проверки

Нужно проверить один конкретный тип в модуле конфигурацииИспользуйте ТипЗнч(Значение) = Тип("ИмяТипа")
Допустимо несколько типов или тип задан составным реквизитомСформируйте ОписаниеТипов и вызовите СодержитТип()
Нужно отличить любую ссылку от примитиваПримените Справочники.ТипВсеСсылки().СодержитТип() и аналоги
Код должен работать в базах, где объекта может не бытьСравнивайте строковое представление типа или имя через Метаданные().ПолноеИмя()
Проверка выполняется в запросеИспользуйте ССЫЛКА, ТИПЗНАЧЕНИЯ() и ВЫРАЗИТЬ()

Для обычной прикладной логики в модулях почти всегда достаточно прямого сравнения через ТипЗнч и Тип — это самый быстрый и читаемый вариант. К ОписаниеТипов переходите, когда список допустимых типов больше двух-трёх или формируется динамически. Строковые сравнения оставляйте для расширений и универсальных обработок.

После внедрения проверки обязательно протестируйте её на всех ветках: передайте значение нужного типа, значение другого типа, Неопределено и пустую ссылку. Убедитесь, что ни одна ветка не вызывает исключений и логика срабатывает именно там, где ожидалось.

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

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

Значение нужного типа
Норма

Условие срабатывает, выполняется нужная ветка

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

Условие молчит — вероятно, сравнение со строкой или неверное имя типа

Значение другого типа
Норма

Выполняется ветка Иначе или код пропускается

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

Срабатывает основная ветка — ошибка в логике сравнения

Неопределено или NULL
Норма

Корректно отсекается без исключений

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

Ошибка выполнения — нет предварительной проверки

Ограничения и подводные камни

Функция ТипЗнч() не работает в управляемых формах на клиенте для некоторых серверных типов — например, объектов данных, доступных только на сервере. В тонком и веб-клиенте многие типы недоступны в принципе, и попытка сравнения с ними вызовет ошибку компиляции или выполнения. Проверки таких типов выносите в серверные процедуры.

Ещё одна ловушка — различие между ссылкой и объектом. Значение, полученное методом ПолучитьОбъект(), имеет тип СправочникОбъект.Имя, а не СправочникСсылка.Имя. Сравнение со ссылочным типом даст Ложь. Если процедура может принимать и то, и другое, проверяйте оба варианта или приводите значение к ссылке через свойство Ссылка.

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

Итог

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

Базовая проверка типа — ТипЗнч(Значение) = Тип("ИмяТипа"). Для списков типов используйте ОписаниеТипов.СодержитТип(), для запросов — ССЫЛКА и ТИПЗНАЧЕНИЯ(). Не сравнивайте тип со строкой напрямую и отличайте ссылку от объекта.

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

Чем ТипЗнч отличается от Тип?

ТипЗнч(Значение) возвращает тип конкретного переданного значения, а Тип("ИмяТипа") создаёт объект-тип по его имени. Первая функция отвечает на вопрос «какой тип у этого значения», вторая — «дай мне тип с таким именем». Вместе они образуют пару для сравнения.

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

Используйте конструкцию Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)). Она вернёт Истина для ссылки на любой справочник конфигурации. Аналогичные методы есть у документов, перечислений, планов видов характеристик и других ссылочных менеджеров.

Почему сравнение ТипЗнч(Х) = "Строка" не работает?

ТипЗнч возвращает объект типа «Тип», а не строку. Объект никогда не равен строке, поэтому условие всегда ложно. Правильный вариант: ТипЗнч(Х) = Тип("Строка").

Как проверить тип значения в запросе?

Используйте оператор ССЫЛКА для проверки принадлежности к виду объекта (Поле ССЫЛКА Справочник.Номенклатура) или функцию ТИПЗНАЧЕНИЯ(Поле) = ТИП(Справочник.Номенклатура) для точного сравнения. Для безопасного обращения к реквизитам составных полей применяйте ВЫРАЗИТЬ().

Что вернёт ТипЗнч для NULL из запроса?

Для значения NULL функция вернёт тип «Null», а для отсутствующего значения — тип «Неопределено». Это разные типы: проверка на Неопределено не отсечёт NULL. В типовых механизмах часто применяют функции ЕстьNull или явную проверку Значение = NULL.

Можно ли проверить тип в тонком клиенте?

Да, но только для типов, доступных в тонком клиенте: примитивы, ссылки, структуры, массивы и другие клиентские типы. Сравнение с серверными типами (например, объектами СправочникОбъект) на клиенте невозможно — такие проверки выносят в серверные процедуры с директивой &НаСервере.