Как настроить вывод объединенного списка значений в ячейке группировки таблицы СКД?

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

При работе с Системой Компоновки Данных (СКД) в 1С часто возникает задача, когда необходимо вывести в отчете агрегированные данные, причем не в отдельной колонке, а непосредственно в ячейке группировки, рядом с основным полем группировки. Особенно это актуально, когда требуется собрать список связанных значений (например, наименований документов) и отобразить их через разделитель в одной строке с элементом основной группировки. Давайте рассмотрим подробнее, как решить эту задачу, используя стандартные возможности СКД.

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

Исходные данные, которые мы получаем из запроса, выглядят примерно так:


Номенклатура | Поступление              | Год поступления | Цена из поступления
Ном 1         | Поступление 12 от 2020 | 2020            | 100
Ном 1         | Поступление 34 от 2021 | 2021            | 150
Ном 2         | Поступление 56 от 2020 | 2020            | 200
Ном 2         | Поступление 78 от 2021 | 2021            | 180

Целевой вид отчета, к которому мы стремимся:


Номенклатура | Поступление                                 | 2020 | 2021
Ном 1         | Поступление 12 от 2020; Поступление 34 от 2021 | 100  | 150
Ном 2         | Поступление 56 от 2020; Поступление 78 от 2021 | 200  | 180

Мы видим, что в целевом отчете для каждой номенклатуры в одной ячейке объединены её наименование и список всех связанных поступлений, а затем идут колонки с ценами по годам. Мы разберем по шагам, как добиться такого результата в СКД.

Шаг 1: Подготовка набора данных в запросе СКД

Прежде всего, нам необходимо убедиться, что наш запрос СКД возвращает все необходимые поля. В нашем случае это:

  1. Номенклатура
  2. Поступление (представление документа поступления, например, "Поступление 12 от 2020")
  3. ГодПоступления (или просто Год, извлеченный из даты поступления)
  4. Цена

Запрос может выглядеть примерно так:


ВЫБРАТЬ
    ТаблицаПоступлений.Номенклатура КАК Номенклатура,
    ТаблицаПоступлений.Поступление.Представление КАК Поступление,
    ГОД(ТаблицаПоступлений.ДатаПоступления) КАК ГодПоступления,
    ТаблицаПоступлений.Цена КАК Цена
ИЗ
    РегистрНакопления.ПоступленияТоваров.Обороты КАК ТаблицаПоступлений

Убедитесь, что в списке доступных полей на вкладке "Наборы данных" присутствуют все эти поля.

Шаг 2: Определение ресурса для агрегации поступлений

Ключевым моментом для сбора нескольких значений в одну ячейку является использование ресурсов СКД. Мы создадим новый ресурс, который будет собирать все представления документов поступления для каждой номенклатуры.

  1. Перейдите на вкладку "Ресурсы" в настройках схемы компоновки данных.
  2. Добавьте новый ресурс. Назовем его, например, СписокПоступлений.
  3. В качестве Выражения для этого ресурса укажите Массив(Поступление).
  4. КРИТИЧНО ВАЖНО: Укажите Выражение группировки для этого ресурса. В нашем случае, это будет Номенклатура. Это означает, что массив поступлений будет собираться для каждого уникального значения поля Номенклатура.

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

Альтернативный вариант, если детализация не требуется, и вы хотите полностью контролировать разделитель, это использовать функцию СоединитьСтроки():

СоединитьСтроки(Массив(Поступление), "; ")

Это выражение сразу вернет строку с поступлениями, разделенными точкой с запятой. Однако в нашем примере мы остановимся на Массив(Поступление), так как это дает больше гибкости и соответствует опыту автора темы. Наглядные практические отчеты с этими функциями можно изучить в примерах использования функций СКД Массив и СоединитьСтроки.

Шаг 3: Настройка структуры отчета СКД

Теперь, когда у нас есть необходимый ресурс, приступим к построению структуры отчета:

  1. Перейдите на вкладку "Настройки".
  2. Добавьте новую таблицу.
  3. В разделе "Строки" добавьте новую группировку по полю Номенклатура.
  4. В разделе "Колонки" добавьте группировку по полю ГодПоступления.
  5. В разделе "Выбранные поля" для таблицы, в секции ресурсов, добавьте поле Цена.

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

Шаг 4: Включение агрегированного списка поступлений в группировку строк

Чтобы ресурс СписокПоступлений появился рядом с Номенклатурой в строке группировки, необходимо добавить его в "Выбранные поля" для самой группировки Номенклатура. Это может показаться нелогичным, так как ресурс обычно ассоциируется с ячейками данных, но СКД позволяет выводить ресурсы и в заголовках группировок.

  1. Выделите группировку Номенклатура в разделе "Строки".
  2. Перейдите на вкладку "Выбранные поля" для этой конкретной группировки (не для всей таблицы).
  3. Добавьте в список выбранных полей:
    • Номенклатура
    • СписокПоступлений (наш только что созданный ресурс)

Важный нюанс: После этих действий, если вы сформируете отчет, вы, скорее всего, увидите, что Номенклатура и СписокПоступлений отображаются в разных колонках в рамках заголовка группировки по строкам. Это не то, что нам нужно. СКД по умолчанию стремится размещать каждое поле в своей колонке. Для того чтобы они оказались в одной ячейке, нам потребуется настроить пользовательский макет.

