Почему запрос в 1С позволяет использовать ЗНАЧЕНИЕ(ИмяТипа) без уточнения и что он возвращает?

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

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

Суть проблемы и пример кода

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

Разберем пример кода, который демонстрирует это поведение:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ЗНАЧЕНИЕ(Справочник.Банки) КАК Результат";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Для Каждого Строка Из РезультатЗапроса Цикл
    Сообщить("Тип значения: " + ТипЗнч(Строка.Результат));
    Сообщить("Значение: " + Строка.Результат);
КонецЦикла;

При выполнении этого кода мы не получим ошибку компиляции запроса. Вместо этого в таблице значений в колонке Результат окажется значение Неопределено. Однако, если мы посмотрим на результат через выборку или в консоли запросов, мы можем увидеть "сырые" двоичные данные.

Разбор внутреннего устройства: идентификатор таблицы (TableID)

Выясним причину такого странного поведения платформы. Когда мы пишем ЗНАЧЕНИЕ(Справочник.Банки), парсер запросов 1С распознает объект метаданных, но не находит после него уточняющей точки (например, .ПустаяСсылка). В этот момент система возвращает внутренний системный идентификатор таблицы метаданных (так называемый TableID).

Проанализируем характеристики этого значения:

  1. Объем данных: Обычно это значение занимает 5 байт.
  2. Тип в базе данных: На уровне СУБД это короткий двоичный код, который платформа использует для адресации таблиц.
  3. Представление: В выборке запроса (Выбрать()) это могут быть ДвоичныеДанные, но встроенный язык 1С не имеет адекватного типа для отображения "абстрактного идентификатора таблицы".

Именно поэтому при использовании метода Выгрузить() система пытается привести этот внутренний идентификатор к известным ей типам данных. Поскольку это не ссылка, не число и не строка, механизм преобразования типов сбрасывает результат в Неопределено.

Различия между ЗНАЧЕНИЕ() и ТИП() в языке запросов

Важно не путать две разные по смыслу функции. Посмотрим на их назначение:

1. Функция ТИП()

Это легитимная функция языка запросов. Если написать ВЫБРАТЬ ТИП(Справочник.Банки), запрос вернет объект типа Тип. Это значение можно использовать для сравнения в составных полях или с оператором ССЫЛКА. Это корректный способ работы с типами в запросе.

2. Функция ЗНАЧЕНИЕ()

Эта функция предназначена исключительно для получения объектов данных (литералов). Правильный синтаксис требует обязательного уточнения:

Использование ЗНАЧЕНИЕ(Справочник.Банки) без точки — это, по сути, "синтаксическая дыра" в парсере, которая сохранилась для обратной совместимости или по недосмотру разработчиков платформы.

Почему это считается плохой практикой?

Разберем, почему использование такой конструкции опасно и бесполезно:

Как делать правильно: работа с типами и ссылками

Рассмотрим правильные подходы для решения типичных задач. Если нам нужно проверить тип значения в запросе, мы используем оператор ССЫЛКА или функцию ТИП().

Пример проверки типа поля в запросе:


ВЫБРАТЬ
    Продажи.ДокументОснование
ИЗ
    РегистрНакопления.Продажи КАК Продажи
ГДЕ
    Продажи.ДокументОснование ССЫЛКА Документ.РеализацияТоваровУслуг

Если нам нужно подставить пустую ссылку определенного типа (например, для объединения запросов с разными колонками), используем уточнение:


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

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

← На главную