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