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

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

Как передать пустую ссылку в запросе 1С

Как передать пустую ссылку в запрос 1С через ЗНАЧЕНИЕ, параметр и Неопределено. Примеры кода, типичные ошибки и проверка результата.

Проверка на пустую ссылку — одна из самых частых задач при написании запросов в 1С. Она нужна, когда требуется отобрать документы без заполненного реквизита, найти элементы справочника без родителя или, наоборот, исключить записи с незаполненными значениями. Способ передачи пустой ссылки зависит от того, известен ли тип реквизита заранее и откуда берётся значение — из кода или из параметра.

Главная сложность в том, что пустая ссылка в 1С типизирована: пустая ссылка справочника «Номенклатура» и пустая ссылка документа «РеализацияТоваровУслуг» — разные значения. Если сравнить поле с пустой ссылкой несовместимого типа, запрос либо вернёт пустой результат, либо выдаст ошибку. Поэтому важно понимать, какой механизм подходит в каждом случае.

Ниже разобраны три рабочих подхода: конструкция ЗНАЧЕНИЕ в тексте запроса, передача пустой ссылки через параметр и обработка составных реквизитов, где хранится значение Неопределено. Каждый подход сопровождается примером кода и указанием на типичные ошибки.

Способ 1: конструкция ЗНАЧЕНИЕ в тексте запроса

Самый надёжный и читаемый способ — встроить пустую ссылку прямо в текст запроса с помощью оператора ЗНАЧЕНИЕ. Он принимает литерал ссылочного типа, включая предопределённое значение ПустаяСсылка для любого справочника, документа, плана счетов и других ссылочных объектов.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПриходнаяНакладная.Ссылка

|ИЗ

| Документ.ПриходнаяНакладная КАК ПриходнаяНакладная

|ГДЕ

| ПриходнаяНакладная.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)";

Результат = Запрос.Выполнить();

Такой запрос вернёт все накладные, у которых реквизит «Контрагент» не заполнен. Обратите внимание: имя ссылочного типа пишется как в дереве метаданных — Справочник.Контрагенты, Документ.ЗаказПокупателя, ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения и так далее.

Преимущество подхода — не нужно объявлять параметры, а тип пустой ссылки гарантированно совпадает с типом реквизита. Недостаток — тип «зашит» в текст запроса, поэтому способ не подходит, когда тип реквизита определяется динамически в коде.

Способ 2: передача пустой ссылки через параметр

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Родитель = &Родитель";

Запрос.УстановитьПараметр("Родитель",

Справочники.Номенклатура.ПустаяСсылка());

Результат = Запрос.Выполнить();

Этот запрос отберёт элементы номенклатуры, находящиеся в корне справочника (у них родитель не задан). Метод ПустаяСсылка() доступен у всех менеджеров ссылочных типов: Справочники, Документы, ПланыСчетов, ПланыВидовРасчета, БизнесПроцессы, Задачи и других.

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

Порядок действий при передаче через параметр
  1. 1
    Сформируйте текст запроса с именованным параметром, например &ПустаяСсылка
  2. 2
    Получите пустую ссылку нужного типа: Справочники.ИмяСправочника.ПустаяСсылка()
  3. 3
    Установите параметр методом Запрос.УстановитьПараметр()
  4. 4
    Выполните запрос и проверьте, что результат не пустой (или пустой, если это ожидаемо)
  5. 5
    При подозрении на ошибку выведите тип параметра через ТипЗнч() для отладки

Сравнение с пустой ссылкой через ЕСТЬ NULL и составные типы

Отдельный случай — соединения таблиц. Если реквизит получен левым соединением и записи в присоединяемой таблице нет, поле будет содержать NULL, а не пустую ссылку. Сравнение NULL = ЗНАЧЕНИЕ(...) вернёт ложь, поэтому нужна конструкция ЕСТЬ NULL.

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура

|ИЗ

| Документ.Заказ.Товары КАК Товары

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды

| ПО Товары.Номенклатура = Штрихкоды.Владелец

|ГДЕ

| Штрихкоды.Штрихкод ЕСТЬ NULL";

Для составных реквизитов ситуация сложнее. Незаполненный составной реквизит может хранить Неопределено, которое в запросе представлено как NULL, либо пустую ссылку одного из допустимых типов — в зависимости от того, как заполнялся объект. Надёжная проверка объединяет оба условия через ИЛИ:

"ГДЕ

| Документ.Плательщик ЕСТЬ NULL

| ИЛИ Документ.Плательщик = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

| ИЛИ Документ.Плательщик = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)"

Сравнение способов проверки

ЗНАЧЕНИЕ в тексте запроса

Подходит, когда тип реквизита известен и фиксирован. Не требует параметров, но тип нельзя менять динамически.

Параметр с ПустаяСсылка()

Подходит, когда значение приходит из кода или тип определяется в runtime. Требует контроля типа передаваемого значения.

ЕСТЬ NULL

Обязательна для полей из левых соединений и составных реквизитов. Не заменяет проверку на пустую ссылку — это разные значения.

Проверка на непустую ссылку

Обратное условие — отобрать только записи с заполненным реквизитом — формулируется через оператор НЕ или неравенство. Оба варианта рабочие:

