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