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

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

Как в 1С выразить значение как ссылку на справочник

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

При работе с запросами в 1С часто встречаются поля составного типа: регистратор, владелец, свойство или реквизит, который может хранить ссылки на разные справочники и документы. Чтобы обратиться к реквизитам такого поля или отфильтровать записи по типу объекта, значение нужно привести к конкретному типу. Для этого в языке запросов 1С служит оператор ВЫРАЗИТЬ (CAST).

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

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

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

Базовая форма оператора выглядит так: ВЫРАЗИТЬ(Выражение КАК ТипДанных). Для ссылочного типа в качестве типа указывается имя объекта метаданных, например Справочник.Контрагенты или Справочник.Организации. Оператор можно использовать в списке выборки, в условиях ГДЕ, в соединениях и в секции ИМЕЮЩИЕ.

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

Имена справочников в операторе пишутся без кавычек и должны точно совпадать с именем объекта в конфигураторе. Если справочник переименован, запрос перестанет работать — синтаксическая проверка модуля это выявит, но запросы, собранные строкой в коде, проверяются только в момент выполнения.

В одном поле составного типа можно выполнить несколько приведений к разным справочникам и собрать результат через ВЫБОР ... КОГДА ... ИНАЧЕ КОНЕЦ, если нужно получить представление значения независимо от фактического типа.

Когда приведение к справочнику действительно нужно

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

Второй сценарий — соединение таблиц по составному полю. Соединять по составному полю напрямую нельзя: платформа запрещает такие соединения из-за неоднозначности типа. Приведение снимает ограничение: ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура ПО ВЫРАЗИТЬ(Таб.Владелец КАК Справочник.Номенклатура) = Номенклатура.Ссылка.

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

Маршрут решения

Как выбрать действие

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

Отличия ВЫРАЗИТЬ от ТИПЗНАЧЕНИЯ и условия ССЫЛКА

Эти три механизма часто путают, хотя они решают разные задачи. ВЫРАЗИТЬ меняет интерпретацию значения и возвращает ссылку или NULL. ТИПЗНАЧЕНИЯ возвращает тип значения и используется для сравнения. Условие ССЫЛКА проверяет принадлежность значения указанному виду объектов.

КонструкцияЧто возвращаетТипичное применение
ВЫРАЗИТЬ(Поле КАК Справочник.Имя)Ссылка или NULLДоступ к реквизитам, соединения
ТИПЗНАЧЕНИЯ(Поле) = ТИП(Справочник.Имя)Истина/ЛожьФильтрация по точному типу
Поле ССЫЛКА Справочник.ИмяИстина/ЛожьБыстрая фильтрация в ГДЕ

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

Пошаговый пример: отбор и соединение по составному полю

Рассмотрим практическую задачу: в регистре сведений есть измерение составного типа, которое может хранить ссылку на справочник «Номенклатура» или «Контрагенты». Нужно получить только записи по номенклатуре и вывести её артикул.

Порядок действий
  1. 1
    Откройте консоль запросов или модуль, где строится запрос, и определите фактический состав типов поля через конфигуратор
  2. 2
    Напишите выборку из регистра и добавьте поле ВЫРАЗИТЬ(Регистр.Объект КАК Справочник.Номенклатура) КАК Номенклатура
  3. 3
    Добавьте условие ГДЕ Регистр.Объект ССЫЛКА Справочник.Номенклатура, чтобы отсечь записи других типов
  4. 4
    Обратитесь к реквизиту: ВЫРАЗИТЬ(Регистр.Объект КАК Справочник.Номенклатура).Артикул
  5. 5
    Выполните запрос и проверьте, что в результате нет строк с NULL в поле Номенклатура
bsl
ВЫБРАТЬ
	ВЫРАЗИТЬ(Цены.Объект КАК Справочник.Номенклатура) КАК Номенклатура,
	ВЫРАЗИТЬ(Цены.Объект КАК Справочник.Номенклатура).Артикул КАК Артикул,
	Цены.Цена КАК Цена
ИЗ
	РегистрСведений.Цены КАК Цены
ГДЕ
	Цены.Объект ССЫЛКА Справочник.Номенклатура