Шаг 5: Создание пользовательского макета для группировки

Чтобы объединить несколько полей в одной ячейке заголовка группировки, мы должны использовать функциональность пользовательских макетов СКД. Это позволяет нам полностью контролировать внешний вид заголовков и подвалов группировок. Практический порядок создания таких настроек показан в примере использования собственных макетов в СКД.

  1. Перейдите на вкладку "Макеты" в настройках схемы компоновки данных.
  2. Нажмите кнопку "Добавить макет" или "Добавить макет группировки".
  3. В появившемся окне укажите:
    • Область использования: Выберите "Заголовок группировки"
    • Группировка: Выберите Номенклатура
    Нажмите "ОК". Откроется конструктор макета, похожий на табличный документ.
  4. В конструкторе макета:
    • Создайте одну ячейку (например, выделите ячейку А1).
    • В свойствах этой ячейки в разделе "Заполнение" выберите "Шаблон".
    • В качестве Текста шаблона укажите комбинацию полей и текста. Например: [Номенклатура] ([СписокПоступлений])

      Здесь [Номенклатура] и [СписокПоступлений] – это ссылки на поля. СКД автоматически подставит значения этих полей в шаблон. Круглые скобки и пробел между ними – это обычный текст, который будет отображаться.

    • Убедитесь, что Тип параметра для Номенклатура и СписокПоступлений установлен как "Поле".
  5. После настройки шаблона макета закройте конструктор.

Теперь, когда вы сформируете отчет, СКД будет использовать этот пользовательский макет для отображения заголовка группировки Номенклатура. В одной ячейке вы увидите наименование номенклатуры и через пробел список всех поступлений, собранных в массив, который СКД автоматически преобразует в строку для вывода.

Шаг 6: Дополнительные возможности и нюансы

Мы выяснили, что основной подход заключается в создании ресурса типа Массив() и его выводе через пользовательский макет группировки. Давайте проанализируем некоторые важные аспекты и дополнительные возможности:

  1. Детализация (Drill-down):

    Использование Массив(Поступление) как выражения ресурса не только позволяет отобразить объединенную строку, но и сохраняет ссылку на исходные данные. Как было отмечено в исходной теме, это дает возможность по правой кнопке мыши на ячейке с объединенными поступлениями открыть список значений и, при наличии соответствующих настроек, перейти к просмотру конкретного документа поступления. Это очень мощная функция, которая значительно повышает интерактивность отчета.

    Для корректной работы детализации убедитесь, что поле Поступление в вашем запросе является ссылочным типом данных (например, ДокументСсылка.ПоступлениеТоваровУслуг). СКД автоматически свяжет эти ссылки с возможностью их открытия.

  2. Настройка внешнего вида:

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

    Если вам нужно изменить разделитель по умолчанию для массива (который обычно является запятой с пробелом), вы можете использовать функцию СоединитьСтроки(Массив(Поступление), "; ") вместо просто Массив(Поступление). Это даст вам точный контроль над тем, как элементы массива будут объединены в строку.

  3. Обработка пустых значений:

    Если для какой-то номенклатуры поступлений не будет, Массив() вернет пустой массив. При выводе в шаблоне ([СписокПоступлений]) это может привести к выводу пустых скобок. Если это нежелательно, вы можете использовать более сложное выражение в шаблоне макета, или, что чаще, изменить само выражение ресурса:

    
    ВЫБОР КОГДА ЕСТЬNULL(Количество(Поступление), 0) > 0 ТОГДА СоединитьСтроки(Массив(Поступление), "; ") ИНАЧЕ "" КОНЕЦ
    

    Такое выражение ресурса будет возвращать пустую строку, если поступлений нет, что предотвратит вывод пустых скобок в отчете.

  4. Альтернативные подходы с вычисляемыми полями в запросе:

    В некоторых случаях, если функционал Массив() или СоединитьСтроки(Массив()) в СКД не подходит или вызывает сложности с производительностью на очень больших объемах данных, можно агрегировать строки непосредственно в запросе. Для этого используются специфичные для СУБД функции. Например, в PostgreSQL это STRING_AGG(), в MS SQL Server STRING_AGG() или FOR XML PATH(''), в Oracle LISTAGG().

    Пример для SQL Server (псевдокод, может отличаться от синтаксиса 1С):

    
    ВЫБРАТЬ
        Номенклатура,
        (
            ВЫБРАТЬ STRING_AGG(Поступление.Представление, '; ')
            ИЗ ТаблицаПоступлений AS Внутренняя
            ГДЕ Внутренняя.Номенклатура = Основная.Номенклатура
        ) КАК СписокПоступлений,
        ГодПоступления,
        Цена
    ИЗ
        РегистрНакопления.ПоступленияТоваров.Обороты КАК Основная
    

    Однако такой подход сложнее в реализации через конструктор запросов 1С и часто требует программного формирования текста запроса. Кроме того, он лишает возможности детализации, которую дает ресурс Массив() в СКД. Поэтому, для большинства задач, решение через ресурсы и макеты СКД является предпочтительным.

Заключение

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

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

← На главную