Как правильно рассчитать стаж в запросе 1С, чтобы данные совпадали с типовыми отчетами

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

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

Метод 1: Расчет количества полных лет (наиболее точный)

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

Проанализируем следующую конструкцию в запросе:


ВЫБРАТЬ
    ГОД(&ДатаОтчета) - ГОД(&ДатаНачала) 
    + ВЫБОР 
        КОГДА МЕСЯЦ(&ДатаНачала) > МЕСЯЦ(&ДатаОтчета) ТОГДА -1 
        КОГДА МЕСЯЦ(&ДатаНачала) = МЕСЯЦ(&ДатаОтчета) И ДЕНЬ(&ДатаНачала) > ДЕНЬ(&ДатаОтчета) ТОГДА -1 
        ИНАЧЕ 0 
    КОНЕЦ КАК ПолныхЛет

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

Метод 2: Работа с округлением дробных значений

Иногда стаж необходимо представить в виде десятичного числа (например, 25.5 лет) и затем округлить его по определенным правилам. В языке запросов 1С функция ВЫРАЗИТЬ выполняет математическое округление. Однако здесь есть нюанс: если результат 25.5, система может округлить его как до 25, так и до 26 в зависимости от реализации СУБД (часто используется банковское округление к ближайшему четному).

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

  1. Округление всегда в большую сторону: ВЫРАЗИТЬ(ПолеСтажа + 0.5 КАК ЧИСЛО(15, 0)) - 1 (в зависимости от логики может потребоваться корректировка).
  2. Округление до ближайшего целого (математическое): ВЫРАЗИТЬ(ПолеСтажа КАК ЧИСЛО(15, 0)).
  3. Отсечение дробной части (получение целого): Чтобы получить только целую часть без округления вверх, можно вычесть 0.5 перед выражением, но более надежным способом в запросе будет использование сложной конструкции ВЫБОР.

Метод 3: Учет стажа из типовых регистров (ЗУП/ERP)

В типовых конфигурациях стаж сотрудника часто складывается из двух частей: стаж до приема на работу (введенный вручную) и стаж после приема (исчисляемый автоматически). Данные хранятся в регистре сведений СтажиФизическихЛиц.

Рассмотрим алгоритм получения актуального стажа в запросе:

  1. Получаем из регистра дату отсчета и количество лет/месяцев/дней «входящего» стажа.
  2. Используем функцию ДОБАВИТЬКДАТЕ, чтобы вычислить виртуальную «дату начала стажа».
  3. Рассчитываем разность между &ДатаОтчета и этой виртуальной датой.

Пример получения «виртуальной» даты начала в запросе:


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

Метод 4: Сложный расчет (Дни, Месяцы, Годы)

Согласно правилам кадрового учета, стаж часто считается по принципу: 30 дней — это месяц, 12 месяцев — это год. При этом важно помнить про правило «+1 день». Если сотрудник принят 1-го числа и уволен 30-го, РАЗНОСТЬДАТ вернет 29 дней, хотя фактически отработан полный месяц. Поэтому к разности дат в днях всегда нужно прибавлять 1.

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


ВЫБРАТЬ
    СУММА(РАЗНОСТЬДАТ(Периоды.ДатаНачала, Периоды.ДатаОкончания, ДЕНЬ) + 1) КАК ВсегоДней
ПОМЕСТИТЬ ВТ_ОбщийСтаж
ИЗ
    ВТ_ПериодыРаботы КАК Периоды;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВЫРАЗИТЬ(ВсегоДней / 365.25 - 0.5 КАК ЧИСЛО(10, 0)) КАК ПолныхЛет
ИЗ
    ВТ_ОбщийСтаж

Использование коэффициента 365.25 позволяет нивелировать влияние високосных лет при грубом расчете. Однако для юридически точного расчета рекомендуется использовать Метод 1, комбинируя его с проверкой периодов.

Важные рекомендации

При работе со стажем в запросах всегда учитывайте следующие моменты:

Таким образом, для получения результата, максимально близкого к ЗУП, лучше всего использовать комбинацию из получения данных регистра СтажиФизическихЛиц и расчета разности дат с проверкой месяцев и дней (Метод 1). Это исключит ошибки округления и обеспечит корректное попадание сотрудника в нужные интервалы стажа (1-5 лет, 5-10 лет и т.д.).

← На главную