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

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

Запрос 1С: ВЫРАЗИТЬ КАК Ссылка — приведение типов в языке запросов

Как использовать оператор ВЫРАЗИТЬ КАК Ссылка в запросах 1С: приведение составных типов, отбор по типу ссылки, типичные ошибки и готовые примеры кода.

Оператор ВЫРАЗИТЬ в языке запросов 1С применяется для приведения значения поля к нужному типу. Одна из самых частых задач — привести составное поле или строковое представление к конкретному типу ссылки, например к СправочникСсылка.Номенклатура или ДокументСсылка.РеализацияТоваровУслуг. Без такого приведения невозможно корректно соединить таблицы по составному реквизиту, отфильтровать записи по типу документа или обратиться к реквизитам «через точку».

Типичная ситуация: в регистре сведений или документе есть реквизит составного типа «ДокументОснование», который может хранить ссылки на несколько видов документов. Чтобы выбрать только записи со ссылками на «ЗаказКлиента» и при этом получить доступ к реквизитам заказа, поле нужно выразить как ссылку конкретного типа. В противном случае запрос либо вернёт ошибку, либо выдаст пустые значения в полях, полученных через точку.

Материал разбирает синтаксис оператора, практические сценарии применения, ограничения платформы и типичные ошибки, которые приводят к потере данных в выборке или к ошибкам исполнения запроса.

Синтаксис оператора ВЫРАЗИТЬ и приведение к ссылке

Общий вид конструкции: ВЫРАЗИТЬ(Выражение КАК ТипДанных). Для ссылочных типов указывается полное имя типа с точностью до объекта метаданных:

ВЫБРАТЬ

ВЫРАЗИТЬ(Таблица.Основание КАК ДокументСсылка.ЗаказКлиента) КАК Заказ

ИЗ

Документ.РеализацияТоваровУслуг КАК Таблица

Оператор не преобразует данные физически — он лишь сообщает механизму запроса, как трактовать значение. Если фактическое значение поля имеет другой тип (например, ссылку на документ «ПоступлениеТоваровУслуг»), результатом приведения будет NULL, а не ошибка. Это ключевое поведение, которое используют для фильтрации по типу.

ВЫРАЗИТЬ допустимо применять в секциях ВЫБРАТЬ, ГДЕ, условиях соединения, а также в параметрах виртуальных таблиц. В секции ГДЕ приведение к ссылочному типу используется реже — обычно там достаточно проверки через ТИПЗНАЧЕНИЯ или сравнение с конкретной ссылкой через параметр.

Отбор записей по типу ссылки в составном поле

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

Первый — сравнение результата ВЫРАЗИТЬ с NULL: если приведение вернуло NULL, значит, значение имеет другой тип. Второй — функция ТИПЗНАЧЕНИЯ совместно с литералом ТИП:

ВЫБРАТЬ

Таблица.ОбъектРасчетов КАК Объект

ИЗ

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

ГДЕ

ТИПЗНАЧЕНИЯ(Таблица.ОбъектРасчетов) = ТИП(Документ.ЗаказКлиента)

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

Чем отбирать по типу

ВЫРАЗИТЬ + проверка на NULL

Подходит, когда результат приведения нужен дальше в выборке. Минус — лишняя операция приведения ради самой фильтрации.

ТИПЗНАЧЕНИЯ(Поле) = ТИП(...)

Прямая проверка типа без приведения. Оптимальна, если само приведённое значение не используется.

Ссылка В ИЕРАРХИИ / сравнение с параметром

Для отбора по конкретной ссылке или группе. Не решает задачу определения вида объекта.

Соединение таблиц по составному реквизиту

Когда составное поле участвует в соединении, без приведения типа запрос либо не выполнится, либо соединение пройдёт некорректно на уровне СУБД. Приведение к конкретному типу ссылки делает условие соединения однозначным:

ВЫБРАТЬ

Расчеты.СуммаОстаток,

