Как в запросе 1С получить значение дополнительного реквизита и почему возникает ошибка "Отсутствует отображение для типа ValueTable"?

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

При работе с языком запросов 1С многие разработчики сталкиваются с ситуацией, когда нужно получить данные, хранящиеся в табличной части другого объекта. Например, получить значение дополнительного реквизита из справочника "Характеристики номенклатуры", на который есть ссылка в документе "Реализация товаров и услуг". Интуитивно кажется, что это можно сделать "через точку", но такой подход приводит к ошибке. Давайте разберемся, почему так происходит и как правильно составить запрос.

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


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Ссылка КАК Ссылка,
    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
    // Следующая строка вызывает ошибку
    РеализацияТоваровУслугТовары.Характеристика.Ссылка.ДополнительныеРеквизиты.Значение КАК Характеристика,
    РеализацияТоваровУслугТовары.Цена КАК Цена,
    РеализацияТоваровУслугТовары.Количество КАК Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары

При выполнении такого запроса, например, в консоли запросов или в СКД, система выдает ошибку:

Ошибка отображения типов: Отсутствует отображение для типа '{http://v8.1c.ru/8.1/data/core}ValueTable'

Проанализируем, в чем корень проблемы и как ее исправить.

Причина ошибки: что такое ValueTable и почему ее нельзя отобразить

Ключевая часть сообщения об ошибке — упоминание типа ValueTable. В терминах объектов 1С это ТаблицаЗначений. Ошибка возникает потому, что наша некорректная конструкция в запросе пытается сделать невозможное: получить целую таблицу данных и поместить ее в одну-единственную ячейку в результирующей выборке.

Конструкция РеализацияТоваровУслугТовары.Характеристика.Ссылка.ДополнительныеРеквизиты обращается к табличной части ДополнительныеРеквизиты справочника-характеристики. Эта табличная часть содержит множество строк, каждая из которых описывает отдельный дополнительный реквизит (например, "Цвет", "Размер", "Материал") и его значение.

Когда мы добавляем .Значение, мы не даем системе понять, из какой именно строки табличной части ДополнительныеРеквизиты нужно взять это значение. Система не может сделать выбор за нас и пытается вернуть всю таблицу целиком. А результат запроса не может содержать в одной ячейке объект "ТаблицаЗначений". Особенно остро это проявляется в управляемых формах при передаче данных между сервером и клиентом, где такой тип данных не может быть напрямую сериализован (преобразован для передачи), что и вызывает вторичную ошибку преобразования данных XDTO.

Важно запомнить: в языке запросов 1С нельзя обращаться к реквизитам табличной части другого объекта "через точку". Для извлечения данных из связанных таблиц предназначен специальный механизм — соединения (JOIN).

Правильное решение: используем ЛЕВОЕ СОЕДИНЕНИЕ

Чтобы корректно получить значение конкретного дополнительного реквизита, необходимо "подключить" нужную нам таблицу (в данном случае Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты) к нашему основному запросу и указать условия связи.

Разберем построение правильного запроса по шагам:

  1. Оставляем основную таблицу. Наш источник данных — Документ.РеализацияТоваровУслуг.Товары.
  2. Добавляем соединяемую таблицу. Мы хотим получить данные из дополнительных реквизитов характеристик. Для этого используем ЛЕВОЕ СОЕДИНЕНИЕ с таблицей Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты. Мы используем именно ЛЕВОЕ соединение, чтобы в результат попали все строки из документа реализации, даже те, у которых нужный дополнительный реквизит у характеристики не заполнен.
  3. Указываем условие связи. Связь между таблицами устанавливается по полю Характеристика. В таблице документа это ссылка на элемент справочника характеристик. В табличной части доп. реквизитов поле Ссылка указывает на владельца этих реквизитов, то есть на тот же самый элемент справочника. Условие связи будет: ПО РеализацияТоваровУслугТовары.Характеристика = ХарактеристикиДопРеквизиты.Ссылка.
  4. Фильтруем по нужному свойству. Это самый важный шаг. Таблица ДополнительныеРеквизиты содержит строки для всех реквизитов. Нам же нужен только один конкретный (например, "Цвет"). Для этого нужно добавить еще одно условие, которое отфильтрует строки по нужному свойству. За это отвечает поле Свойство, которое ссылается на элемент из ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения. Это условие добавляется через оператор И.

Соберем все вместе. Итоговый запрос будет выглядеть так:


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Ссылка,
    РеализацияТоваровУслугТовары.Номенклатура,
    РеализацияТоваровУслугТовары.Цена,
    РеализацияТоваровУслугТовары.Количество,
    ХарактеристикиДопРеквизиты.Значение КАК ЗначениеРеквизитаЦвет
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ХарактеристикиДопРеквизиты
        ПО РеализацияТоваровУслугТовары.Характеристика = ХарактеристикиДопРеквизиты.Ссылка
        И ХарактеристикиДопРеквизиты.Свойство = &НужноеСвойство

В этом запросе &НужноеСвойство — это параметр. Перед выполнением запроса вы должны передать в него ссылку на элемент плана видов характеристик, который соответствует нужному вам реквизиту (например, ПВХ.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Цвет")).

Как получить значения нескольких дополнительных реквизитов?

Часто возникает задача получить не один, а сразу несколько дополнительных реквизитов (например, и "Цвет", и "Размер"). Сделать это можно, соединив таблицу с дополнительными реквизитами несколько раз — по одному разу для каждого нужного реквизита, используя разные псевдонимы.

Посмотрим на пример. Нам нужно получить "Цвет" и "Размер".


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Ссылка,
    РеализацияТоваровУслугТовары.Номенклатура,
    ДопРеквизитЦвет.Значение КАК Цвет,
    ДопРеквизитРазмер.Значение КАК Размер
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
        // Первое соединение для получения Цвета
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ДопРеквизитЦвет
        ПО РеализацияТоваровУслугТовары.Характеристика = ДопРеквизитЦвет.Ссылка
        И ДопРеквизитЦвет.Свойство = &СвойствоЦвет
        
        // Второе соединение для получения Размера
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ДопРеквизитРазмер
        ПО РеализацияТоваровУслугТовары.Характеристика = ДопРеквизитРазмер.Ссылка
        И ДопРеквизитРазмер.Свойство = &СвойствоРазмер

В этом запросе мы используем два параметра: &СвойствоЦвет и &СвойствоРазмер. Каждое соединение работает независимо и "прикрепляет" к строке реализации значение своего реквизита. Этот подход прост и понятен, но если реквизитов очень много, запрос может стать громоздким и медленным.

Подведем итог: ошибка "Отсутствует отображение для типа ValueTable" — это сигнал о том, что вы пытаетесь получить целую таблицу в качестве одного значения. Правильный и производительный способ получения данных из связанных табличных частей — это использование СОЕДИНЕНИЙ в запросе с четким указанием условий связи и фильтрации.

← На главную