Как получить стаж сотрудника в днях, месяцах и годах в ЗУП 3.1 с помощью запроса

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

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

Способ 1. Прямой расчет в запросе через разность дат

Этот метод подходит, если вам нужно быстро получить данные в простом отчете или обработке, не углубляясь в сложные механизмы конфигурации. Основным источником данных служит регистр сведений СтажиФизическихЛиц. Мы будем использовать виртуальную таблицу СрезПоследних, чтобы получить актуальные настройки стажа для каждого сотрудника.

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


ВЫБРАТЬ
    СтажиФизическихЛицСрезПоследних.ФизическоеЛицо КАК ФизическоеЛицо,
    СтажиФизическихЛицСрезПоследних.ВидСтажа КАК ВидСтажа,
    СтажиФизическихЛицСрезПоследних.ДатаОтсчета КАК ДатаОтсчета,
    СтажиФизическихЛицСрезПоследних.РазмерМесяцев + РАЗНОСТЬДАТ(СтажиФизическихЛицСрезПоследних.ДатаОтсчета, ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, СтажиФизическихЛицСрезПоследних.РазмерДней), МЕСЯЦ) КАК ИтогоМесяцев,
    СтажиФизическихЛицСрезПоследних.РазмерДней - РАЗНОСТЬДАТ(&ТекущаяДата, ДОБАВИТЬКДАТЕ(СтажиФизическихЛицСрезПоследних.ДатаОтсчета, МЕСЯЦ, РАЗНОСТЬДАТ(СтажиФизическихЛицСрезПоследних.ДатаОтсчета, ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, СтажиФизическихЛицСрезПоследних.РазмерДней), МЕСЯЦ)), ДЕНЬ) КАК ИтогоДней
ИЗ
    РегистрСведений.СтажиФизическихЛиц.СрезПоследних(&ТекущаяДата, ) КАК СтажиФизическихЛицСрезПоследних

Важные пояснения к алгоритму:

  1. Функция РАЗНОСТЬДАТ с параметром МЕСЯЦ вычисляет количество полных календарных месяцев.
  2. Мы используем ДОБАВИТЬКДАТЕ, чтобы учесть те дни, которые уже были накоплены на дату начала отсчета.
  3. Этот запрос возвращает «общие» месяцы. Чтобы перевести их в формат «Лет и Месяцев», потребуется дополнительная обработка (либо в самом запросе, либо в коде 1С).

Способ 2. Получение лет, месяцев и дней в программном коде

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   СтажиФизическихЛицСрезПоследних.ВидСтажа КАК ВидСтажа,
    |   СтажиФизическихЛицСрезПоследних.РазмерМесяцев + РАЗНОСТЬДАТ(СтажиФизическихЛицСрезПоследних.ДатаОтсчета, &ТекущаяДата, МЕСЯЦ) КАК ИтогоМесяцев,
    |   СтажиФизическихЛицСрезПоследних.РазмерДней КАК ИтогоДней
    |ИЗ
    |   РегистрСведений.СтажиФизическихЛиц.СрезПоследних(&ТекущаяДата, ФизическоеЛицо = &ФизическоеЛицо) КАК СтажиФизическихЛицСрезПоследних";

Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
Запрос.УстановитьПараметр("ФизическоеЛицо", ФизЛицо);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    КоличЛет = Цел(Выборка.ИтогоМесяцев / 12);
    КоличМесяцев = Выборка.ИтогоМесяцев % 12;
    КоличДней = Выборка.ИтогоДней; 
    
    // Теперь переменные КоличЛет, КоличМесяцев и КоличДней можно выводить в отчет
КонецЦикла;

В данном примере мы используем функцию Цел() для получения целого количества лет и оператор остатка от деления % (или математическое вычитание ИтогоМесяцев - (Лет * 12)) для получения остатка месяцев.

Способ 3. Профессиональный подход: Использование механизмов представлений ЗУП 3.1

Для тех, кто хочет получить данные максимально точно (с учетом всех особенностей календаря и правил округления, принятых в ЗУП), рекомендуется использовать механизм представлений. В ЗУП 3.1 многие сложные отчеты строятся на динамической подмене текста запроса. Если вы создаете отчет на Системе компоновки данных (СКД), вы можете использовать таблицу Представления_СтажиСотрудников. Для тестирования и отладки таких запросов подойдет консоль запросов с поддержкой исполняемых представлений ЗУП.

Как это работает:

  1. В схеме компоновки данных вы описываете запрос к несуществующей в базе данных таблице Представления_СтажиСотрудников.
  2. При выполнении отчета программный интерфейс ЗУП перехватывает этот запрос и заменяет имя таблицы на огромный, тщательно выверенный код (подобный тому, что приведен в сообщении №12 обсуждения).
  3. Этот механизм автоматически учитывает данные из регистров СтажиФизическихЛиц и НакопленныеСтажиФизическихЛиц.

Рассмотрим фрагмент логики, которую использует система для вычисления лет внутри этого сложного механизма:


ВЫБОР 
    КОГДА (ВЫРАЗИТЬ(Таблица.СтажМесяцев / 12 КАК ЧИСЛО(3, 0))) * 12 > Таблица.СтажМесяцев 
        ТОГДА (ВЫРАЗИТЬ(Таблица.СтажМесяцев / 12 КАК ЧИСЛО(3, 0))) - 1 
    ИНАЧЕ ВЫРАЗИТЬ(Таблица.СтажМесяцев / 12 КАК ЧИСЛО(3, 0)) 
КОНЕЦ КАК Лет

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

Рекомендации по выбору метода

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

Если вам нужен простой список в консоли запросов: используйте Способ 1. Это быстро и наглядно, хотя может давать погрешность в 1-2 дня из-за разницы в количестве дней в разных месяцах года.

Если вы пишете внешнюю обработку: используйте Способ 2. Программная обработка данных после запроса всегда надежнее и легче в отладке.

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

Помните, что в ЗУП 3.1 расчет стажа привязан к правилу: 30 дней = 1 месяц и 12 месяцев = 1 год при суммировании «рваных» периодов. Если же стаж непрерывный, система считает календарные периоды. Типовые механизмы учитывают эти нюансы автоматически, в то время как самописные запросы часто их игнорируют.

← На главную