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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При написании запросов в платформе 1С:Предприятие часто возникает задача получить значение реквизита объекта, ссылка на который передается в запрос в виде параметра. Прямая попытка обратиться к полю через точку, например &СсылкаНаЭлемент.Код, приводит к синтаксической ошибке, так как механизм синтаксического анализа запросов не знает точный тип данных переданного параметра.

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

Способ 1. Официальный и надежный вариант: явное приведение типа через ВЫРАЗИТЬ

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

Посмотрим на пример правильного синтаксиса:


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

Данную конструкцию можно использовать не только в списке выборки, но и в секции условий ГДЕ:


ВЫБРАТЬ
    Спр.Ссылка КАК Ссылка
ИЗ
    Справочник.Валюты КАК Спр
ГДЕ
    Спр.Код <> ВЫРАЗИТЬ(&СсылкаНаЭлемент КАК Справочник.Валюты).Код

Преимущества данного подхода:

  1. Полная совместимость: запрос без ошибок открывается, редактируется и сохраняется в стандартном Конструкторе запросов.
  2. Синтаксический контроль: конфигуратор корректно проверяет наличие реквизитов у указанного типа метаданных.
  3. Поддержка во всех версиях: работает на любых режимах совместимости платформы 1С 8.2 и 8.3.

Способ 2. Недокументированная конструкция со скобками

Проанализируем альтернативный вариант, с которым иногда сталкиваются разработчики:


ВЫБРАТЬ
    Спр.Ссылка КАК Ссылка
ИЗ
    Справочник.Валюты КАК Спр
ГДЕ
    Спр.Код <> (&Ссылка).Код

Особенности этого способа:

  1. Обертывание параметра в круглые скобки (&Ссылка).Код является недокументированной особенностью парсера СУБД. В ряде релизов платформы такой запрос может успешно выполниться на сервере.
  2. Конструктор запросов не поддерживает данный синтаксис: при попытке открыть запрос в конструкторе возникнет ошибка синтаксиса либо текст будет искажен.
  3. В зависимости от режима совместимости конфигурации и версии платформы поведение парсера может меняться, поэтому использовать конструкцию (&Ссылка).Реквизит в рабочих решениях крайне не рекомендуется.

Особенности работы с типами данных и значениями NULL

Разберем поведение платформы при выполнении запроса в нестандартных ситуациях:

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

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

Механизм трансляции в SQL и производительность

Выясним, как платформа обрабатывает разыменование параметров на уровне СУБД:

  1. При выполнении конструкции ВЫРАЗИТЬ(&Параметр КАК ...).Реквизит платформа строит неявное левое соединение (LEFT JOIN) или скалярный подзапрос к таблице соответствующего объекта.
  2. Если запрос выполняется многократно или в цикле, каждое такое неявное соединение создает дополнительную нагрузку на сервер баз данных.

Для оптимизации производительности рекомендуем следующие альтернативы:

  1. Передача готового значения: если реквизит известен до выполнения запроса, эффективнее прочитать его значение во встроенном языке (например, через ОбщегоНазначения.ЗначениеРеквизитаОбъекта) и передать в запрос простым скалярным типом (число, строка): Запрос.УстановитьПараметр("ИскомыйКод", СсылкаНаЭлемент.Код);
  2. Явное соединение: если требуется получить сразу несколько реквизитов переданного объекта, целесообразно выполнить явное ЛЕВОЕ СОЕДИНЕНИЕ с таблицей справочника или документа по условию равенства ссылки параметру.
  3. Ограничение в СКД: помните, что в параметрах схемы компоновки данных прямое разыменование параметров запроса не поддерживается — значения полей следует вычислять либо на вкладке «Параметры» через выражения языка 1С, либо в наборе данных запроса.
← На главную