Как получить итоги по колонкам (дням) и строкам в отчете "Табель учета рабочего времени" в СКД?

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

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

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

Выясняем причину: почему запрос к табличной части документа не считает итоги?

Проанализируем ситуацию, с которой столкнулся автор темы. В исходном запросе выбираются поля ПервыйЧасов1, ПервыйЧасов2 ... ПервыйЧасов31 из табличной части документа. Для получения итогов автор использует конструкцию СУММА(ПервыйЧасов1 + ПервыйЧасов2 + ...) и добавляет группировку СГРУППИРОВАТЬ ПО по всем детальным полям, включая часы и виды времени за каждый день.

Такой подход ломает логику работы СКД по нескольким причинам:

  1. Избыточная группировка в запросе. Когда мы группируем данные в СУБД по конкретным часам каждого дня, платформа физически не может свернуть строки. Если у сотрудника в один из дней было две разные специальности (например, 12 часов по одной и 12 часов по другой), строки продублируются, так как значения в группировочных полях специальностей различаются.
  2. Отсутствие полей в ресурсах СКД. СКД рассчитывает итоги (как вертикальные, так и горизонтальные) только по тем полям, которые явно добавлены на вкладку "Ресурсы". Если поле выведено в отчет просто как детальное, система отобразит его "как есть", без какого-либо суммирования.
  3. Статическая структура вместо динамической. Жесткое кодирование 31 колонки в запросе делает невозможным автоматическое построение итогов по колонкам средствами самой СКД, так как для системы это просто 31 несвязанное числовое поле, а не одно измерение "Дата" с числовым ресурсом "Часы".

Правильный подход: переход на регистр накопления "Рабочее время сотрудников"

Чтобы табель работал быстро, правильно считал итоги и автоматически подстраивался под количество дней в выбранном месяце (28, 30 или 31 день), мы должны отказаться от запроса к документу и обратиться к виртуальной таблице оборотов регистра накопления РабочееВремяСотрудников (или аналогичного регистра в вашей конфигурации).

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

Посмотрим на пример правильного запроса для схемы компоновки данных:


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

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

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

После того как запрос написан, нам необходимо объяснить системе компоновки данных, какие поля являются числовыми показателями, требующими суммирования. Для этого мы переходим на вкладку "Ресурсы" в конструкторе схемы компоновки данных.

Выполним следующие настройки:

  1. Добавим поле Часы в список ресурсов. В колонке "Выражение" укажем стандартную агрегатную функцию: СУММА(Часы).
  2. Добавим поле Дни в список ресурсов. Выражение для расчета также зададим как СУММА(Дни).

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

Проектирование структуры отчета: Кросс-таблица

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

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

  1. В корне настроек добавим элемент "Таблица".
  2. В секцию "Строки" таблицы добавим группировку по полю Сотрудник. При необходимости над сотрудником можно добавить группировку по полю Подразделение.
  3. В секцию "Колонки" таблицы добавим группировку по полю Период.
  4. Перейдем на вкладку "Выбранные поля" для всей таблицы и перетащим туда наши ресурсы: Часы и ВидВремени.

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

Форматирование дат в шапке колонок

По умолчанию в шапке колонок табеля будет выводиться полная дата со временем, например, "01.04.2018 00:00:00". Это делает таблицу слишком широкой и нечитаемой. Мы можем легко исправить это с помощью оформления.

Рассмотрим, как настроить отображение только номера дня (1, 2, 3...):

  1. Перейдем на вкладку "Наборы данных" в конструкторе СКД.
  2. Найдем в списке полей наше поле Период.
  3. В колонке "Оформление" нажмем на кнопку выбора и найдем параметр "Формат".
  4. В строке формата укажем выражение: ДФ=д (для вывода только числа дня) или ДФ=дд (для двузначного представления, например, "01", "02").

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

Решение проблемы "двойных записей" (несколько смен за один день)

Возвращаясь к проблеме автора: "допустим 2 число и там две записи так как сотрудник работал по двум специальностям в этот день. Так вот эти две записи он не суммирует".

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

  1. Если в структуре строк нашей таблицы добавлено только поле Сотрудник, а поле Специальность не выведено, то СКД автоматически сложит все часы сотрудника за этот день (например, 12 часов по одной специальности + 12 часов по другой = 24 часа в одной ячейке за 2-е число).
  2. Если же руководству важно видеть детальную аналитику по видам работ, мы можем добавить поле Специальность (или ВидРабот) внутрь группировки Сотрудник в строках таблицы. Тогда строка сотрудника развернется на две детальные строки с указанием должностей, в каждой из которых будут свои часы, а в общей строке сотрудника выведется корректный суммарный итог по дням и за месяц в целом.

Таким образом, использование регистра накопления в сочетании с гибким механизмом кросс-таблиц и ресурсов СКД позволяет полностью отказаться от громоздкого "ручного" кодирования колонок и переложить всю работу по расчету итогов на платформу 1С.

← На главную