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

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

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с особенностью настройки типа Таблица. В такой структуре на пересечении строк и колонок могут находиться только поля, определенные как Ресурсы. По своей природе ресурсы обязаны агрегироваться (суммироваться, выбираться по максимуму или минимуму), что приводит к «схлопыванию» данных. Например, если у одного сотрудника за один день есть несколько записей о приходе и уходе, СКД выведет только одну строку с максимальным или минимальным значением, игнорируя остальные записи.

В этой статье мы подробно разберем, как обмануть этот механизм и заставить СКД выводить все детальные записи внутри таблицы, сохраняя структуру «Пользователь — Дата».

Почему ресурсы всегда группируются

Рассмотрим механику работы СКД. Когда мы выбираем тип настройки Таблица, система строит кросс-отчет. Ячейка на пересечении конкретной строки и конкретной колонки должна содержать итоговый результат. Если в исходных данных для этого пересечения есть три записи, СКД не «знает», как разместить их в одной ячейке, поэтому она применяет функцию агрегации, указанную на вкладке Ресурсы (например, Максимум(ВремяПрихода)).

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

Способ 1: Нумерация строк в запросе

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

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


ВЫБРАТЬ
    ТаблицаДанных.Пользователь КАК Пользователь,
    ТаблицаДанных.Подразделение КАК Подразделение,
    ТаблицаДанных.Дата КАК Дата,
    ТаблицаДанных.ВремяПрихода КАК ВремяПрихода,
    ТаблицаДанных.ВремяУхода КАК ВремяУхода
ПОМЕСТИТЬ ВТ_ТаблицаДанных
ИЗ
    &ТаблицаДанных КАК ТаблицаДанных;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_ТаблицаДанных.Пользователь,
    ВТ_ТаблицаДанных.Подразделение,
    ВТ_ТаблицаДанных.Дата,
    ВТ_ТаблицаДанных.ВремяПрихода,
    ВТ_ТаблицаДанных.ВремяУхода,
    КОЛИЧЕСТВО(ВТ_ТаблицаДанных1.ВремяПрихода) КАК НомерСтроки
ИЗ
    ВТ_ТаблицаДанных КАК ВТ_ТаблицаДанных
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ТаблицаДанных КАК ВТ_ТаблицаДанных1
        ПО ВТ_ТаблицаДанных.Пользователь = ВТ_ТаблицаДанных1.Пользователь
            И ВТ_ТаблицаДанных.Подразделение = ВТ_ТаблицаДанных1.Подразделение
            И ВТ_ТаблицаДанных.Дата = ВТ_ТаблицаДанных1.Дата
            И ВТ_ТаблицаДанных.ВремяПрихода >= ВТ_ТаблицаДанных1.ВремяПрихода
СГРУППИРОВАТЬ ПО
    ВТ_ТаблицаДанных.Пользователь,
    ВТ_ТаблицаДанных.Подразделение,
    ВТ_ТаблицаДанных.Дата,
    ВТ_ТаблицаДанных.ВремяПрихода,
    ВТ_ТаблицаДанных.ВремяУхода

В данном коде мы создаем поле НомерСтроки. Для каждой записи о времени прихода мы считаем, сколько записей было до нее (включая текущую). Таким образом, для одного пользователя и одной даты мы получим строки с номерами 1, 2, 3 и так далее.

Настройка структуры отчета в СКД

Теперь выясним, как правильно настроить саму схему компоновки, чтобы воспользоваться полученным номером строки:

  1. Перейдем на вкладку Настройки и выберем нашу таблицу.
  2. В иерархии Строки таблицы добавим основную группировку по полю Пользователь.
  3. Внутри группировки Пользователь добавим подчиненную группировку по полю НомерСтроки.
  4. В иерархии Колонки таблицы добавим группировку по полю Дата.
  5. На вкладке Выбранные поля для всей таблицы укажем наши ресурсы: ВремяПрихода и ВремяУхода.

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

Способ 2: Использование функции АВТОНОМЕРЗАПИСИ()

Если ваша база данных работает на платформе 8.3.20 и выше, или вы используете запросы к СУБД, поддерживающим оконные функции, можно упростить получение уникального номера. Рассмотрим вариант с использованием функции АВТОНОМЕРЗАПИСИ(), которая появилась в языке запросов СКД.

Мы можем добавить в запрос поле:

АВТОНОМЕРЗАПИСИ() КАК ПорядковыйНомер

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

Разбор типичной ошибки: «Лесенка» в отчете

Проанализируем ситуацию, когда данные начинают выводиться «лесенкой» (каждое новое значение в новой колонке со смещением вниз). Это происходит, если поле НомерСтроки или ВремяПрихода ошибочно добавлено в группировку Колонок.

Запомните правило: В колонках должна быть только Дата. Все, что отвечает за уникальность строки (Пользователь, Номер строки, Регистратор), должно находиться только в Группировке строк.

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

Способ 3: Детальные записи внутри таблицы

Малоизвестный, но эффективный метод — использование группировки Детальные записи прямо внутри структуры таблицы. Рассмотрим, как это сделать:

  1. В структуре настройки Таблица в разделе Строки создайте новую группировку.
  2. В поле группировки ничего не выбирайте — система автоматически предложит вариант <Детальные записи>.
  3. Убедитесь, что поля ВремяПрихода и ВремяУхода добавлены в Ресурсы на соответствующей вкладке схемы.

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

Резюме

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

← На главную