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