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