"ГДЕ

| НЕ Документ.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)"

"ГДЕ

| Документ.Контрагент <> &ПустойКонтрагент"

При работе с составными типами помните, что неравенство пустой ссылке не отсекает NULL. Если в выборку не должны попасть записи с незаполненным составным реквизитом, добавьте условие НЕ Поле ЕСТЬ NULL.

Типичные ошибки
01
Сравнение с Неопределено в тексте запроса — в языке запросов нет такого литерала, запрос завершится ошибкой
02
Передача в параметр пустой строки вместо пустой ссылки — типы несовместимы, условие никогда не выполнится
03
Сравнение поля из левого соединения с пустой ссылкой вместо ЕСТЬ NULL — записи без соответствия теряются
04
Использование ПустаяСсылка() не того типа: для составного реквизита пустая ссылка одного типа не равна пустой ссылке другого
05
Проверка строки длиной 36 нулей как признака пустой ссылки — работает не для всех типов и усложняет код

Как проверить, что запрос работает правильно

После написания запроса полезно убедиться, что условие действительно отбирает ожидаемые записи. Самый быстрый способ — консоль запросов (в типовых конфигурациях на управляемых формах она часто доступна как внешняя обработка или встроенный инструмент разработчика).

Проверочная методика проста: сначала выполните запрос без отбора и посмотрите, какие значения реально хранятся в реквизите. Затем добавьте условие и сравните количество строк. Если с условием «равно пустой ссылке» запрос вернул ноль строк, хотя вы точно видели незаполненные реквизиты, — почти наверняка там NULL или пустая ссылка другого типа.

Для отладки типа значения в коде используйте ТипЗнч(Значение) и сравнение ЗначениеЗаполнено(Значение). Функция ЗначениеЗаполнено() возвращает Ложь для пустой ссылки, Неопределено и пустой строки — это удобный универсальный критерий в коде, но в тексте запроса её аналога нет.

Контрольные точки

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

Количество строк с условием на пустую ссылку
Норма

Совпадает с числом записей, где реквизит визуально не заполнен

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

Ноль строк при наличии пустых реквизитов — вероятно, NULL или другой тип

Тип значения реквизита через ТипЗнч()
Норма

Тип совпадает с типом передаваемой пустой ссылки

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

Типы различаются — условие никогда не сработает

Поле из левого соединения
Норма

Используется ЕСТЬ NULL

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

Сравнение с пустой ссылкой отсекает нужные строки

Ограничения и частные сценарии

Несколько ситуаций требуют отдельного внимания. Во-первых, в параметрах виртуальных таблиц (например, отбор регистра сведений) передавать пустую ссылку можно, но отбор по незаполненному измерению часто лучше формулировать в секции ГДЕ — так запрос проще оптимизируется.

Во-вторых, для реквизитов типа «Характеристика» в типовых конфигурациях (механизм дополнительных реквизитов) пустое значение — это пустая ссылка плана видов характеристик «ДополнительныеРеквизитыИСведения» или соответствующего справочника, а не Неопределено. Проверяйте фактический тип по конфигуратору.

В-третьих, в запросах к внешним источникам данных и в СКД синтаксис ЗНАЧЕНИЕ поддерживается, но параметры в СКД часто удобнее типизировать на закладке «Параметры» компоновщика, указав доступные типы явно — тогда пустая ссылка будет корректно интерпретироваться при любом выбранном значении.

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

Частые вопросы

Можно ли передать Неопределено как параметр запроса?

Технически параметр со значением Неопределено установить можно, но сравнивать поле с ним в тексте запроса через равенство бессмысленно — NULL не равен ничему, включая NULL. Для отбора таких записей используйте условие Поле ЕСТЬ NULL.

Чем отличается пустая ссылка от NULL в запросе?

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

Как проверить пустую ссылку в коде без запроса?

Используйте функцию ЗначениеЗаполнено(Ссылка) — она вернёт Ложь для пустой ссылки. Альтернатива — сравнение Ссылка = Справочники.ИмяСправочника.ПустаяСсылка() или метод Ссылка.Пустая(), который возвращает Истину для пустой ссылки.

Почему условие с пустой ссылкой не отбирает записи, хотя реквизит пустой?

Наиболее вероятные причины: реквизит составного типа и хранит пустую ссылку другого типа, значение получено левым соединением и равно NULL, либо в параметр передана пустая строка вместо ссылки. Проверьте фактическое значение и его тип через консоль запросов.

Работает ли ЗНАЧЕНИЕ(Перечисление.Имя.ПустаяСсылка)?

Да, конструкция ЗНАЧЕНИЕ поддерживает перечисления, включая пустую ссылку перечисления. Синтаксис аналогичен: ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка). Это удобно для поиска документов с незаполненным реквизитом перечислимого типа.

Итог

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

Для фиксированного типа используйте ЗНАЧЕНИЕ(Тип.ПустаяСсылка) в тексте запроса, для динамического — параметр с ПустаяСсылка(). Поля из соединений и составные реквизиты дополнительно проверяйте через ЕСТЬ NULL. Расхождение типов — главная причина «неработающего» условия.