Как сравнить «Неопределено» и «Пустую ссылку» в запросе 1С?

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

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

Различие между Неопределено, Пустой ссылкой и NULL

Прежде чем переходить к написанию кода, проанализируем, почему возникает сама проблема сравнения. В платформе 1С существуют три вида «пустоты» на уровне запросов:

  1. Пустая ссылка — это значение конкретного ссылочного типа (например, ДокументСсылка.ЗаказКлиента). В базе данных она представлена уникальным идентификатором, состоящим из одних нулей.
  2. Неопределено — это специальное значение, которое может храниться только в полях составного типа (когда тип еще не выбран). В SQL-таблицах это состояние описывается специальными маркерами в служебных колонках типов.
  3. NULL — это отсутствие значения как такового, возникающее чаще всего при левых соединениях таблиц, когда запись во второй таблице не была найдена.

Сравнение Поле = ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка) вернет «Ложь», если в поле фактически хранится Неопределено, так как типы этих значений не совпадают. Рассмотрим, как решить эту задачу правильно.

Решение 1: Использование конструкции ВЫБОР КОГДА

Самый прямой способ — это явная проверка значения на Неопределено и его преобразование к нужному типу ссылки прямо в теле запроса. Рассмотрим пример кода, который позволяет привести все «пустые» значения к единому виду — пустой ссылке конкретного документа:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ТоварыКПоступлению.ЗаказКлиента = НЕОПРЕДЕЛЕНО
            ТОГДА ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)
        ИНАЧЕ ТоварыКПоступлению.ЗаказКлиента
    КОНЕЦ КАК ЗаказКлиента
ИЗ
    РегистрСведений.ЗаказыПоставщикам КАК ТоварыКПоступлению

В данном примере мы анализируем поле ЗаказКлиента. Если система видит значение Неопределено, она подставляет пустую ссылку типа ЗаказКлиента. В противном случае используется исходное значение. Теперь результат этого выражения можно смело сравнивать с пустой ссылкой из другого документа.

Важный нюанс синтаксиса: Обратите внимание на использование функции ЗНАЧЕНИЕ(). Распространенной ошибкой является написание Документы (во множественном числе), как это принято во встроенном языке. В языке запросов 1С всегда используется единственное число: Документ, Справочник, Перечисление.

Решение 2: Использование оператора ВЫРАЗИТЬ и ЕСТЬNULL

Существует более элегантный и часто более эффективный способ обработки составных типов. Если мы заранее знаем, к какому типу мы хотим привести данные для сравнения, мы можем использовать оператор ВЫРАЗИТЬ. Разберем по шагам, как это работает:

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

Посмотрим на пример реализации:


ВЫБРАТЬ
    ЕСТЬNULL(
        ВЫРАЗИТЬ(ТоварыКПоступлению.ЗаказКлиента КАК Документ.ЗаказКлиента),
        ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)
    ) КАК ЗаказКлиентаПриведенный
ИЗ
    РегистрСведений.ЗаказыПоставщикам КАК ТоварыКПоступлению

Этот метод хорош тем, что он автоматически «отсеивает» любые нерелевантные типы данных в составном поле, превращая их в NULL, а затем заменяет их на стандартную пустую ссылку.

Технические нюансы хранения в СУБД

Чтобы глубже понять суть проблемы, проанализируем, как эти данные хранятся на уровне SQL. Поля составного типа в 1С обычно представлены несколькими колонками в таблице СУБД. Одна колонка хранит двоичные данные (GUID ссылки), а другая — код типа данных (_TYPE).

Для значения Неопределено поле типа содержит специальный маркер (обычно 0 или NULL в колонке типа), а поле данных может быть пустым. Для Пустой ссылки поле типа содержит идентификатор метаданных документа, а поле GUID заполнено нулями. Именно поэтому прямое сравнение «в лоб» без приведения типов часто не дает результата — СУБД сравнивает разные комбинации колонок.

Особенности сортировки

Выясним, как ведут себя эти значения при использовании УПОРЯДОЧИТЬ ПО (ORDER BY). Если в вашей выборке присутствуют и NULL, и Неопределено, и Пустые ссылки, 1С выстроит их в следующем порядке (по возрастанию):

  1. NULL (всегда первый)
  2. Неопределено
  3. Простые типы (Булево, Число, Дата, Строка)
  4. Ссылочные типы (включая пустые ссылки)

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

Производительность и рекомендации

Проанализируем ситуацию с точки зрения скорости работы системы. Использование ВЫБОР КОГДА или ТИПЗНАЧЕНИЯ() в условиях ГДЕ может негативно сказаться на производительности (запрос перестает быть SARGable, то есть СУБД становится сложнее использовать индексы).

Практические советы:

Рассмотренные методы позволяют корректно обрабатывать неопределенные значения и обеспечивают надежное сравнение данных в запросах любой сложности. Для интерактивной проверки и отладки таких конструкций подойдёт инженерная консоль запросов для 1С.

← На главную