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

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

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

Разбираем способы определить тип поля в запросе 1С: функция ТипЗначения, операторы ТИП, ССЫЛКА, ВЫБОР и обход составных типов данных с примерами кода.

Определить тип значения прямо в запросе 1С нужно, когда поле имеет составной тип: например, реквизит «Контрагент» может хранить ссылку на справочник «Контрагенты» или «Организации», а поле расшифровки — документы разных видов. Язык запросов 1С предоставляет для этого несколько инструментов: функцию ТипЗначения(), операторы ТИП и ССЫЛКА, а также конструкцию ВЫБОР для классификации строк результата.

Выбор способа зависит от задачи. Если нужно отфильтровать записи по типу — используют условие ГДЕ ... ССЫЛКА или сравнение ТипЗначения() с конкретным типом. Если нужно вывести тип как колонку отчёта — применяют ВЫБОР КОГДА ... ТОГДА или сами функции ТипЗначения() и ТИПЗНАЧЕНИЯ() в списке полей. Ошибки здесь типичны: путают оператор ТИП с функцией, забывают, что у примитивных типов (число, строка) нельзя вызвать ССЫЛКА, или пытаются получить «имя типа строкой», чего язык запросов напрямую не умеет.

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

Какие инструменты языка запросов определяют тип

Язык запросов 1С даёт четыре основных механизма работы с типами. Функция ТипЗначения(Выражение) возвращает значение специального вида «Тип», которое можно сравнивать с конкретным типом. Оператор ТИП используется внутри конструкции ВЫБОР и в условиях как литерал типа: ТИП(Справочник.Номенклатура). Оператор ССЫЛКА проверяет, принадлежит ли значение указанному ссылочному типу. Конструкция ВЫБОР КОГДА ... ТОГДА ... КОНЕЦ связывает эти проверки и выдаёт понятный результат.

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

Функция ТипЗначения: получение и сравнение типа

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

Типичный пример — отбор строк, где регистратор является конкретным документом:

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.Регистратор

ИЗ

РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК Остатки

ГДЕ

ТипЗначения(Остатки.Регистратор) = ТИП(Документ.ПриходнаяНакладная)

Здесь важна деталь: сравнивать ТипЗначения() можно только с литералом ТИП(...), а не со строкой с именем типа. Запись вида ТипЗначения(Поле) = "СправочникСсылка.Номенклатура" синтаксически пройдёт, но всегда даст ложь, потому что тип никогда не равен строке.

bsl
ВЫБРАТЬ
	ТипЗначения(Движения.Регистратор) КАК ТипРегистратора
ИЗ
	РегистрНакопления.Продажи КАК Движения
ГДЕ
	ТипЗначения(Движения.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг)

Оператор ССЫЛКА: короткая проверка ссылочного типа

Для ссылочных значений (справочники, документы, планы счетов и т.д.) самый читаемый способ — оператор ССЫЛКА. Условие Поле ССЫЛКА Справочник.Номенклатура возвращает истину, если значение является ссылкой именно этого вида. По сути это сокращённая форма сравнения ТипЗначения(Поле) = ТИП(Справочник.Номенклатура).

Ограничение оператора принципиально: он не работает с примитивными типами. Проверить «является ли поле числом» через ССЫЛКА нельзя — для этого применяют ТипЗначения(Поле) = ТИП(ЧИСЛО) или ТИП(СТРОКА), ТИП(ДАТА), ТИП(БУЛЕВО). Это частая причина ошибки «Неверные параметры в операции сравнения» при построении запроса.

ВЫБРАТЬ

Взаиморасчеты.Контрагент,

Взаиморасчеты.СуммаОстаток

ИЗ

РегистрНакопления.Взаиморасчеты.Остатки КАК Взаиморасчеты

ГДЕ

Взаиморасчеты.Контрагент ССЫЛКА Справочник.Контрагенты

Если нужно отобрать сразу несколько допустимых типов, условия объединяют через ИЛИ: Поле ССЫЛКА Справочник.Контрагенты ИЛИ Поле ССЫЛКА Справочник.Организации. Альтернатива — сравнение ТипЗначения() со списком через В (...), но с типами оператор В работает ограниченно, поэтому надёжнее перечислять условия явно.

Конструкция ВЫБОР: вывод типа понятной строкой

Когда тип нужно показать пользователю в отчёте, единственный корректный приём — конструкция ВЫБОР, где каждому типу сопоставляется строковое обозначение. Язык запросов не умеет преобразовывать значение типа в строку напрямую, поэтому «имя типа» формируют вручную.

ВЫБРАТЬ

Движения.Регистратор,

ВЫБОР

КОГДА Движения.Регистратор ССЫЛКА Документ.ПриходнаяНакладная

ТОГДА "Поступление"

КОГДА Движения.Регистратор ССЫЛКА Документ.РасходнаяНакладная

ТОГДА "Реализация"

КОГДА Движения.Регистратор ССЫЛКА Документ.Инвентаризация

ТОГДА "Инвентаризация"

ИНАЧЕ "Прочее"

КОНЕЦ КАК ВидДокумента

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК Движения

Ветка ИНАЧЕ обязательна на практике: составной тип регистратора в типовых конфигурациях может включать десятки видов документов, и без «прочего» варианта часть строк получит NULL в колонке. Порядок условий значения не имеет — тип у значения один, пересечений не возникает.

Определение типа у примитивных значений и NULL

Примитивные типы проверяются через сравнение ТипЗначения() с литералами ТИП(ЧИСЛО), ТИП(СТРОКА), ТИП(ДАТА), ТИП(БУЛЕВО). Это актуально для универсальных реквизитов, хранилищ значений после извлечения и полей, где конфигуратор разрешает смешанное содержимое.

