В практике разработки на платформе 1С:Предприятие часто возникают ситуации, когда необходимо выполнить фильтрацию в запросе по конкретному, заранее известному элементу справочника, перечисления или плана счетов. Стандартный и наиболее правильный путь — это передача ссылки через Запрос.УстановитьПараметр(). Однако бывают случаи, когда текст запроса должен быть самодостаточным. В данной статье мы подробно разберем, как «зашить» ссылку на объект прямо в текст запроса, какие инструменты для этого предоставляет платформа и с какими ограничениями можно столкнуться.
Если объект, к которому мы хотим обратиться, является предопределенным (созданным в конфигураторе), платформа предоставляет максимально удобный и быстрый механизм — литерал ЗНАЧЕНИЕ(). Этот метод работает на уровне SQL максимально эффективно, так как система заранее знает внутренний идентификатор этого объекта.
Рассмотрим синтаксис использования этой конструкции для различных типов данных. Нам необходимо указать тип метаданных и полное имя объекта через точку.
Пример работы с перечислениями:
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Количество
ИЗ
РегистрНакопления.Продажи КАК Продажи
ГДЕ
Продажи.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
Пример работы с предопределенными элементами справочников:
ВЫБРАТЬ
Остатки.Склад,
Остатки.В Наличии
ИЗ
РегистрНакопления.Запасы.Остатки КАК Остатки
ГДЕ
Остатки.Склад = ЗНАЧЕНИЕ(Справочник.Склады.ОсновнойСклад)
Пример работы с планом счетов:
ВЫБРАТЬ
Хозрасчетный.СуммаОстаток
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки КАК Хозрасчетный
ГДЕ
Хозрасчетный.Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ТоварыНаСкладах)
Проанализируем этот подход: он является самым надежным, так как предопределенные элементы защищены от удаления пользователем, а их имена в конфигураторе остаются неизменными. Если объект часто фигурирует в программной логике, рекомендуется сделать его именно предопределенным.
Что делать, если элемент справочника был создан пользователем в режиме «Предприятие» и не имеет предопределенного имени в конфигураторе? В этом случае мы не можем использовать ЗНАЧЕНИЕ(). Нам остается только обращаться к свойствам объекта, которые нам известны.
Разберем ситуацию, когда нам нужно выбрать данные только по одной конкретной позиции номенклатуры, зная её код. Мы можем использовать условие ГДЕ с проверкой строкового значения.
ВЫБРАТЬ
Цены.Цена,
Цены.Номенклатура.Наименование
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ГДЕ
Цены.Номенклатура.Код = "000000001"
Выясним причины, почему этот способ считается менее надежным:
Код в 1С почти всегда индексировано.Если нам нужно программно «вычислить» ссылку прямо в запросе для дальнейшего использования в полях ВЫБОР, мы можем применить следующую конструкцию:
ВЫБРАТЬ
ВЫБОР
КОГДА Номенклатура.Артикул = "АРТ-100-20" ТОГДА Номенклатура.Ссылка
ИНАЧЕ NULL
КОНЕЦ КАК НужнаяСсылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
Важно не путать обращение к конкретному объекту и проверку типа. В сообщениях форума часто упоминается оператор ССЫЛКА. Проанализируем его назначение. Этот оператор используется в основном для работы с составными типами данных (например, поле «Владелец» или «ДокументОснование»).
Он позволяет проверить, относится ли ссылка в данном поле к конкретной таблице. Это критически важно для производительности при обращении к реквизитам через точку.
Пример правильного использования ССЫЛКА:
ВЫБРАТЬ
Затраты.Ссылка
ИЗ
Документ.ПоступлениеТоваровУслуг КАК Затраты
ГДЕ
Затраты.Контрагент ССЫЛКА Справочник.Контрагенты
Это условие отсечет все записи, где в поле контрагента (если бы оно было составным) указан не элемент справочника Контрагенты, а, например, физическое лицо. Но запомните: оператор ССЫЛКА никогда не вернет вам конкретного «Иванова» или «Петрова», он лишь подтвердит, что это в принципе «Контрагент».
Рассмотрим нестандартную, но эффективную ситуацию. Допустим, у нас есть настройка «Основной склад», которая хранится в константе. Нам нужно получить данные по этому складу в запросе, не передавая его параметром. Мы можем просто добавить таблицу константы в секцию ИЗ.
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.ВНаличииОстаток
ИЗ
Константа.ОсновнойСклад КАК ТекСклад
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Остатки.Склад = ТекСклад.Значение
В данном примере мы «вытащили» ссылку на склад из базы данных динамически. Это отличный способ избежать жесткого кодирования (hardcode) наименований или кодов в тексте запроса.
Рассмотрим важный технический нюанс. В языке запросов 1С невозможно использовать литералы типа УникальныйИдентификатор (GUID). Вы не можете написать конструкцию вида ГДЕ Ссылка = "550e8400-e29b-41d4-a716-446655440000". Платформа просто не поймет эту строку как идентификатор.
Если у вас есть GUID в виде строки и вам нужно найти объект именно по нему, у вас есть два пути:
Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрGUID))) и передать её как параметр &Ссылка.Подведем итог нашему анализу и определим иерархию методов по их надежности и скорости:
&Параметр. Это позволяет СУБД кэшировать план запроса и защищает код от изменений в данных.ЗНАЧЕНИЕ(Справочник.Имя.ПредопределенныйЭлемент). Это быстро, надежно и типизировано.Константы или использование функциональных опций.Посмотрим на ситуацию с точки зрения производительности: каждый раз, когда вы меняете текст запроса (вставляя туда разные коды строками), 1С и SQL тратят ресурсы на повторную компиляцию запроса. Использование параметров позволяет избежать этой нагрузки, поэтому старайтесь минимизировать использование «жестко заданных» значений в текстах сложных и часто вызываемых запросов.