При работе с запросами в системе 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда необходимо сравнить значения в полях с составным типом данных. Типичный пример — сопоставление данных из регистра сведений, где поле может принимать значение Неопределено, с данными из документа, где пустое значение представлено как ПустаяСсылка. Несмотря на то что визуально оба значения могут казаться «пустыми», для системы это принципиально разные сущности. В этой статье мы подробно разберем, как правильно организовать их сравнение в запросе, избежав типичных ошибок синтаксиса.
Прежде чем переходить к написанию кода, проанализируем, почему возникает сама проблема сравнения. В платформе 1С существуют три вида «пустоты» на уровне запросов:
ДокументСсылка.ЗаказКлиента). В базе данных она представлена уникальным идентификатором, состоящим из одних нулей.Сравнение Поле = ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка) вернет «Ложь», если в поле фактически хранится Неопределено, так как типы этих значений не совпадают. Рассмотрим, как решить эту задачу правильно.
Самый прямой способ — это явная проверка значения на Неопределено и его преобразование к нужному типу ссылки прямо в теле запроса. Рассмотрим пример кода, который позволяет привести все «пустые» значения к единому виду — пустой ссылке конкретного документа:
ВЫБРАТЬ
ВЫБОР
КОГДА ТоварыКПоступлению.ЗаказКлиента = НЕОПРЕДЕЛЕНО
ТОГДА ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)
ИНАЧЕ ТоварыКПоступлению.ЗаказКлиента
КОНЕЦ КАК ЗаказКлиента
ИЗ
РегистрСведений.ЗаказыПоставщикам КАК ТоварыКПоступлению
В данном примере мы анализируем поле ЗаказКлиента. Если система видит значение Неопределено, она подставляет пустую ссылку типа ЗаказКлиента. В противном случае используется исходное значение. Теперь результат этого выражения можно смело сравнивать с пустой ссылкой из другого документа.
Важный нюанс синтаксиса: Обратите внимание на использование функции ЗНАЧЕНИЕ(). Распространенной ошибкой является написание Документы (во множественном числе), как это принято во встроенном языке. В языке запросов 1С всегда используется единственное число: Документ, Справочник, Перечисление.
Существует более элегантный и часто более эффективный способ обработки составных типов. Если мы заранее знаем, к какому типу мы хотим привести данные для сравнения, мы можем использовать оператор ВЫРАЗИТЬ. Разберем по шагам, как это работает:
ВЫРАЗИТЬ(Поле КАК Документ.ЗаказКлиента).Неопределено или ссылка на другой тип (например, ЗаказПоставщику), результат выражения станет NULL.NULL с помощью функции ЕСТЬNULL.Посмотрим на пример реализации:
ВЫБРАТЬ
ЕСТЬNULL(
ВЫРАЗИТЬ(ТоварыКПоступлению.ЗаказКлиента КАК Документ.ЗаказКлиента),
ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)
) КАК ЗаказКлиентаПриведенный
ИЗ
РегистрСведений.ЗаказыПоставщикам КАК ТоварыКПоступлению
Этот метод хорош тем, что он автоматически «отсеивает» любые нерелевантные типы данных в составном поле, превращая их в NULL, а затем заменяет их на стандартную пустую ссылку.
Чтобы глубже понять суть проблемы, проанализируем, как эти данные хранятся на уровне SQL. Поля составного типа в 1С обычно представлены несколькими колонками в таблице СУБД. Одна колонка хранит двоичные данные (GUID ссылки), а другая — код типа данных (_TYPE).
Для значения Неопределено поле типа содержит специальный маркер (обычно 0 или NULL в колонке типа), а поле данных может быть пустым. Для Пустой ссылки поле типа содержит идентификатор метаданных документа, а поле GUID заполнено нулями. Именно поэтому прямое сравнение «в лоб» без приведения типов часто не дает результата — СУБД сравнивает разные комбинации колонок.
Выясним, как ведут себя эти значения при использовании УПОРЯДОЧИТЬ ПО (ORDER BY). Если в вашей выборке присутствуют и NULL, и Неопределено, и Пустые ссылки, 1С выстроит их в следующем порядке (по возрастанию):
NULL (всегда первый)НеопределеноТаким образом, Неопределено всегда будет находиться в списке выше, чем любая пустая ссылка документа.
Проанализируем ситуацию с точки зрения скорости работы системы. Использование ВЫБОР КОГДА или ТИПЗНАЧЕНИЯ() в условиях ГДЕ может негативно сказаться на производительности (запрос перестает быть SARGable, то есть СУБД становится сложнее использовать индексы).
Практические советы:
Неопределено на Пустую ссылку нужного типа в коде модуля объекта.ВЫРАЗИТЬ, так как это дает оптимизатору запросов 1С больше информации о предполагаемых типах данных.ЗНАЧЕНИЕ(Документ.Имя.ПустаяСсылка) — это стандарт, который нужно запомнить.Рассмотренные методы позволяют корректно обрабатывать неопределенные значения и обеспечивают надежное сравнение данных в запросах любой сложности. Для интерактивной проверки и отладки таких конструкций подойдёт инженерная консоль запросов для 1С.