Обратите внимание: приведение в запросе повторяется дважды — для самого поля и для реквизита. Это нормально. Альтернатива — вынести приведение во временную таблицу или вложенный запрос и дальше работать уже с приведённым полем, что улучшает читаемость при большом числе реквизитов.

Ограничения и поведение при несовпадении типов

Главное ограничение: ВЫРАЗИТЬ не генерирует исключение при несовпадении типа. Записи, где поле содержит ссылку другого вида, просто получат NULL в приведённом поле. Если забыть условие ССЫЛКА или ТИПЗНАЧЕНИЯ, в выборку попадут строки с пустым результатом, что исказит итоги и соединения.

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

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

Приведение типов во встроенном языке вне запросов

Вне запросов оператора ВЫРАЗИТЬ не существует — он относится только к языку запросов. В модуле объекта или общем модуле проверка и работа со ссылкой на справочник выполняется иначе: через ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") и дальнейшее обращение к реквизитам напрямую, поскольку встроенный язык работает с типами динамически.

Если нужно получить ссылку по строковому представлению уникального идентификатора, используется конструкция Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)). Это не приведение типа, а создание ссылки по известному идентификатору — при отсутствии объекта в базе получится битая ссылка, поэтому предварительно стоит проверять существование объекта.

В типовых конфигурациях составные поля встречаются в регистрах сведений с произвольными объектами, в планах обмена и в механизмах дополнительных свойств. Перед написанием запроса откройте структуру объекта в конфигураторе и посмотрите точный список типов поля — это избавит от приведений к справочникам, которых в поле никогда не бывает.
ПЗ
Практическое замечание

Типичные ошибки и проверка результата

Разработчики, которые только начинают использовать приведение типов, повторяют одни и те же ошибки. Большинство из них приводит не к падению запроса, а к тихо неверным данным, что опаснее.

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

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

Поле после ВЫРАЗИТЬ
Норма

Содержит ссылки нужного справочника, навигация по реквизитам работает

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

Значения NULL там, где ожидались ссылки — тип поля не совпадает с указанным

Количество строк результата
Норма

Совпадает с числом записей, где поле имеет целевой тип

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

Лишние строки с пустыми значениями — забыто условие ССЫЛКА

Реквизиты приведённого объекта
Норма

Артикул, наименование и другие поля заполнены

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

Строки вида «<Объект не найден>» — в данных есть битые ссылки

Для диагностики полезно временно вывести рядом исходное поле и приведённое: сразу видно, какие записи не прошли приведение. В консоли запросов это делается добавлением обоих полей в выборку без изменения условий.

Частые вопросы о приведении к ссылке на справочник

Можно ли выразить поле сразу как несколько справочников?

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

Чем ВЫРАЗИТЬ отличается от оператора ЕСТЬ NULL?

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

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

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

Что вернёт ВЫРАЗИТЬ, если поле содержит перечисление?

NULL. Перечисление и ссылка на справочник — несовместимые для приведения типы. Чтобы обработать такие записи, добавьте отдельное приведение к нужному перечислению или условие по его типу.

Можно ли в запросе получить ссылку справочника из строки с кодом или наименованием?

Напрямую нет: ВЫРАЗИТЬ не выполняет поиск. Нужно соединить таблицу со справочником по полю Код или Наименование и взять оттуда Ссылку, учитывая возможные дубли и несовпадения форматов.

Влияет ли приведение типов на скорость запроса?

Да, особенно на больших таблицах и при последующем обращении к реквизитам через точку. Рекомендуется сначала сузить выборку условиями, затем приводить типы, а при массовой обработке проверять план запроса и при необходимости использовать временные таблицы.

Итог

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

Приведение к ссылке на справочник выполняется оператором ВЫРАЗИТЬ(Поле КАК Справочник.Имя) только в языке запросов. Несовпадающие типы дают NULL, поэтому приведение сочетают с условием ССЫЛКА или ТИПЗНАЧЕНИЯ. Оператор нужен для доступа к реквизитам составных полей и соединений; для простой фильтрации достаточно условия ССЫЛКА.