Заказ.Номер КАК НомерЗаказа,

Заказ.Дата КАК ДатаЗаказа

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК Заказ

ПО Расчеты.ЗаказКлиента = Заказ.Ссылка

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

Обращение к реквизитам через точку от составного поля без ВЫРАЗИТЬ — частая причина ошибки «Поле не найдено» или неявных соединений со всеми таблицами составного типа. Платформа в этом случае строит соединения с каждой таблицей, входящей в составной тип, что резко увеличивает стоимость запроса. Явное приведение оставляет одно соединение и делает план запроса предсказуемым.

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

Важное ограничение: ВЫРАЗИТЬ не умеет превращать строку в ссылку. Запись вида ВЫРАЗИТЬ("00000000-0000-0000-0000-000000000000" КАК СправочникСсылка.Номенклатура) синтаксически недопустима — приведение к ссылочному типу возможно только от значения, которое уже является ссылкой (составное поле, параметр, результат другого выражения).

Если на входе строка с GUID, задача решается вне запроса: во встроенном языке используют Документы.ЗаказКлиента.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)), а полученную ссылку передают в запрос параметром. Внутри запроса с ней уже можно работать как с обычным ссылочным значением.

Параметр запроса произвольного типа тоже приводят через ВЫРАЗИТЬ, когда платформа не может вывести тип автоматически: ГДЕ Таблица.Ссылка = ВЫРАЗИТЬ(&Документ КАК ДокументСсылка.ЗаказКлиента). Это особенно актуально, если параметр может содержать NULL или значение нетипизировано.

Приведение в параметрах виртуальных таблиц и СКД

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

РегистрСведений.ЦеныНоменклатуры.СрезПоследних(

&Период,

Номенклатура = ВЫРАЗИТЬ(&Номенклатура КАК СправочникСсылка.Номенклатура)

) КАК Цены

В СКД конструкция ВЫРАЗИТЬ используется в тексте набора данных и в выражениях вычисляемых полей. При этом в отборах СКД для полей составного типа платформа умеет предлагать пользователю выбор вида ссылки через «Тип значения», но внутри текста запроса набора данных приведение всё равно остаётся обязанностью разработчика.

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

Как привести составное поле к ссылке
  1. 1
    Определите, какие виды объектов реально хранятся в составном реквизите (посмотрите тип в конфигураторе)
  2. 2
    В секции ВЫБРАТЬ примените ВЫРАЗИТЬ(Поле КАК НужныйТипСсылка) с понятным псевдонимом
  3. 3
    Если нужен отбор только по этому виду — добавьте условие ТИПЗНАЧЕНИЯ(Поле) = ТИП(...) или проверку приведённого значения на НЕ NULL
  4. 4
    Обращайтесь к реквизитам только через приведённое поле, а не через исходное составное
  5. 5
    Выполните запрос в консоли и проверьте, что строки с другими типами дали NULL, а нужные — заполненные реквизиты

Типичные ошибки и как их диагностировать

Ошибка «Неверные параметры в операции сравнения» или «Поле не найдено» чаще всего означает, что разработчик обратился к реквизиту составного поля без приведения, и платформа не смогла однозначно определить таблицу-источник. Лечится явным ВЫРАЗИТЬ до обращения через точку.

Обратная ситуация — запрос выполняется, но возвращает пустые поля. Причина почти всегда в том, что фактический тип значений не совпадает с типом приведения: значения другого вида превратились в NULL. Диагностируется добавлением в выборку ТИПЗНАЧЕНИЯ(Поле) и проверкой, какие типы реально присутствуют в данных.

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

