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