Как вывести значения из строк табличной части в отдельные колонки одной строки динамического списка?

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

При разработке интерфейсов на платформе 1С:Предприятие 8.3 часто возникает задача отображения данных из табличных частей документов непосредственно в списке (форме списка). Типичный пример: в документе есть табличная часть «Параметры», где хранятся записи в формате «Ключ — Значение» (например, «Марка — Audi», «Модель — A3»). Если просто выбрать эти данные в запросе динамического списка, система выведет несколько строк для одного документа, что делает список нечитаемым.

В этой статье мы подробно разберем, как «развернуть» (транспонировать) строки табличной части в колонки, чтобы в динамическом списке была одна строка на один документ с заполненными реквизитами в разных столбцах.

Анализ проблемы: почему стандартный запрос не подходит

Рассмотрим ситуацию, которую описал автор вопроса. При использовании конструкции ВЫБОР КОГДА в простом запросе к табличной части, система перебирает каждую строку ТЧ по отдельности. Если в документе две строки (Марка и Модель), то запрос сформирует две записи. В первой записи будет заполнена только «Марка», а «Модель» будет пустой строкой. Во второй — наоборот. В результате в динамическом списке один и тот же документ продублируется столько раз, сколько строк в его табличной части.

Для решения этой задачи нам необходимо объединить эти данные «по горизонтали». Проанализируем три основных способа реализации.

Способ 1: Использование нескольких левых соединений (Рекомендуемый)

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

Рассмотрим по шагам, как составить такой запрос:

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

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


ВЫБРАТЬ
    ЗапросКотировок.Ссылка КАК Ссылка,
    ЗапросКотировок.Дата КАК Дата,
    ЗапросКотировок.Номер КАК Номер,
    ЕСТЬNULL(ТЧ_Марка.Значение, "") КАК Марка,
    ЕСТЬNULL(ТЧ_Модель.Значение, "") КАК Модель
ИЗ
    Документ.ЗапросКотировок КАК ЗапросКотировок
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗапросКотировок.ПараметрыЗапросаКотировок КАК ТЧ_Марка
        ПО ЗапросКотировок.Ссылка = ТЧ_Марка.Ссылка
            И ТЧ_Марка.Идентификатор = "Марка"
        
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗапросКотировок.ПараметрыЗапросаКотировок КАК ТЧ_Модель
        ПО ЗапросКотировок.Ссылка = ТЧ_Модель.Ссылка
            И ТЧ_Модель.Идентификатор = "Модель"

Важный момент: Мы используем ЕСТЬNULL, чтобы в случае отсутствия записи в табличной части в списке отображалась пустая строка, а не системное значение NULL, которое может мешать поиску и сортировке.

Способ 2: Агрегация данных с группировкой

Проанализируем ситуацию, когда параметров много и плодить десятки соединений не хочется. В этом случае можно использовать механизм СГРУППИРОВАТЬ ПО и агрегатную функцию МАКСИМУМ. Этот метод позволяет «схлопнуть» несколько строк в одну.

Разберем логику работы такого запроса:


ВЫБРАТЬ
    ЗапросКотировок.Ссылка КАК Ссылка,
    МАКСИМУМ(ВЫБОР
            КОГДА ТЧ.Идентификатор = "Марка"
                ТОГДА ТЧ.Значение
            ИНАЧЕ ""
        КОНЕЦ) КАК Марка,
    МАКСИМУМ(ВЫБОР
            КОГДА ТЧ.Идентификатор = "Модель"
                ТОГДА ТЧ.Значение
            ИНАЧЕ ""
        КОНЕЦ) КАК Модель
ИЗ
    Документ.ЗапросКотировок КАК ЗапросКотировок
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗапросКотировок.ПараметрыЗапросаКотировок КАК ТЧ
        ПО ЗапросКотировок.Ссылка = ТЧ.Ссылка
ГДЕ
    ТЧ.Идентификатор В ("Марка", "Модель")
СГРУППИРОВАТЬ ПО
    ЗапросКотировок.Ссылка

Выясним причину использования МАКСИМУМ: так как для каждой строки ТЧ все поля ВЫБОР, кроме одного, будут пустыми, функция МАКСИМУМ выберет именно то единственное заполненное значение для каждой колонки и объединит их в рамках одной строки по ссылке документа.

Способ 3: Использование механизма Характеристик

Если ваша конфигурация использует План видов характеристик (ПВХ) для определения параметров, то 1С предоставляет встроенный инструмент. В настройках динамического списка на вкладке «Характеристики» можно указать источник данных для дополнительных реквизитов.

Преимущества этого подхода:

Производительность и ограничения

Нужно учитывать, что динамический список выполняет запрос при каждом скроллинге или поиске. Проанализируем возможные проблемы при работе с большими объемами данных:

  1. Количество соединений: Если у вас 20-30 параметров, использование 20-30 ЛЕВОЕ СОЕДИНЕНИЕ может значительно замедлить открытие формы списка.
  2. Индексация: Поля Идентификатор и Ссылка в табличной части должны быть индексированы, иначе СУБД будет выполнять полное сканирование таблицы.
  3. Альтернатива (Регистр сведений): Если список начинает «тормозить», профессиональным решением будет создание вспомогательного Регистра сведений. При проведении документа данные из ТЧ записываются в «плоскую» структуру регистра. В динамическом списке вы просто делаете одно соединение с этим регистром, что работает на порядок быстрее.

Таким образом, для простых задач идеально подходит Способ 1 с левыми соединениями. Он нагляден, легко отлаживается и позволяет быстро получить требуемый результат в одной строке динамического списка.

← На главную