Отдельная ситуация — неопределённое значение и NULL. NULL появляется при соединениях таблиц, когда совпадение не найдено, и любые сравнения типа с NULL дают ложь. Поэтому логику строят так: сначала отсекают NULL через ЕСТЬ NULL или заменяют его функцией ЕСТЬNULL(Поле, ЗначениеПоУмолчанию), и только потом определяют тип.

Для сложных сценариев удобен комбинированный вариант:

ВЫБОР

КОГДА Таблица.Значение ЕСТЬ NULL

ТОГДА "Не заполнено"

КОГДА ТипЗначения(Таблица.Значение) = ТИП(ЧИСЛО)

ТОГДА "Число"

КОГДА ТипЗначения(Таблица.Значение) = ТИП(СТРОКА)

ТОГДА "Строка"

КОГДА ТипЗначения(Таблица.Значение) = ТИП(БУЛЕВО)

ТОГДА "Булево"

ИНАЧЕ "Ссылка"

КОНЕЦ КАК ТипЗначенияСтрокой

Типичные ошибки
01
Сравнение ТипЗначения() со строкой "Справочник.Номенклатура" — условие всегда ложно, строки результата теряются без видимой ошибки
02
Использование оператора ССЫЛКА для примитивных типов — запрос падает с ошибкой, для числа и строки нужно ТипЗначения() = ТИП(ЧИСЛО)
03
Отсутствие ветки ИНАЧЕ в ВЫБОР — для неучтённых типов колонка получает NULL и ломает группировки отчёта
04
Проверка типа до обработки NULL — строки с пустым результатом соединения выпадают из всех условий

Приведение типов: ВЫРАЗИТЬ как способ сузить составной тип

Обратная задача — не определить тип, а зафиксировать его. Оператор ВЫРАЗИТЬ(Поле КАК Справочник.Номенклатура) приводит составное поле к конкретному типу: значения других типов превращаются в NULL. Это используют, когда нужно обратиться к реквизиту конкретного объекта через точку — язык запросов позволяет «разыменовать» поле только после приведения.

ВЫБРАТЬ

ВЫРАЗИТЬ(Заказы.Контрагент КАК Справочник.Контрагенты).ИНН КАК ИНН

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ГДЕ

Заказы.Контрагент ССЫЛКА Справочник.Контрагенты

Связка «фильтр через ССЫЛКА + приведение через ВЫРАЗИТЬ» — стандартный безопасный шаблон: сначала отсекаются значения чужих типов, затем выполняется обращение к реквизиту. Без фильтра запрос останется рабочим, но вернёт NULL в колонке для всех несоответствующих строк.

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

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

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

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

Проверить корректность определения типа проще всего в консоли запросов: выполните запрос без условия, добавьте колонку с ВЫБОР-классификацией и сравните с исходными данными. Контрольные признаки: сумма строк по всем веткам ВЫБОР (включая «Прочее») равна общему числу строк; в колонке типа нет неожиданных NULL; фильтр по типу не отсекает строки, которые должны попасть в выборку.

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

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

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

Колонка с классификацией типа
Норма

Каждая строка имеет понятное обозначение, NULL нет

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

Часть строк содержит NULL — не хватает ветки ИНАЧЕ или не обработан NULL

Количество строк после фильтра по типу
Норма

Совпадает с ожидаемым числом документов этого вида

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

Выборка пуста — вероятно, тип сравнивается со строкой вместо ТИП(...)

Обращение к реквизиту после ВЫРАЗИТЬ
Норма

Реквизит заполнен для строк нужного типа

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

NULL у всех строк — не совпал вид объекта в ВЫРАЗИТЬ и в данных

Если запрос работает в реальном отчёте, дополнительно проверьте его на периоде, где точно встречаются все типы составного поля. Тест на «удобном» периоде, где все регистраторы одного вида, скрывает ошибки классификации.

Итог

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

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

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

Можно ли получить имя типа строкой прямо в запросе?

Штатной функции преобразования типа в строку в языке запросов нет. Используют конструкцию ВЫБОР с ручным перечислением типов и их названий либо получают ТипЗначения() в результате запроса и преобразуют его в строку уже на встроенном языке после выполнения.

Чем отличается ТипЗначения() от оператора ССЫЛКА?

ТипЗначения() — универсальная функция, возвращающая тип любого значения, включая числа, строки и даты. Оператор ССЫЛКА работает только со ссылочными типами и служит краткой формой записи условия. Для ссылок оба способа эквивалентны, для примитивов подходит только ТипЗначения().

Почему условие ТипЗначения(Поле) = "Документ.РеализацияТоваров" не работает?

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

Как определить тип значения, если поле может содержать NULL?

NULL не имеет типа, и все проверки типа для него возвращают ложь. Сначала обработайте NULL: отфильтруйте условием «Поле ЕСТЬ NULL», замените функцией ЕСТЬNULL() или добавьте отдельную ветку в ВЫБОР, и только затем определяйте тип оставшихся значений.

Работает ли определение типа в СКД и динамических списках?

В запросе набора данных СКД и в произвольном запросе динамического списка все описанные приёмы работают полностью. Ограничения возникают в вычисляемых полях и выражениях ресурсов СКД — там синтаксис иной, и тип чаще проверяют уже в самом запросе, передавая результат как отдельное поле.

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

Перечислите нужные виды документов через ИЛИ с оператором ССЫЛКА: «Поле ССЫЛКА Документ.Первый ИЛИ Поле ССЫЛКА Документ.Второй». Условия «любой документ вообще» одним оператором задать нельзя — составной тип в запросе раскрывается только явным списком.