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

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

При разработке отчетов в системе 1С:Предприятие 8 часто возникает ситуация, когда запрос возвращает слишком детальные данные, и строки не «сворачиваются» так, как ожидает пользователь. Особенно это актуально для конфигураций «Зарплата и управление персоналом» (ЗУП 3.1), «ERP» или «Комплексная автоматизация», где данные хранятся в разрезе документов-оснований и видов расчетных листков. Разберем подробно, как модифицировать запрос и настроить Систему компоновки данных (СКД), чтобы получить компактный отчет с группировкой по сотрудникам и выводом месяцев в колонки.

Анализ проблемы избыточной группировки

Рассмотрим исходную ситуацию. Программист пытается получить данные из регистра накопления НачисленияУдержанияПоСотрудникам. В запросе используются следующие поля:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    НАЧАЛОПЕРИОДА(НачисленияИУдержания.Период, МЕСЯЦ) КАК МесяцНачисления,
    НачисленияИУдержания.Организация КАК Организация,
    НачисленияИУдержания.Сотрудник КАК Сотрудник,
    НачисленияИУдержания.НачислениеУдержание КАК ВидРасчета,
    НачисленияИУдержания.ДокументОснование КАК ДокументОснование,
    СУММА(ВЫБОР
            КОГДА НачисленияИУдержания.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = ЗНАЧЕНИЕ(Перечисление.КатегорииНачисленийИНеоплаченногоВремени.ПовременнаяОплатаТруда)
                ТОГДА НачисленияИУдержания.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаОклад,
    СУММА(ВЫБОР
            КОГДА НачисленияИУдержания.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = ЗНАЧЕНИЕ(Перечисление.КатегорииНачисленийИНеоплаченногоВремени.Премия)
                ТОГДА НачисленияИУдержания.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаПремия,
    СУММА(НачисленияИУдержания.Сумма) КАК Сумма
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам КАК НачисленияИУдержания
ГДЕ
    НачисленияИУдержания.Период МЕЖДУ &НачалоПериода И &ОкончаниеПериода
    И НачисленияИУдержания.ГруппаНачисленияУдержанияВыплаты = ЗНАЧЕНИЕ(Перечисление.ГруппыНачисленияУдержанияВыплаты.Начислено)
СГРУППИРОВАТЬ ПО
    НачисленияИУдержания.Организация,
    НачисленияИУдержания.Сотрудник,
    НачисленияИУдержания.НачислениеУдержание,
    НачисленияИУдержания.ДокументОснование,
    НАЧАЛОПЕРИОДА(НачисленияИУдержания.Период, МЕСЯЦ)

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

Шаг 1. Оптимизация текста запроса

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

Исправленный вариант запроса будет выглядеть следующим образом:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    НАЧАЛОПЕРИОДА(НачисленияИУдержания.Период, МЕСЯЦ) КАК МесяцНачисления,
    НачисленияИУдержания.Организация КАК Организация,
    НачисленияИУдержания.Сотрудник КАК Сотрудник,
    СУММА(ВЫБОР
            КОГДА НачисленияИУдержания.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = ЗНАЧЕНИЕ(Перечисление.КатегорииНачисленийИНеоплаченногоВремени.ПовременнаяОплатаТруда)
                ТОГДА НачисленияИУдержания.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаОклад,
    СУММА(ВЫБОР
            КОГДА НачисленияИУдержания.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = ЗНАЧЕНИЕ(Перечисление.КатегорииНачисленийИНеоплаченногоВремени.Премия)
                ТОГДА НачисленияИУдержания.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаПремия,
    СУММА(НачисленияИУдержания.Сумма) КАК Сумма
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам КАК НачисленияИУдержания
ГДЕ
    НачисленияИУдержания.Период МЕЖДУ &НачалоПериода И &ОкончаниеПериода
    И НачисленияИУдержания.ГруппаНачисленияУдержанияВыплаты = ЗНАЧЕНИЕ(Перечисление.ГруппыНачисленияУдержанияВыплаты.Начислено)
СГРУППИРОВАТЬ ПО
    НачисленияИУдержания.Организация,
    НачисленияИУдержания.Сотрудник,
    НАЧАЛОПЕРИОДА(НачисленияИУдержания.Период, МЕСЯЦ)

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

Шаг 2. Использование виртуальных таблиц (Pro-совет)

Для повышения производительности, особенно в крупных базах ЗУП 3.1, рекомендуется использовать виртуальную таблицу Обороты вместо физической таблицы регистра. Посмотрим на пример реализации:


ВЫБРАТЬ
    НачисленияОбороты.Период КАК МесяцНачисления,
    НачисленияОбороты.Организация,
    НачисленияОбороты.Сотрудник,
    СУММА(ВЫБОР КОГДА НачисленияОбороты.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = &КатегорияОклад ТОГДА НачисленияОбороты.СуммаОборот ИНАЧЕ 0 КОНЕЦ) КАК СуммаОклад,
    СУММА(ВЫБОР КОГДА НачисленияОбороты.НачислениеУдержание.КатегорияНачисленияИлиНеоплаченногоВремени = &КатегорияПремия ТОГДА НачисленияОбороты.СуммаОборот ИНАЧЕ 0 КОНЕЦ) КАК СуммаПремия,
    СУММА(НачисленияОбороты.СуммаОборот) КАК Сумма
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам.Обороты(&НачалоПериода, &КонецПериода, Месяц, ГруппаНачисленияУдержанияВыплаты = ЗНАЧЕНИЕ(Перечисление.ГруппыНачисленияУдержанияВыплаты.Начислено)) КАК НачисленияОбороты
СГРУППИРОВАТЬ ПО
    НачисленияОбороты.Период,
    НачисленияОбороты.Организация,
    НачисленияОбороты.Сотрудник

Использование виртуальной таблицы .Обороты с периодичностью Месяц автоматически подготовит данные в нужном разрезе, а фильтрация внутри параметров виртуальной таблицы сработает быстрее, чем обычное условие ГДЕ.

Шаг 3. Настройка ресурсов в СКД

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

  1. Откройте вкладку «Ресурсы».
  2. Добавьте поля СуммаОклад, СуммаПремия и Сумма в список ресурсов.
  3. В колонке «Выражение» для каждого поля укажите СУММА(СуммаОклад), СУММА(СуммаПремия) и СУММА(Сумма) соответственно.
  4. Если в данных могут быть пустые значения, полезно использовать функцию ЕСТЬNULL(СУММА(СуммаОклад), 0).

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

Шаг 4. Настройка структуры отчета («Таблица»)

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

Рассмотрим последовательность действий:

  1. В корне настроек нажмите правой кнопкой мыши и выберите «Новая таблица».
  2. В секцию «Строки» добавьте группировку по полю Организация, а вложенную в нее — по полю Сотрудник.
  3. В секцию «Колонки» добавьте группировку по полю МесяцНачисления.
  4. Перейдите на вкладку «Выбранные поля» для всей таблицы и добавьте туда наши ресурсы: СуммаОклад, СуммаПремия, Сумма.

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

Важные нюансы учета в ЗУП 3.1

Проанализируем специфику работы с регистром НачисленияУдержанияПоСотрудникам, о которой часто забывают разработчики:

1. Период регистрации vs Период действия. Поле Период в физической таблице этого регистра — это дата записи (часто дата документа). Если вы хотите построить отчет по «Месяцам начисления» (как в расчетном листке), правильнее использовать измерение ПериодРегистрации. Оно всегда кратно первому числу месяца. Если использовать Период, то начисления одного месяца могут попасть в разные дни, и функция НАЧАЛОПЕРИОДА обязательна.

2. Идентификация сотрудников. Помните, что один и тот же человек может быть уволен и принят вновь. В этом случае у него будет две разные карточки в справочнике Сотрудники. Если ваша задача — объединить все его доходы в одну строку, группируйте не по Сотруднику, а по Сотрудник.ФизическоеЛицо.

3. Группы начислений. Фильтр по ГруппыНачисленияУдержанияВыплаты.Начислено отсекает выплаты и удержания, но не забывайте, что внутри могут быть сторно-записи. Агрегатная функция СУММА корректно обработает отрицательные значения сторно, если они есть в периоде отчета.

Резюме

Чтобы исправить запрос и получить корректную группировку, мы проделали следующую работу:

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

← На главную