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