Что возвращает в запросе конструкция ЗНАЧЕНИЕ(Справочник.ИмяСправочника) и как с ней работать

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

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

Внутреннее представление и природа возвращаемого значения

Проанализируем ситуацию, когда в тексте запроса используется обращение к метаданным без уточнения элемента:


ВЫБРАТЬ
    ЗНАЧЕНИЕ(Справочник.Контрагенты) КАК ПолеТипа

В консоли запросов разработчик может увидеть шестнадцатеричное значение вида 08 00 00 83 либо Неопределено (в зависимости от клиента и способа отображения). Выясним причину такого поведения:

  1. Эквивалентность функции ТИП: Синтаксический анализатор языка запросов (SDBL) воспринимает конструкцию ЗНАЧЕНИЕ(Справочник.Имя) как литерал типа данных, что полностью эквивалентно вызову функции ТИП(Справочник.Имя).
  2. Внутренний идентификатор СУБД: Шестнадцатеричный код (например, 08 00 00 83) — это бинарный код типа объекта метаданных. Платформа 1С использует его на уровне таблиц базы данных для хранения и идентификации типов в полях составного типа (Reference-поля), где отдельно хранится код таблицы и отдельно GUID ссылки.

Посмотрим на пример логической проверки, подтверждающей эту эквивалентность:


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

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

Почему происходит ошибка при выгрузке запроса

Рассмотрим распространенную проблему: запрос с конструкцией ЗНАЧЕНИЕ(Справочник.Имя) в блоке ВЫБРАТЬ успешно выполняется на сервере баз данных, но при попытке выгрузить результат во встроенном языке происходит аварийное завершение:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ЗНАЧЕНИЕ(Справочник.Контрагенты) КАК ТипОбъекта,
    |    ТИПЗНАЧЕНИЯ(ЗНАЧЕНИЕ(Справочник.Контрагенты)) КАК ТипЗначенияПоля";
Выборка = Запрос.Выполнить();
ТаблицаРезультата = Выборка.Выгрузить(); // Вызывает системную ошибку

Причина ошибки заключается в том, что платформа 1С не поддерживает маршалинг и сериализацию «сырых» бинарных литералов типов метаданных в стандартные типы встроенного языка для колонок объекта ТаблицаЗначений. Литералы типов в языке запросов спроектированы исключительно для вычислений внутри сервера баз данных (в секциях ГДЕ, КОГДА ... ТОГДА, СОЕДИНЕНИЕ), а не для передачи в выходной набор колонок.

Корректные способы получения пустых ссылок

Если цель запроса состояла в получении пустой ссылки на справочник, документ или иной ссылочный тип, необходимо явно указывать свойство пустой ссылки. Разберем правильный синтаксис:


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

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

Правильные способы проверки и ограничения типов в запросах

Когда требуется проверить тип поля составного типа или привести значение к конкретной таблице метаданных, рассмотрим стандартные и проверенные практики платформы 1С:

  1. Проверка через оператор ССЫЛКА: Наиболее производительный и канонический способ проверки принадлежности ссылки к конкретному справочнику или документу:
    
    ВЫБРАТЬ
        Взаиморасчеты.Документ,
        ВЫБОР
            КОГДА Взаиморасчеты.Документ ССЫЛКА Документ.РеализацияТоваровУслуг
                ТОГДА "Реализация"
            КОГДА Взаиморасчеты.Документ ССЫЛКА Документ.ПоступлениеТоваровУслуг
                ТОГДА "Поступление"
            ИНАЧЕ "Прочее"
        КОНЕЦ КАК ВидДокумента
    ИЗ
        РегистрНакопления.ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты
    
  2. Проверка через ТИПЗНАЧЕНИЯ и ТИП: Используется для прямого сравнения типов на уровне СУБД:
    
    ВЫБРАТЬ
        Задачи.Объект
    ИЗ
        Задача.ЗадачиПользователя КАК Задачи
    ГДЕ
        ТИПЗНАЧЕНИЯ(Задачи.Объект) = ТИП(Справочник.Контрагенты)
    
  3. Ограничение составного типа функцией ВЫРАЗИТЬ: Если необходимо разыменовать реквизиты составного поля, обязательно приводим тип с помощью ВЫРАЗИТЬ:
    
    ВЫБРАТЬ
        ВЫРАЗИТЬ(Задачи.Объект КАК Справочник.Контрагенты).ИНН КАК ИННКонтрагента
    ИЗ
        Задача.ЗадачиПользователя КАК Задачи
    
  4. Передача типа через параметры запроса: Если тип необходимо определять динамически в коде 1С, передаем его через объект Тип:
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    СкладскиеОстатки.Номенклатура
        |ИЗ
        |    РегистрНакопления.ТоварыНаСкладах КАК СкладскиеОстатки
        |ГДЕ
        |    ТИПЗНАЧЕНИЯ(СкладскиеОстатки.Номенклатура) = &ИскомыйТип";
    
    Запрос.УстановитьПараметр("ИскомыйТип", Тип("СправочникСсылка.Номенклатура"));
    Результат = Запрос.Выполнить();
    

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

← На главную