Типичные ошибки
01
Обращение к реквизитам составного поля без ВЫРАЗИТЬ — ошибка исполнения или неявные соединения со всеми таблицами типа
02
Попытка привести строку с GUID к ссылке прямо в запросе — синтаксическая ошибка, ссылку из строки создают во встроенном языке
03
Использование ВЫРАЗИТЬ для отбора по типу там, где достаточно ТИПЗНАЧЕНИЯ — лишние операции и более тяжёлый план запроса
04
Ожидание, что ВЫРАЗИТЬ отфильтрует записи — он не фильтрует, а превращает чужие типы в NULL, отбор нужно писать отдельно
05
Приведение к типу, которого нет в составе составного поля, — все значения станут NULL без какой-либо ошибки

Проверка результата и границы применения

Корректность приведения проверяется на контрольной выборке: в запрос добавляют исходное поле, приведённое поле и ТИПЗНАЧЕНИЯ исходного поля. Для значений нужного вида приведённое поле должно совпадать с исходным, для остальных — содержать NULL. Любое расхождение (например, NULL там, где тип подходящий) говорит об ошибке в имени типа.

ВЫРАЗИТЬ не заменяет проектные решения. Если составной реквизит постоянно приводится к одному и тому же типу в десятках запросов, это признак того, что составной тип избыточен и реквизит стоит сузить на уровне метаданных. Запросное приведение — инструмент работы с уже существующей структурой, а не способ компенсировать её недостатки бесконечно.

На больших таблицах имеет смысл сравнить планы запросов с приведением и без него. Явное приведение почти всегда выигрывает у неявного поведения платформы, но лишние ВЫРАЗИТЬ в секции ГДЕ там, где хватает ТИПЗНАЧЕНИЯ, тоже добавляют стоимость.

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

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

Приведённое поле для значений нужного вида
Норма

Совпадает с исходным значением, реквизиты через точку заполнены

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

NULL при подходящем типе — проверьте имя типа в ВЫРАЗИТЬ

Значения других видов
Норма

Приведённое поле равно NULL, строки либо отфильтрованы, либо ожидаемо пустые

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

Ошибка исполнения запроса — вероятно, обращение к реквизитам идёт мимо приведения

Время выполнения на реальных данных
Норма

Сопоставимо с запросом без составного поля

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

Резкий рост времени — проверьте неявные соединения по составному типу

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

Можно ли через ВЫРАЗИТЬ получить ссылку из строки с GUID?

Нет. Оператор приводит только ссылочные значения к другому ссылочному типу. Строку с идентификатором преобразуют во встроенном языке через ПолучитьСсылку(Новый УникальныйИдентификатор(Строка)), а результат передают в запрос параметром.

Что вернёт ВЫРАЗИТЬ, если значение имеет другой тип ссылки?

NULL, без ошибки исполнения. Поэтому ВЫРАЗИТЬ сам по себе не фильтрует записи — строки остаются в выборке, просто приведённое поле пустое. Для отбора добавляют условие на NULL или ТИПЗНАЧЕНИЯ.

Что лучше для отбора по виду документа: ВЫРАЗИТЬ или ТИПЗНАЧЕНИЯ?

Для чистого отбора — ТИПЗНАЧЕНИЯ(Поле) = ТИП(...): это прямая проверка типа без операции приведения. ВЫРАЗИТЬ оправдан, когда приведённое значение дальше используется в выборке или соединении.

Почему запрос падает с ошибкой «Поле не найдено» при обращении к составному реквизиту?

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

Работает ли ВЫРАЗИТЬ в СКД и динамических списках?

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

Нужно ли повторно приводить поле после помещения во временную таблицу?

Нет. Если при выборке во временную таблицу поле уже приведено к конкретному типу, его тип фиксируется, и в последующих запросах пакета приведение не требуется.

Итог

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

ВЫРАЗИТЬ(Поле КАК ТипСсылка) приводит ссылочное значение к конкретному виду объекта: несовместимые значения становятся NULL. Используйте оператор для соединений по составным реквизитам и обращения к реквизитам через точку, а для чистого отбора по типу — ТИПЗНАЧЕНИЯ. Ссылку из строки с GUID создавайте во встроенном языке, а не в запросе.