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

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

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

Постановка задачи и анализ логики

Разберем ситуацию на примере: если сотруднику исполняется 20 лет в декабре, то в колонках отчета с января по ноябрь он должен учитываться в группе "до 20 лет", а в колонке декабря — уже в группе "от 20 до 30 лет". Если мы будем рассчитывать возраст просто на дату окончания периода отчета, мы получим статичную картину, которая не отражает реальное состояние дел в прошлых месяцах.

Для решения этой задачи нам необходимо выполнить три основных условия:

  1. Сформировать временную шкалу (таблицу всех месяцев внутри выбранного периода).
  2. Соединить список сотрудников с каждым месяцем этой шкалы.
  3. Рассчитать возраст сотрудника именно на дату окончания каждого конкретного месяца.

Шаг 1: Генерация временной шкалы (Таблица периодов)

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

Пример запроса для получения месяцев периода:


ВЫБРАТЬ
    ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, Цифры.Номер) КАК МесяцПериода,
    КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, Цифры.Номер), МЕСЯЦ) КАК КонецМесяца
ПОМЕСТИТЬ ВТ_Периоды
ИЗ
    (ВЫБРАТЬ 0 КАК Номер ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2 
     ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 5 
     ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 8 
     ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 9 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 10 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 11) КАК Цифры
ГДЕ
    ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, Цифры.Номер) <= &ДатаОкончания
;

Шаг 2: Расчет возраста на каждую контрольную точку

Проанализируем формулу расчета возраста. Использование конструкции ГОД(Дата1) - ГОД(Дата2) часто дает ошибку, так как не учитывает, наступил ли уже день рождения в текущем году. Рассмотрим более точную формулу, которую мы применим в соединении с нашей таблицей периодов.

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


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

Шаг 3: Классификация по возрастным группам

Выясним причину, почему жесткое прописывание условий ВЫБОР КОГДА непосредственно в запросе может быть неудобным. Если требования к интервалам изменятся (например, группа "от 20 до 30" превратится в "от 18 до 25"), придется переписывать весь запрос. Однако для простого отчета воспользуемся классической схемой группировки:


ВЫБРАТЬ
    Данные.ПериодМесяц,
    Данные.Сотрудник,
    ВЫБОР
        КОГДА Данные.ВозрастНаКонецМесяца < 20 ТОГДА "Менее 20 лет"
        КОГДА Данные.ВозрастНаКонецМесяца МЕЖДУ 20 И 30 ТОГДА "От 20 до 30 лет"
        КОГДА Данные.ВозрастНаКонецМесяца МЕЖДУ 31 И 40 ТОГДА "От 31 до 40 лет"
        КОГДА Данные.ВозрастНаКонецМесяца МЕЖДУ 41 И 50 ТОГДА "От 41 до 50 лет"
        ИНАЧЕ "Свыше 50 лет"
    КОНЕЦ КАК ВозрастнаяГруппа
ИЗ
    ВТ_СотрудникиСВозрастом КАК Данные

Шаг 4: Настройка СКД для вывода кросс-таблицы

Чтобы отчет выглядел наглядно (в строках — группы, в колонках — месяцы), выполним следующие настройки в схеме компоновки данных:

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

Важные замечания по кадровому учету

Рассмотрим подробнее нюанс, связанный с актуальностью данных. В реальных базах данных (например, 1С:ЗУП) недостаточно просто выбрать сотрудников из справочника. Необходимо учитывать:

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

← На главную